Ovirt

【Ovirt 笔记】engine-manage-domains

2017-05-18  本文已影响14人  58bc06151329

分析整理的版本为 Ovirt 3.4.5 版本。

命令使用方式:engine-manage-domains <action> [<args>]

Available actions:
    add         add a domain using specified provider and user
    edit        edit an existing domain
    delete      delete an existing domain
    validate    validate the current configuration
    list        list the current configuration

Add domain:
    engine-manage-domains add --domain=DOMAIN --provider=PROVIDER --user=USER  [--add-permissions] [--config-file=CFG_FILE] [--ldap-servers=SERVERS] [--resolve-kdc] [--password-file=PASS_FILE] [--change-password-msg]

Edit domain:
    engine-manage-domains edit --domain=DOMAIN [--provider=PROVIDER] [--user=USER]  [--add-permissions] [--config-file=CFG_FILE] [--ldap-servers=SERVERS] [--resolve-kdc]  [--password-file=PASS_FILE] [--change-password-msg]

Delete domain:
    engine-manage-domains delete --domain=DOMAIN [--force] [--config-file=CFG_FILE] [--password-file=PASS_FILE]

Validate configuration:
    engine-manage-domains validate [--report] [--config-file=CFG_FILE]

List configuration:
    engine-manage-domains list [--config-file=CFG_FILE]

Options:
--add-permissions
    Add engine superuser permissions to the user.

--change-password-msg
    Reads interactively a URL or a message to be returned to the user in case the password has expired.

--config-file=CFG_FILE
    Use the given alternate configuration file.

--domain=DOMAIN
    The domain you wish to perform the action on.

--force
    Skip confirmation of a delete operation.

--help
    Show this help message and exit.

--ldap-servers=SERVERS
    A comma delimited list of LDAP servers to be set to the domain.

--log-file=LOG_FILE
    Sets file to write logging into (if not set nothing is logged).

--log-level=LOG_LEVEL
    Sets log level, one of DEBUG (default), INFO, WARN, ERROR (case insensitive).

--log4j-config=XML_FILE
    Sets log4j.xml file which logging configuration is loaded from.

--provider=PROVIDER
    The LDAP provider type of server used for the domain, can be one of (case insensitive):
        ad        Microsoft Active Directory
        ipa       freeIPA
        rhds      Red Hat Directory Server
        itds      IBM Tivoli Directory Server
        oldap     OpenLDAP

--report
    Report all validation error, if occured (default behaviour is to exit when a validation error occurs).

