public CreatePrincipalResult createPrincipal(String principal, boolean isServicePrincipal,
                                               Map<String, String> kerberosConfiguration,
                                               KerberosOperationHandler kerberosOperationHandler,
                                               boolean regenerateKeytabs, ActionLog actionLog) {

    // in case this is called directly from TopologyManager there's no HostRoleCommand
    CreatePrincipalKerberosAuditEvent.CreatePrincipalKerberosAuditEventBuilder auditEventBuilder = CreatePrincipalKerberosAuditEvent.builder()
        .withTimestamp(System.currentTimeMillis())
        .withRequestId(getHostRoleCommand() != null ? getHostRoleCommand().getRequestId() : -1)
        .withTaskId(getHostRoleCommand() != null ? getHostRoleCommand().getTaskId() : -1)
        .withPrincipal(principal);
    CreatePrincipalResult result = null;
    String message = null;

    try {
      message = String.format("Processing principal, %s", principal);
      LOG.info(message);
      if (actionLog != null) {
        actionLog.writeStdOut(message);
      }

      Integer length;
      Integer minLowercaseLetters;
      Integer minUppercaseLetters;
      Integer minDigits;
      Integer minPunctuation;
      Integer minWhitespace;

      if (kerberosConfiguration == null) {
        length = null;
        minLowercaseLetters = null;
        minUppercaseLetters = null;
        minDigits = null;
        minPunctuation = null;
        minWhitespace = null;
      } else {
        length = toInt(kerberosConfiguration.get("password_length"));
        minLowercaseLetters = toInt(kerberosConfiguration.get("password_min_lowercase_letters"));
        minUppercaseLetters = toInt(kerberosConfiguration.get("password_min_uppercase_letters"));
        minDigits = toInt(kerberosConfiguration.get("password_min_digits"));
        minPunctuation = toInt(kerberosConfiguration.get("password_min_punctuation"));
        minWhitespace = toInt(kerberosConfiguration.get("password_min_whitespace"));
      }

      String password = securePasswordHelper.createSecurePassword(length, minLowercaseLetters, minUppercaseLetters, minDigits, minPunctuation, minWhitespace);

      try {
        /*
         * true indicates a new principal was created, false indicates an existing principal was updated
         */
        boolean created;
        Integer keyNumber;

        if (regenerateKeytabs) {
          try {
            keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password, isServicePrincipal);
            created = false;
          } catch (KerberosPrincipalDoesNotExistException e) {
            message = String.format("Principal, %s, does not exist, creating new principal", principal);
            LOG.warn(message);
            if (actionLog != null) {
              actionLog.writeStdOut(message);
            }

            keyNumber = kerberosOperationHandler.createPrincipal(principal, password, isServicePrincipal);
            created = true;
          }
        } else {
          try {
            keyNumber = kerberosOperationHandler.createPrincipal(principal, password, isServicePrincipal);
            created = true;
          } catch (KerberosPrincipalAlreadyExistsException e) {
            message = String.format("Principal, %s, already exists, setting new password", principal);
            LOG.warn(message);
            if (actionLog != null) {
              actionLog.writeStdOut(message);
            }

            keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password, isServicePrincipal);
            created = false;
          }
        }

        if (keyNumber != null) {
          result = new CreatePrincipalResult(principal, password, keyNumber);

          if (created) {
            message = String.format("Successfully created new principal, %s", principal);
          } else {
            message = String.format("Successfully set password for %s", principal);
          }
          LOG.debug(message);
        } else {
          if (created) {
            message = String.format("Failed to create principal, %s - unknown reason", principal);
          } else {
            message = String.format("Failed to set password for %s - unknown reason", principal);
          }
          LOG.error(message);
          if (actionLog != null) {
            actionLog.writeStdErr(message);
          }
        }

        if (!kerberosPrincipalDAO.exists(principal)) {
          kerberosPrincipalDAO.create(principal, isServicePrincipal);
        }

      } catch (KerberosOperationException e) {
        message = String.format("Failed to create principal, %s - %s", principal, e.getMessage());
        LOG.error(message, e);
        if (actionLog != null) {
          actionLog.writeStdErr(message);
        }
      }
    } finally {
      if (result == null) {
        auditEventBuilder.withReasonOfFailure(message == null ? "Unknown error" : message);
      }
      auditLog(auditEventBuilder.build());
    }

    return result;
  }
Creates a principal in the relevant KDC

@param principal                the principal name to create
@param isServicePrincipal       true if the principal is a service principal; false if the
                                principal is a user principal
@param kerberosConfiguration    the kerberos-env configuration properties
@param kerberosOperationHandler the KerberosOperationHandler for the relevant KDC
@param regenerateKeytabs        true if this was triggered in response to regenerating keytab files; false otherwise
@param actionLog                the logger (may be null if no logging is desired)
@return a CreatePrincipalResult containing the generated password and key number value
ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java