@Override
  public Integer createPrincipal(String principal, String password, boolean service)
      throws KerberosOperationException {

    if (!isOpen()) {
      throw new KerberosOperationException("This operation handler has not been opened");
    }

    if (StringUtils.isEmpty(principal)) {
      throw new KerberosOperationException("Failed to create new principal - no principal specified");
    }

    DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
    String normalizedPrincipal = deconstructedPrincipal.getNormalizedPrincipal();

    String[] ipaCommand;
    if (service) {
      ipaCommand = new String[]{
          "service-add",
          normalizedPrincipal
      };
    } else {
      String principalName = deconstructedPrincipal.getPrincipalName();

      if (!principalName.equals(principalName.toLowerCase())) {
        LOG.warn("{} is not in lowercase. FreeIPA does not recognize user " +
            "principals that are not entirely in lowercase. This can lead to issues with kinit and keytabs. Make " +
            "sure users are in lowercase.", principalName);
      }

      ipaCommand = new String[]{
          "user-add",
          deconstructedPrincipal.getPrimary(),
          "--principal",
          principalName,
          "--first",
          deconstructedPrincipal.getPrimary(),
          "--last",
          deconstructedPrincipal.getPrimary(),
          "--cn",
          deconstructedPrincipal.getPrimary()
      };
    }

    ShellCommandUtil.Result result = invokeIpa(ipaCommand);
    if (!result.isSuccessful()) {
      String message = String.format("Failed to create principal for %s\n%s\nSTDOUT: %s\nSTDERR: %s",
          normalizedPrincipal, StringUtils.join(ipaCommand, " "), result.getStdout(), result.getStderr());
      LOG.error(message);

      String stdErr = result.getStderr();

      if ((stdErr != null) &&
          ((service && stdErr.contains(String.format("service with name \"%s\" already exists", normalizedPrincipal))) ||
          (!service && stdErr.contains(String.format("user with name \"%s\" already exists", deconstructedPrincipal.getPrimary()))))) {
        throw new KerberosPrincipalAlreadyExistsException(principal);
      } else {
        throw new KerberosOperationException(String.format("Failed to create principal for %s\nSTDOUT: %s\nSTDERR: %s",
            normalizedPrincipal, result.getStdout(), result.getStderr()));
      }
    }

    if ((!service) && !StringUtils.isEmpty(userPrincipalGroup)) {
      result = invokeIpa(new String[]{"group-add-member", userPrincipalGroup, "--users", deconstructedPrincipal.getPrimary()});
      if (!result.isSuccessful()) {
        LOG.warn("Failed to add account for {} to group {}: \nSTDOUT: {}\nSTDERR: {}",
            normalizedPrincipal, userPrincipalGroup, result.getStdout(), result.getStderr());
      }
    }

    // Always return 0 since we do not have a key to get a key number for.
    return 0;
  }
Creates a new principal in a previously configured KDC.
<p>
This implementation uses the ipa shell to create either a user or service account.  No password
will be set for either account type.  The password (or key) will be automatically generated by
the IPA server when exporting the keytab entry.  Upon success, this method will always return
<code>0</code> as the key number since the value is not generated until the keytab entry is
exported.

@param principal a String containing the principal to add
@param password  a String containing the password to use when creating the principal (ignored)
@param service   a boolean value indicating whether the principal is to be created as a service principal or not
@return an Integer declaring the generated key number (always 0)
@throws KerberosOperationException
ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java