--resolve-kdc
    Resolve KDC servers using DNS (don't assume they are the same as LDAP servers).

--user=USER
    The domain user.

--password-file=PASS_FILE
    A  file containing the password (if it's not set, the password will be read interactively).

命令采用了 shell 调用 java 的方式进行实现。

engine-manage-domains.sh 利用 jboss-modules.jar 查询指定的模块 org.ovirt.engine.core.tools 执行启动类 org.ovirt.engine.core.domains.ManageDomainsExecutor

exec "${JAVA_HOME}/bin/java" \
    -Djboss.modules.write-indexes=false \
    -jar "${JBOSS_HOME}/jboss-modules.jar" \
    -dependencies org.ovirt.engine.core.tools \
    -class org.ovirt.engine.core.domains.ManageDomainsExecutor \
    "$@"
  1. ManageDomainsExecutor 执行 main 方法,通过 ManageDomainsArguments 处理验证参数。
mdArgs = new ManageDomainsArguments();
mdArgs.parse(args);
  1. 事务逻辑通过 ManageDomains 类进行处理。
ManageDomains util = new ManageDomains(mdArgs);
// it's existence is checked during the parser validation
util.init();
util.createConfigurationProvider();
util.runCommand();
  1. ManageDomains 执行的相关事务。
public void runCommand() throws ManageDomainsResult {
    String action = args.get(ARG_ACTION);

    if (ACTION_ADD.equals(action)) {
        addDomain();
    } else if (ACTION_EDIT.equals(action)) {
        editDomain();
    } else if (ACTION_DELETE.equals(action)) {
        deleteDomain();
    } else if (ACTION_VALIDATE.equals(action)) {
        validate();
    } else if (ACTION_LIST.equals(action)) {
        getConfiguration();
    }
}
  1. 有关 AD 的操作使用了 ldap 服务,加载配置信息。
util.createConfigurationProvider();
public void createConfigurationProvider() throws ManageDomainsResult {
    String engineConfigProperties = createTempPropFile();
    try {
        String engineConfigExecutable = utilityConfiguration.getEngineConfigExecutablePath();
        String adUserName = getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.AdUserName);
        String domainName = getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.DomainName);
        String ldapSecurityAuthentication =
                getConfigValue(engineConfigExecutable,
                        engineConfigProperties,
                        ConfigValues.LDAPSecurityAuthentication);
        String adUserPassword =
                getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.AdUserPassword);
        String adUserId = getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.AdUserId);
        String ldapServers =
                getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.LdapServers);
        String ldapProviderTypes =
                getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.LDAPProviderTypes);
        String ldapPort =
                getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.LDAPServerPort);
        if (ldapPort == null) {
            ldapPort = DEFAULT_LDAP_SERVER_PORT;
        }
        String changePasswordUrl =
                getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.ChangePasswordMsg);
        if (changePasswordUrl == null) {
            changePasswordUrl = "";
        }
        String saslQOP =
                getConfigValue(engineConfigExecutable, engineConfigProperties, ConfigValues.SASL_QOP);

        configurationProvider =
                new ConfigurationProvider(adUserName,
                        adUserPassword,
                        domainName,
                        ldapSecurityAuthentication,
                        ldapServers,
                        adUserId,
                        ldapProviderTypes,
                        utilityConfiguration.getEngineConfigExecutablePath(),
                        engineConfigProperties, ldapPort, changePasswordUrl, saslQOP);

    } catch (Throwable e) {
        throw new ManageDomainsResult(ManageDomainsResultEnum.FAILED_READING_CURRENT_CONFIGURATION, e.getMessage());
    }
}
public String getConfigValue(String engineConfigExecutable, String engineConfigProperties, ConfigValues enumValue)
        throws IOException,
        InterruptedException {
    Process engineConfigProcess =
            Runtime.getRuntime().exec(engineConfigExecutable + " -g "
                    + enumValue.name() + " --cver=general" + " -p " + engineConfigProperties);
    int retVal = engineConfigProcess.waitFor();
    if (retVal == 0) {
        InputStream processOutput = engineConfigProcess.getInputStream();
        return convertStreamToString(processOutput);
    } else {
        InputStream errorOutput = engineConfigProcess.getErrorStream();
        throw new FailedReadingConfigValueException(enumValue.name(), convertStreamToString(errorOutput));
    }
}

例如:

engine-config.sh -g AdUserName --cver=general -p /tmp/engine-config25691...2950properties

从数据库中表 vdc_options 读取信息。

validate

ldap://30cloud-4137917.sdcad.com:389/DC=sdcad,DC=com

注意:数据库中域用户的密码存放在 AdUserPassword 内置参数中(多个域用户之间由逗号分隔),其加密方式和门户管理员密码 AdminPassword 一样。

add

List<String> ldapServers = getLdapServers(domainName);
dns:///_ldap._tcp.sdcad.com
validateKdcServers(authMode, domainName);
dns:///_kerberos._tcp.sdcad.com
krbConfCreator = new KrbConfCreator(gssapiDomainsString, useDnsLookup, ldapServersPerGSSAPIDomains, domainRealmMappingFile);
/backend/manager/modules/utils/src/main/resources/krb5.conf.template

krb5 配置文件路径的读取从 engine-manage-domains.conf 配置文件中获取

jaasFile=/usr/share/ovirt-engine/conf/jaas.conf
krb5confFile=/etc/ovirt-engine/krb5.conf
engineConfigExecutable=/usr/share/ovirt-engine/bin/engine-config.sh
localHostEntry=localhost
useDnsLookup=true
[libdefaults]

default_realm = SDCAD.COM
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = no
default_tkt_enctypes = arcfour-hmac-md5
udp_preference_limit = 1

#realms

#domain_realm

AuthenticationResult authResult = authenticate(realm, username, password, pathToJAASFile, pathToKrb5ConfFile);
private AuthenticationResult checkAuthentication(String username, String password) {

    AuthenticationResult result = AuthenticationResult.OK;
    try {

        lc = new LoginContext("KerberosUtil", new KerberosUtilCallbackHandler(username, password));
        lc.login();
        log.debug("Check authentication finished successfully ");
    } catch (LoginException ex) {
        String resultMessage = ex.getMessage();
        String formattedMessage = ERROR_PREFIX + " exception message: " + resultMessage;
        log.error(formattedMessage);
        log.debug("", ex);

        KerberosReturnCodeParser parser = new KerberosReturnCodeParser();
        result = parser.parse(resultMessage);
        if (result != AuthenticationResult.OTHER) {
            return result;
        } else {
            System.out.println(formattedMessage);
        }
    }
    return result;
}
/**
 * Login Configuration for JAAS.
 *
 * Specify that Kerberos v5 is a required login module for the
 * example classes: GssExample and Mutual.
 */
KerberosUtil {
  com.sun.security.auth.module.Krb5LoginModule required client=TRUE;
};
lc = new LoginContext("KerberosUtil", new KerberosUtilCallbackHandler(username, password));
lc.login();

实现 JAAS(Java Authentication Authorization Service) 一个简单验证实例。

String pathToKrb5File = "/etc/ovirt-engine/krb5.conf";
String pathToJAASFile = "/usr/share/ovirt-engine/conf/jaas.conf";
String username = "sdcadmin";
String password = "Kvm_123456";
System.setProperty("java.security.krb5.conf", pathToKrb5File);
System.setProperty("java.security.auth.login.config", pathToJAASFile);
try {
    lc = new LoginContext("KerberosUtil", new KerberosUtilCallbackHandler(username, password));
    lc.login();
    System.out.println("Check authentication finished successfully");
} catch (LoginException ex) {
    System.out.println("auth failed.");
    ex.printStackTrace();
}

delete

protected Map<String, String> valuePerDomain = new HashMap<String, String>();
public void removeValueForDomain(String domain) {
    valuePerDomain.remove(domain);
}
public void setValueForDomain(String domain, String value) {
    valuePerDomain.put(domain, value);
}
public void setConfigValue(ConfigValues enumValue, DomainsConfigurationEntry entry, boolean passedAsValue)
        throws ManageDomainsResult {

    log.info("Setting value for " + enumValue.toString() + " to " + entry.getDomainsLoggingEntry());
    File passFile = null;

    try {
        StringBuilder executeCmd = new StringBuilder(engineConfigExecutable);
        executeCmd.append(" -s ").append(enumValue.name());
        if (passedAsValue) {
            executeCmd.append("=" + entry.getDomainsConfigurationEntry());
        } else {
            passFile = createPassFile(entry.getDomainsConfigurationEntry());
            executeCmd.append(" --admin-pass-file " + passFile.getAbsolutePath());
        }
        executeCmd.append(" -p " + engineConfigProperties);
        Process engineConfigProcess = Runtime.getRuntime().exec(executeCmd.toString());

        int retVal = engineConfigProcess.waitFor();
        if (retVal != 0) {
            throw new ManageDomainsResult(ManageDomainsResultEnum.FAILED_SETTING_CONFIGURATION_VALUE_FOR_OPTION,
                    enumValue.name() + " - execute command: " + executeCmd.toString());
        }
    } catch (Throwable e) {
        throw new ManageDomainsResult(ManageDomainsResultEnum.FAILED_SETTING_CONFIGURATION_VALUE_FOR_OPTION_WITH_DETAILS,
                enumValue.name(), e.getMessage());
    } finally {
        disposePassFile(passFile);
    }
}
engine-config.sh -s AdUserName=xx.com -p /tmp/engine-config25691...2950properties

错误信息

2015-10-29 17:11:36,249 ERROR [org.ovirt.engine.core.bll.adbroker.DirectorySearcher] (ajp-/127.0.0.1:8702-5) Failed ldap search server ldap://sdcad.com:389 using user sdcadmin@SDCAD.COM due to General connection problem due to javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7))]. We should try the next server

错误原因

DNS 解析有错误,配置正确的 DNS 解析即可。

/etc/resolv.conf
nameserver 192.168.xx.xx
上一篇 下一篇

猜你喜欢

热点阅读