class CustomFolderHelper(object):
    """
    Shared code for custom (user-defined) folders in the model.
    These require special handling, since they do not have alias definitions.
    """
    __class_name = 'CustomFolderHelper'
    __cipher_text_prefixes = ["{AES}", "{AES-256}"]

    def __init__(self, aliases, logger, model_context, exception_type):
        self.aliases = aliases
        self.logger = logger
        self.model_context = model_context
        self.exception_type = exception_type
        self.weblogic_helper = WebLogicHelper(self.logger)
        self.wlst_helper = WlstHelper(self.exception_type)

    def update_security_folder(self, location, model_type, model_subtype, model_name, model_nodes):
        """
        Update the specified security model nodes in WLST.
        :param location: the location for the provider
        :param model_type: the type of the provider to be updated, such as AuthenticationProvider
        :param model_subtype: the subtype of the provider to be updated, such as 'custom.my.CustomIdentityAsserter'
        :param model_name: the name of the provider to be updated, such as 'My custom IdentityAsserter'
        :param model_nodes: a child model nodes of the provider to be updated
        :raises: BundleAwareException of the specified type: if an error occurs
        """
        _method_name = 'update_security_folder'

        location_path = self.aliases.get_model_folder_path(location)
        self.logger.entering(location_path, model_subtype, model_name,
                             class_name=self.__class_name, method_name=_method_name)

        self.logger.info('WLSDPLY-12124', model_type, model_name, model_subtype, location_path,
                         class_name=self.__class_name, method_name=_method_name)

        create_path = self.aliases.get_wlst_subfolders_path(location)
        self.wlst_helper.cd(create_path)

        # create the MBean using the model type, name, and subtype

        type_location = LocationContext(location).append_location(model_type)
        token = self.aliases.get_name_token(type_location)
        type_location.add_name_token(token, model_name)

        mbean_type = self.aliases.get_wlst_mbean_type(type_location)
        self.wlst_helper.create(model_name, model_subtype, mbean_type)

        provider_path = self.aliases.get_wlst_attributes_path(type_location)
        provider_mbean = self.wlst_helper.cd(provider_path)

        interface_name = model_subtype + 'MBean'
        bean_info = self.weblogic_helper.get_bean_info_for_interface(interface_name)
        if bean_info is None:
            ex = exception_helper.create_exception(self.exception_type, 'WLSDPLY-12125', interface_name)
            self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
            raise ex

        property_map = dict()
        for property_descriptor in bean_info.getPropertyDescriptors():
            self.logger.finer('WLSDPLY-12126', str(property_descriptor), class_name=self.__class_name,
                              method_name=_method_name)
            property_map[property_descriptor.getName()] = property_descriptor

        for model_key in model_nodes:
            model_value = model_nodes[model_key]
            property_descriptor = property_map.get(model_key)

            if not property_descriptor:
                folder_path = self.aliases.get_model_folder_path(type_location)
                ex = exception_helper.create_exception(self.exception_type, 'WLSDPLY-12128', model_key, folder_path)
                self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
                raise ex

            # find the setter method for the attribute

            method = property_descriptor.writeMethod
            if not method:
                # this must be a read-only attribute, just log it and continue with next attribute
                self.logger.info('WLSDPLY-12129', str(model_key), class_name=self.__class_name,
                                 method_name=_method_name)
                continue

            self.logger.finer('WLSDPLY-12127', str(model_key), str(model_value), class_name=self.__class_name,
                              method_name=_method_name)

            # determine the data type from the set method

            parameter_types = method.getParameterTypes()
            parameter_count = len(parameter_types)

            if parameter_count != 1:
                ex = exception_helper.create_exception(self.exception_type, 'WLSDPLY-12130', model_key,
                                                       parameter_count)
                self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
                raise ex

            # if the property requires encryption, and the value is not encrypted,
            # encrypt the value with domain encryption.

            requires_encrypted = property_descriptor.getValue('encrypted')
            if requires_encrypted and not self.is_encrypted(model_value) and isinstance(model_value, str):
                model_value = self.weblogic_helper.encrypt(model_value, self.model_context.get_domain_home())

            property_type = parameter_types[0]

            # convert the model value to the target type and call the setter with the target value.
            # these are done together in Java to avoid automatic Jython type conversions.

            try:
                CustomBeanUtils.callMethod(provider_mbean, method, property_type, model_value)

            # failure converting value or calling method
            except (IllegalAccessException, IllegalArgumentException, InvocationTargetException), ex:
                ex = exception_helper.create_exception(self.exception_type, 'WLSDPLY-12131', method,
                                                       str(model_value), ex.getLocalizedMessage(), error=ex)
                self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
                raise ex
from wlsdeploy.util import variables
from wlsdeploy.util import wlst_extended
from wlsdeploy.util import wlst_helper
from wlsdeploy.util.cla_utils import CommandLineArgUtil
from wlsdeploy.util.model_context import ModelContext
from wlsdeploy.util.model_translator import FileToPython
from wlsdeploy.util.weblogic_helper import WebLogicHelper

wlst_extended.wlst_functions = globals()

_program_name = CREATE_DOMAIN

_class_name = 'create'
__logger = PlatformLogger('wlsdeploy.create')
__wlst_mode = WlstModes.OFFLINE
__version = WebLogicHelper(__logger).get_actual_weblogic_version()
__tmp_model_dir = None

__required_arguments = [
    CommandLineArgUtil.ORACLE_HOME_SWITCH,
    CommandLineArgUtil.DOMAIN_TYPE_SWITCH
]

__optional_arguments = [
    CommandLineArgUtil.ARCHIVE_FILE_SWITCH,
    CommandLineArgUtil.DOMAIN_HOME_SWITCH,
    CommandLineArgUtil.DOMAIN_PARENT_SWITCH,
    CommandLineArgUtil.JAVA_HOME_SWITCH, CommandLineArgUtil.MODEL_FILE_SWITCH,
    CommandLineArgUtil.RUN_RCU_SWITCH, CommandLineArgUtil.RCU_SYS_PASS_SWITCH,
    CommandLineArgUtil.RCU_DB_SWITCH, CommandLineArgUtil.RCU_PREFIX_SWITCH,
    CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH,
from wlsdeploy.tool.util import wlst_helper
from wlsdeploy.tool.util.wlst_helper import WlstHelper
from wlsdeploy.tool.util.rcu_helper import RCUHelper
from wlsdeploy.tool.util.string_output_stream import StringOutputStream
from wlsdeploy.util import cla_helper
from wlsdeploy.util import tool_exit
from wlsdeploy.util.cla_utils import CommandLineArgUtil
from wlsdeploy.util.model import Model
from wlsdeploy.util.weblogic_helper import WebLogicHelper

wlst_helper.wlst_functions = globals()

_program_name = UPDATE_DOMAIN
_class_name = 'update'
__logger = PlatformLogger('wlsdeploy.update')
__wls_helper = WebLogicHelper(__logger)
__wlst_helper = WlstHelper(ExceptionType.DEPLOY)
__wlst_mode = WlstModes.OFFLINE

__required_arguments = [
    CommandLineArgUtil.ORACLE_HOME_SWITCH,
    CommandLineArgUtil.DOMAIN_HOME_SWITCH
]

__optional_arguments = [
    # Used by shell script to locate WLST
    CommandLineArgUtil.DOMAIN_TYPE_SWITCH,
    CommandLineArgUtil.ARCHIVE_FILE_SWITCH,
    CommandLineArgUtil.MODEL_FILE_SWITCH,
    CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH,
    CommandLineArgUtil.VARIABLE_FILE_SWITCH,
    def __init__(self, program_name, arg_map):
        self._program_name = program_name
        self._logger = platform_logger.PlatformLogger('wlsdeploy.util')
        self._wls_helper = WebLogicHelper(self._logger)

        self._oracle_home = None
        self._wl_home = None
        self._java_home = None
        self._domain_home = None
        self._domain_name = None
        self._domain_parent_dir = None
        self._domain_type = 'WLS'
        self._domain_typedef = None
        self._admin_url = None
        self._admin_user = None
        self._admin_password = None
        self._archive_file_name = None
        self._archive_file = None
        self._model_file = None
        self._previous_model_file = None
        self._print_usage = None
        self._variable_file_name = None
        self._run_rcu = False
        self._rcu_database = None
        self._rcu_prefix = None
        self._rcu_sys_pass = None
        self._rcu_schema_pass = None
        self._encryption_passphrase = None
        self._encrypt_manual = False
        self._encrypt_one_pass = None
        self._use_encryption = False
        self._wl_version = None
        self._wlst_mode = None
        self._recursive = False
        self._attributes_only = False
        self._folders_only = False

        if CommandLineArgUtil.ORACLE_HOME_SWITCH in arg_map:
            self._oracle_home = arg_map[CommandLineArgUtil.ORACLE_HOME_SWITCH]
            self._wl_home = self._wls_helper.get_weblogic_home(
                self._oracle_home)

        if CommandLineArgUtil.JAVA_HOME_SWITCH in arg_map:
            self._java_home = arg_map[CommandLineArgUtil.JAVA_HOME_SWITCH]

        if CommandLineArgUtil.DOMAIN_HOME_SWITCH in arg_map:
            self._domain_home = arg_map[CommandLineArgUtil.DOMAIN_HOME_SWITCH]
            self._domain_name = os.path.basename(self._domain_home)

        if CommandLineArgUtil.DOMAIN_PARENT_SWITCH in arg_map:
            self._domain_parent_dir = arg_map[
                CommandLineArgUtil.DOMAIN_PARENT_SWITCH]

        if CommandLineArgUtil.DOMAIN_TYPE_SWITCH in arg_map:
            self._domain_type = arg_map[CommandLineArgUtil.DOMAIN_TYPE_SWITCH]

        if CommandLineArgUtil.ADMIN_URL_SWITCH in arg_map:
            self._admin_url = arg_map[CommandLineArgUtil.ADMIN_URL_SWITCH]

        if CommandLineArgUtil.ADMIN_USER_SWITCH in arg_map:
            self._admin_user = arg_map[CommandLineArgUtil.ADMIN_USER_SWITCH]

        if CommandLineArgUtil.ADMIN_PASS_SWITCH in arg_map:
            self._admin_password = arg_map[
                CommandLineArgUtil.ADMIN_PASS_SWITCH]

        if CommandLineArgUtil.ARCHIVE_FILE_SWITCH in arg_map:
            self._archive_file_name = arg_map[
                CommandLineArgUtil.ARCHIVE_FILE_SWITCH]

        if CommandLineArgUtil.MODEL_FILE_SWITCH in arg_map:
            self._model_file = arg_map[CommandLineArgUtil.MODEL_FILE_SWITCH]

        if CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH in arg_map:
            self._previous_model_file = arg_map[
                CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH]

        if CommandLineArgUtil.PRINT_USAGE_SWITCH in arg_map:
            self._print_usage = arg_map[CommandLineArgUtil.PRINT_USAGE_SWITCH]

        if CommandLineArgUtil.ATTRIBUTES_ONLY_SWITCH in arg_map:
            self._attributes_only = arg_map[
                CommandLineArgUtil.ATTRIBUTES_ONLY_SWITCH]

        if CommandLineArgUtil.FOLDERS_ONLY_SWITCH in arg_map:
            self._folders_only = arg_map[
                CommandLineArgUtil.FOLDERS_ONLY_SWITCH]

        if CommandLineArgUtil.RECURSIVE_SWITCH in arg_map:
            self._recursive = arg_map[CommandLineArgUtil.RECURSIVE_SWITCH]

        if CommandLineArgUtil.VARIABLE_FILE_SWITCH in arg_map:
            self._variable_file_name = arg_map[
                CommandLineArgUtil.VARIABLE_FILE_SWITCH]

        if CommandLineArgUtil.RUN_RCU_SWITCH in arg_map:
            self._run_rcu = arg_map[CommandLineArgUtil.RUN_RCU_SWITCH]

        if CommandLineArgUtil.RCU_DB_SWITCH in arg_map:
            self._rcu_database = arg_map[CommandLineArgUtil.RCU_DB_SWITCH]

        if CommandLineArgUtil.RCU_PREFIX_SWITCH in arg_map:
            self._rcu_prefix = arg_map[CommandLineArgUtil.RCU_PREFIX_SWITCH]

        if CommandLineArgUtil.RCU_SYS_PASS_SWITCH in arg_map:
            self._rcu_sys_pass = arg_map[
                CommandLineArgUtil.RCU_SYS_PASS_SWITCH]

        if CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH in arg_map:
            self._rcu_schema_pass = arg_map[
                CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH]

        if CommandLineArgUtil.DOMAIN_TYPEDEF in arg_map:
            self._domain_typedef = arg_map[CommandLineArgUtil.DOMAIN_TYPEDEF]

        if CommandLineArgUtil.PASSPHRASE_SWITCH in arg_map:
            self._encryption_passphrase = arg_map[
                CommandLineArgUtil.PASSPHRASE_SWITCH]

        if CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH in arg_map:
            self._encrypt_manual = arg_map[
                CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH]

        if CommandLineArgUtil.ONE_PASS_SWITCH in arg_map:
            self._encrypt_one_pass = arg_map[
                CommandLineArgUtil.ONE_PASS_SWITCH]

        if CommandLineArgUtil.USE_ENCRYPTION_SWITCH in arg_map:
            self._use_encryption = arg_map[
                CommandLineArgUtil.USE_ENCRYPTION_SWITCH]

        if CommandLineArgUtil.ARCHIVE_FILE in arg_map:
            self._archive_file = arg_map[CommandLineArgUtil.ARCHIVE_FILE]

        if CommandLineArgUtil.TARGET_VERSION_SWITCH in arg_map:
            self._wl_version = arg_map[
                CommandLineArgUtil.TARGET_VERSION_SWITCH]

        if CommandLineArgUtil.TARGET_MODE_SWITCH in arg_map:
            wlst_mode_string = arg_map[CommandLineArgUtil.TARGET_MODE_SWITCH]
            if wlst_mode_string.lower() == 'online':
                self._wlst_mode = WlstModes.ONLINE
            else:
                self._wlst_mode = WlstModes.OFFLINE

        if self._wl_version is None:
            self._wl_version = self._wls_helper.get_actual_weblogic_version()

        if self._wlst_mode is None:
            self._wlst_mode = WlstModes.OFFLINE

        return
class CommandLineArgUtil(object):
    """
    Class that handles command-line argument parsing and common validation.
    """
    _class_name = 'CommandLineArgUtil'

    HELP_SWITCH                = '-help'
    ORACLE_HOME_SWITCH         = '-oracle_home'
    JAVA_HOME_SWITCH           = '-java_home'
    DOMAIN_HOME_SWITCH         = '-domain_home'
    DOMAIN_PARENT_SWITCH       = '-domain_parent'
    DOMAIN_TYPE_SWITCH         = '-domain_type'
    # never used by the tools but used by shell scripts
    WLST_PATH_SWITCH           = '-wlst_path'
    ADMIN_URL_SWITCH           = '-admin_url'
    ADMIN_USER_SWITCH          = '-admin_user'
    # phony arg used as a key to store the password
    ADMIN_PASS_SWITCH          = '-admin_pass'
    ARCHIVE_FILE_SWITCH        = '-archive_file'
    MODEL_FILE_SWITCH          = '-model_file'
    OPSS_WALLET_SWITCH         = '-opss_wallet'
    OPSS_WALLET_PASSPHRASE     = '-opss_wallet_passphrase'
    PREVIOUS_MODEL_FILE_SWITCH = '-prev_model_file'
    VARIABLE_FILE_SWITCH       = '-variable_file'
    RCU_DB_SWITCH              = '-rcu_db'
    RCU_DB_USER_SWITCH         = '-rcu_db_user'
    RCU_PREFIX_SWITCH          = '-rcu_prefix'
    # phony arg used as a key to store the password
    RCU_SYS_PASS_SWITCH        = '-rcu_sys_pass'
    # phony arg used as a key to store the password
    RCU_SCHEMA_PASS_SWITCH     = '-rcu_schema_pass'
    # phony arg used as a key to store the encryption passphrase
    PASSPHRASE_SWITCH          = '-passphrase'
    ENCRYPT_MANUAL_SWITCH      = '-manual'
    # phony arg used as a key to store the password
    ONE_PASS_SWITCH            = '-password'
    ROLLBACK_IF_RESTART_REQ_SWITCH = '-rollback_if_require_restart'
    USE_ENCRYPTION_SWITCH      = '-use_encryption'
    RUN_RCU_SWITCH             = '-run_rcu'
    TARGET_VERSION_SWITCH      = '-target_version'
    TARGET_MODE_SWITCH         = '-target_mode'
    # phony arg used as a key to store the trailing (non-switched) arguments
    TRAILING_ARGS_SWITCH       = '-trailing_arguments'
    ATTRIBUTES_ONLY_SWITCH     = '-attributes_only'
    FOLDERS_ONLY_SWITCH        = '-folders_only'
    # deprecated
    MODEL_SAMPLE_SWITCH        = '-model_sample'
    RECURSIVE_SWITCH           = '-recursive'
    UPDATE_RCU_SCHEMA_PASS_SWITCH = '-updateRCUSchemaPassword'
    VALIDATION_METHOD          = '-method'
    # overrides for the variable injector
    VARIABLE_INJECTOR_FILE_SWITCH   = '-variable_injector_file'
    VARIABLE_KEYWORDS_FILE_SWITCH   = '-variable_keywords_file'
    VARIABLE_PROPERTIES_FILE_SWITCH = '-variable_properties_file'
    # extractDomainResource output file
    DOMAIN_RESOURCE_FILE_SWITCH   = '-domain_resource_file'
    OUTPUT_DIR_SWITCH = "-output_dir"

    TARGET_SWITCH = '-target'

    # arguments that are true if specified, false if not
    BOOLEAN_SWITCHES = [
        ATTRIBUTES_ONLY_SWITCH,
        ENCRYPT_MANUAL_SWITCH,
        FOLDERS_ONLY_SWITCH,
        MODEL_SAMPLE_SWITCH,
        RECURSIVE_SWITCH,
        ROLLBACK_IF_RESTART_REQ_SWITCH,
        RUN_RCU_SWITCH,
        UPDATE_RCU_SCHEMA_PASS_SWITCH,
        USE_ENCRYPTION_SWITCH
    ]

    # a slot to stash the parsed domain typedef dictionary
    DOMAIN_TYPEDEF             = 'domain_typedef'
    # a slot to stash the archive file object
    ARCHIVE_FILE               = 'archive_file'

    ARCHIVE_FILES_SEPARATOR = ','
    MODEL_FILES_SEPARATOR = ','

    HELP_EXIT_CODE                 = 100
    USAGE_ERROR_EXIT_CODE          = 99
    ARG_VALIDATION_ERROR_EXIT_CODE = 98
    PROG_RESTART_REQUIRED          = 103
    PROG_ROLLBACK_IF_RESTART_EXIT_CODE = 104
    PROG_ERROR_EXIT_CODE           = 2
    PROG_WARNING_EXIT_CODE         = 1
    PROG_OK_EXIT_CODE              = 0

    def __init__(self, program_name, required_args, optional_args):
        self._program_name = program_name
        self._logger = PlatformLogger('wlsdeploy.util')

        self._required_args = list(required_args)
        self._optional_args = list(optional_args)
        self._allow_multiple_models = False

        #
        # Add args that all tools should accept.
        #
        self._optional_args.append(self.HELP_SWITCH)
        self._optional_args.append(self.WLST_PATH_SWITCH)

        self._required_result = {}
        self._optional_result = {}
        return

    def set_allow_multiple_models(self, allow_multiple_models):
        """
        This method determines if this instance allows multiple models to be specified for the MODEL_FILE_SWITCH
        argument. By default, multiple models are not allowed.
        :param allow_multiple_models: the flag indicating if multiple models are allowed
        """
        self._allow_multiple_models = allow_multiple_models

    def process_args(self, args, tool_type=TOOL_TYPE_DEFAULT, trailing_arg_count=0):
        """
        This method parses the command-line arguments and returns dictionaries of the required and optional args.

        :param args: sys.argv
        :param tool_type: optional, type of tool for special argument processing
        :param trailing_arg_count: optional, the number of trailing (no switch) arguments
        :return: the required and optional argument dictionaries
        :raises CLAException: if argument processing encounters a usage or validation exception
        """

        method_name = 'process_args'

        self._logger.entering(args, class_name=self._class_name, method_name=method_name)
        #
        # reset the result fields in case the object was reused
        #
        self._required_result = {}
        self._optional_result = {}

        args_len = len(args)
        if args_len == 1:
            ex = exception_helper.create_cla_exception('Dummy Key')
            ex.setExitCode(self.HELP_EXIT_CODE)
            raise ex

        args = self._check_trailing_arguments(args, trailing_arg_count)
        args_len = len(args)

        idx = 1
        while idx < args_len:
            key = args[idx]
            self._logger.fine('WLSDPLY-01600', key, class_name=self._class_name, method_name=method_name)
            if self.is_help_key(key):
                ex = exception_helper.create_cla_exception('Dummy Key')
                ex.setExitCode(self.HELP_EXIT_CODE)
                raise ex
            elif self.is_oracle_home_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_oracle_home_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_java_home_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_java_home_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_domain_home_key(key):
                value, idx = self._get_arg_value(args, idx)
                if tool_type == TOOL_TYPE_CREATE:
                    full_path = self._validate_domain_home_arg_for_create(value)
                elif tool_type == TOOL_TYPE_EXTRACT:
                    full_path = self._validate_domain_home_arg_for_extract(value)
                else:
                    full_path = self._validate_domain_home_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_domain_parent_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_domain_parent_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_domain_type_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_domain_type_arg(value)
                self._add_arg(key, value)
            elif self.is_wlst_path_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_wlst_path_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_admin_url_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_admin_url_arg(value)
                self._add_arg(key, value)
            elif self.is_admin_user_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_admin_user_arg(value)
                self._add_arg(key, value)
            elif self.is_admin_pass_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_admin_pass_arg(value)
                self._add_arg(key, value)
            elif self.is_archive_file_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_archive_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_opss_passphrase_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_opss_passphrase_arg(value)
                self._add_arg(key, value)
            elif self.is_opss_wallet_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_opss_wallet_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_model_file_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_model_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_previous_model_file_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_previous_model_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_validate_method_key(key):
                value, idx = self._get_arg_value(args, idx)
                context = self._validate_validate_method_arg(value)
                self._add_arg(key, context)
            elif self.is_variable_file_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._add_arg(key, value, True)
            elif self.is_rcu_database_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_rcu_database_arg(value)
                self._add_arg(key, value)
            elif self.is_rcu_dbuser_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_rcu_dbuser_arg(value)
                self._add_arg(key, value)
            elif self.is_rcu_prefix_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_rcu_prefix_arg(value)
                self._add_arg(key, value)
            elif self.is_rcu_sys_pass_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_rcu_sys_pass_arg(value)
                self._add_arg(key, value)
            elif self.is_rcu_schema_pass_key(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_rcu_schema_pass_arg(value)
                self._add_arg(key, value)
            elif self.is_passphrase_switch(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_passphrase_arg(value)
                self._add_arg(key, value)
            elif self.is_one_pass_switch(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_one_pass_arg(value)
                self._add_arg(key, value)
            elif self.is_target_version_switch(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_target_version_arg(value)
                self._add_arg(key, value)
            elif self.is_target_mode_switch(key):
                value, idx = self._get_arg_value(args, idx)
                self._validate_target_mode_arg(value)
                self._add_arg(key, value)
            elif self.is_variable_injector_file_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_variable_injector_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_variable_keywords_file_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_variable_keywords_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_variable_properties_file_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_variable_properties_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_domain_resource_file_key(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_domain_resource_file_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_boolean_switch(key):
                self._add_arg(key, True)
            elif self.is_compare_model_output_dir_switch(key):
                value, idx = self._get_arg_value(args, idx)
                full_path = self._validate_compare_model_output_dir_arg(value)
                self._add_arg(key, full_path, True)
            elif self.is_target_switch(key):
                value, idx = self._get_arg_value(args, idx)
                value = self._validate_target_arg(value)
                self._add_arg(key, value, True)
            else:
                ex = exception_helper.create_cla_exception('WLSDPLY-01601', self._program_name, key)
                ex.setExitCode(self.USAGE_ERROR_EXIT_CODE)
                self._logger.throwing(ex, class_name=self._class_name, method_name=method_name)
                raise ex
            idx += 1

        self._verify_required_args_present(self._program_name, self._required_args, self._required_result)

        combined_arg_map = self._optional_result.copy()
        combined_arg_map.update(self._required_result)

        self._logger.exiting(class_name=self._class_name, method_name=method_name, result=combined_arg_map)
        return combined_arg_map

    def _get_arg_value(self, args, index):
        """
        Return the value after the specified index in the argument array.
        Throw an exception if the next index is past the end of the arguments.
        :param args: the arguments to be examined
        :param index: the index argument before the value
        :return: the value of the argument, and the next index value
        """
        method_name = '_get_arg_value'
        key = args[index]

        # check that key is valid here, to avoid validation if it is not
        if (key not in self._required_args) and (key not in self._optional_args):
            ex = exception_helper.create_cla_exception('WLSDPLY-01632', key, self._program_name)
            ex.setExitCode(self.USAGE_ERROR_EXIT_CODE)
            self._logger.throwing(ex, class_name=self._class_name, method_name=method_name)
            raise ex

        index = index + 1
        if index >= len(args):
            ex = self._get_out_of_args_exception(key)
            self._logger.throwing(ex, class_name=self._class_name, method_name=method_name)
            raise ex
        return args[index], index

    def _check_trailing_arguments(self, args, trailing_arg_count):
        """
        Remove any trailing (no switch) arguments from the argument list and add them to the required result.
          example:
            command.sh -oracle_home /oracle file1 file2
            file1 and file2 are trailing arguments

        :param args: the arguments to be examined
        :param trailing_arg_count: the number of trailing arguments that are expected
        :return: the argument list, with the trailing arguments removed
        :raises CLAException: if there are not enough arguments present
        """
        method_name = '_check_trailing_arguments'
        args_len = len(args)

        # verify there are enough arguments for any trailing (no switch) args
        if args_len < trailing_arg_count + 1:
            ex = exception_helper.create_cla_exception('WLSDPLY-01639', trailing_arg_count)
            ex.setExitCode(self.ARG_VALIDATION_ERROR_EXIT_CODE)
            self._logger.throwing(ex, class_name=self._class_name, method_name=method_name)
            raise ex

        # set required_result['TRAILING_ARGS'] to list of trailing args (such as ['file1', 'file2'])
        trailing_args = []
        for index in range(args_len - trailing_arg_count, args_len):
            arg = args[index]
            trailing_args.append(arg)
        self._required_result[self.TRAILING_ARGS_SWITCH] = trailing_args

        # remove trailing args from the list and return revised list
        return args[0:(args_len - trailing_arg_count)]

    def _verify_required_args_present(self, program_name, required_arguments, required_arg_map):
        """
        Verify that the required args are present.
        :param program_name: the program name, for logging
        :param required_arguments: the required arguments to be checked
        :param required_arg_map: the required arguments map
        :raises CLAException: if one or more of the required arguments are missing
        """
        _method_name = '_verify_required_args_present'

        for req_arg in required_arguments:
            if req_arg not in required_arg_map:
                ex = exception_helper.create_cla_exception('WLSDPLY-20005', program_name, req_arg)
                ex.setExitCode(CommandLineArgUtil.USAGE_ERROR_EXIT_CODE)
                self._logger.throwing(ex, class_name=self._class_name, method_name=_method_name)
                raise ex
        return

    def get_help_key(self):
        return self.HELP_SWITCH

    def is_help_key(self, key):
        return self.HELP_SWITCH == key

    def get_oracle_home_key(self):
        return str(self.ORACLE_HOME_SWITCH)

    def is_oracle_home_key(self, key):
        return self.ORACLE_HOME_SWITCH == key

    def _validate_oracle_home_arg(self, value):
        method_name = '_validate_oracle_home_arg'

        try:
            oh = JFileUtils.validateExistingDirectory(value)
        except JIllegalArgumentException, iae:
            ex = exception_helper.create_cla_exception('WLSDPLY-01602', value, iae.getLocalizedMessage(), error=iae)
            ex.setExitCode(self.ARG_VALIDATION_ERROR_EXIT_CODE)
            self._logger.throwing(ex, class_name=self._class_name, method_name=method_name)
            raise ex

        oh_name = oh.getAbsolutePath()
        wl_helper = WebLogicHelper(self._logger)
        wl_home_name = wl_helper.get_weblogic_home(oh_name)
        try:
            JFileUtils.validateExistingDirectory(wl_home_name)
        except JIllegalArgumentException, iae:
            ex = exception_helper.create_cla_exception('WLSDPLY-01603', wl_home_name, oh_name,
                                                       iae.getLocalizedMessage(), error=iae)
            ex.setExitCode(self.ARG_VALIDATION_ERROR_EXIT_CODE)
            self._logger.throwing(ex, class_name=self._class_name, method_name=method_name)
            raise ex
class Discoverer(object):
    """
    Discoverer contains the private methods used to facilitate discovery of the domain information by its subclasses.
    """
    def __init__(self, model_context, base_location, wlst_mode, aliases=None):
        """

        :param model_context: context about the model for this instance of discover domain
        :param base_location: to look for common weblogic resources. By default this is the global path or '/'
        """
        self._model_context = model_context
        self._base_location = base_location
        self._wlst_mode = wlst_mode
        if aliases:
            self._aliases = aliases
        else:
            self._aliases = Aliases(self._model_context,
                                    wlst_mode=self._wlst_mode)
        self._alias_helper = AliasHelper(self._aliases, _logger,
                                         ExceptionType.DISCOVER)
        self._att_handler_map = OrderedDict()
        self._custom_folder = CustomFolderHelper(self._aliases, _logger,
                                                 self._model_context,
                                                 ExceptionType.DISCOVER)
        self._weblogic_helper = WebLogicHelper(_logger)
        self._wlst_helper = WlstHelper(_logger, ExceptionType.DISCOVER)
        self._mbean_utils = MBeanUtils(self._model_context, self._alias_helper,
                                       ExceptionType.DISCOVER)
        self._wls_version = self._weblogic_helper.get_actual_weblogic_version()

    # methods for use only by the subclasses

    def _populate_model_parameters(self, dictionary, location):
        """
        Populate the model dictionary with the attribute values discovered at the current location. Perform
        any special processing for a specific attribute before storing into the model dictionary.
        :param dictionary: where to store the discovered attributes
        :param location: context containing current location information
        :return: dictionary of model attribute name and wlst value
        """
        _method_name = '_populate_model_parameters'
        wlst_path = self._alias_helper.get_wlst_attributes_path(location)
        _logger.finer('WLSDPLY-06100',
                      wlst_path,
                      class_name=_class_name,
                      method_name=_method_name)

        if not self.wlst_cd(wlst_path, location):
            return

        wlst_lsa_params = self._get_attributes_for_current_location(location)
        _logger.finest('WLSDPLY-06102',
                       self._wlst_helper.get_pwd(),
                       wlst_lsa_params,
                       class_name=_class_name,
                       method_name=_method_name)
        wlst_get_params = self._get_required_attributes(location)
        _logger.finest('WLSDPLY-06103',
                       str(location),
                       wlst_get_params,
                       class_name=_class_name,
                       method_name=_method_name)
        if wlst_lsa_params is not None:
            for wlst_lsa_param in wlst_lsa_params:
                if wlst_lsa_param in wlst_get_params:
                    success, wlst_value = self._get_attribute_value_with_get(
                        wlst_lsa_param, wlst_path)
                    if not success:
                        continue
                else:
                    _logger.finer('WLSDPLY-06131',
                                  wlst_lsa_param,
                                  class_name=_class_name,
                                  method_name=_method_name)
                    wlst_value = wlst_lsa_params[wlst_lsa_param]
                self._add_to_dictionary(dictionary, location, wlst_lsa_param,
                                        wlst_value, wlst_path)

        # These will come after the lsa / get params in the ordered dictionary
        wlst_extra_params = self._get_additional_parameters(location)
        _logger.finest('WLSDPLY-06149',
                       str(location),
                       wlst_extra_params,
                       class_name=_class_name,
                       method_name=_method_name)
        if wlst_extra_params is not None:
            for wlst_extra_param in wlst_extra_params:
                if wlst_extra_param in wlst_get_params:
                    success, wlst_value = self._get_attribute_value_with_get(
                        wlst_extra_param, wlst_path)
                    if success:
                        self._add_to_dictionary(dictionary, location,
                                                wlst_extra_param, wlst_value,
                                                wlst_path)
                    else:
                        _logger.info('WLSDPLY-06152',
                                     wlst_extra_param,
                                     location.get_folder_path(),
                                     class_name=_class_name,
                                     method_name=_method_name)
                elif self._is_defined_attribute(location, wlst_extra_param):
                    _logger.info('WLSDPLY-06154',
                                 wlst_extra_param,
                                 location.get_folder_path(),
                                 class_name=_class_name,
                                 method_name=_method_name)
                else:
                    _logger.info('WLSDPLY-06153',
                                 wlst_extra_param,
                                 location.get_folder_path(),
                                 class_name=_class_name,
                                 method_name=_method_name)

    def _get_attribute_value_with_get(self, wlst_get_param, wlst_path):
        _method_name = '_get_attribute_value_with_get'
        _logger.finest('WLSDPLY-06104',
                       wlst_get_param,
                       class_name=_class_name,
                       method_name=_method_name)
        success = False
        wlst_value = None
        try:
            wlst_value = self._wlst_helper.get(wlst_get_param)
            success = True
        except DiscoverException, pe:
            _logger.warning('WLSDPLY-06127',
                            wlst_get_param,
                            wlst_path,
                            pe.getLocalizedMessage(),
                            class_name=_class_name,
                            method_name=_method_name)
        return success, wlst_value
class ModelContext(object):
    """
    This class contains fields derived from the command-line parameters and external configuration files,
    excluding the model file.
    """
    _class_name = "ModelContext"

    __ORACLE_HOME_TOKEN = '@@ORACLE_HOME@@'
    __WL_HOME_TOKEN = '@@WL_HOME@@'
    __DOMAIN_HOME_TOKEN = '@@DOMAIN_HOME@@'
    __CURRENT_DIRECTORY_TOKEN = '@@PWD@@'
    __TEMP_DIRECTORY_TOKEN = '@@TMP@@'

    def __init__(self, program_name, arg_map):
        self._program_name = program_name
        self._logger = platform_logger.PlatformLogger('wlsdeploy.util')
        self._wls_helper = WebLogicHelper(self._logger)

        self._oracle_home = None
        self._wl_home = None
        self._java_home = None
        self._domain_home = None
        self._domain_name = None
        self._domain_parent_dir = None
        self._domain_type = 'WLS'
        self._domain_typedef = None
        self._admin_url = None
        self._admin_user = None
        self._admin_password = None
        self._archive_file_name = None
        self._archive_file = None
        self._model_file = None
        self._previous_model_file = None
        self._print_usage = None
        self._variable_file_name = None
        self._run_rcu = False
        self._rcu_database = None
        self._rcu_prefix = None
        self._rcu_sys_pass = None
        self._rcu_schema_pass = None
        self._encryption_passphrase = None
        self._encrypt_manual = False
        self._encrypt_one_pass = None
        self._use_encryption = False
        self._wl_version = None
        self._wlst_mode = None
        self._recursive = False
        self._attributes_only = False
        self._folders_only = False

        if CommandLineArgUtil.ORACLE_HOME_SWITCH in arg_map:
            self._oracle_home = arg_map[CommandLineArgUtil.ORACLE_HOME_SWITCH]
            self._wl_home = self._wls_helper.get_weblogic_home(
                self._oracle_home)

        if CommandLineArgUtil.JAVA_HOME_SWITCH in arg_map:
            self._java_home = arg_map[CommandLineArgUtil.JAVA_HOME_SWITCH]

        if CommandLineArgUtil.DOMAIN_HOME_SWITCH in arg_map:
            self._domain_home = arg_map[CommandLineArgUtil.DOMAIN_HOME_SWITCH]
            self._domain_name = os.path.basename(self._domain_home)

        if CommandLineArgUtil.DOMAIN_PARENT_SWITCH in arg_map:
            self._domain_parent_dir = arg_map[
                CommandLineArgUtil.DOMAIN_PARENT_SWITCH]

        if CommandLineArgUtil.DOMAIN_TYPE_SWITCH in arg_map:
            self._domain_type = arg_map[CommandLineArgUtil.DOMAIN_TYPE_SWITCH]

        if CommandLineArgUtil.ADMIN_URL_SWITCH in arg_map:
            self._admin_url = arg_map[CommandLineArgUtil.ADMIN_URL_SWITCH]

        if CommandLineArgUtil.ADMIN_USER_SWITCH in arg_map:
            self._admin_user = arg_map[CommandLineArgUtil.ADMIN_USER_SWITCH]

        if CommandLineArgUtil.ADMIN_PASS_SWITCH in arg_map:
            self._admin_password = arg_map[
                CommandLineArgUtil.ADMIN_PASS_SWITCH]

        if CommandLineArgUtil.ARCHIVE_FILE_SWITCH in arg_map:
            self._archive_file_name = arg_map[
                CommandLineArgUtil.ARCHIVE_FILE_SWITCH]

        if CommandLineArgUtil.MODEL_FILE_SWITCH in arg_map:
            self._model_file = arg_map[CommandLineArgUtil.MODEL_FILE_SWITCH]

        if CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH in arg_map:
            self._previous_model_file = arg_map[
                CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH]

        if CommandLineArgUtil.PRINT_USAGE_SWITCH in arg_map:
            self._print_usage = arg_map[CommandLineArgUtil.PRINT_USAGE_SWITCH]

        if CommandLineArgUtil.ATTRIBUTES_ONLY_SWITCH in arg_map:
            self._attributes_only = arg_map[
                CommandLineArgUtil.ATTRIBUTES_ONLY_SWITCH]

        if CommandLineArgUtil.FOLDERS_ONLY_SWITCH in arg_map:
            self._folders_only = arg_map[
                CommandLineArgUtil.FOLDERS_ONLY_SWITCH]

        if CommandLineArgUtil.RECURSIVE_SWITCH in arg_map:
            self._recursive = arg_map[CommandLineArgUtil.RECURSIVE_SWITCH]

        if CommandLineArgUtil.VARIABLE_FILE_SWITCH in arg_map:
            self._variable_file_name = arg_map[
                CommandLineArgUtil.VARIABLE_FILE_SWITCH]

        if CommandLineArgUtil.RUN_RCU_SWITCH in arg_map:
            self._run_rcu = arg_map[CommandLineArgUtil.RUN_RCU_SWITCH]

        if CommandLineArgUtil.RCU_DB_SWITCH in arg_map:
            self._rcu_database = arg_map[CommandLineArgUtil.RCU_DB_SWITCH]

        if CommandLineArgUtil.RCU_PREFIX_SWITCH in arg_map:
            self._rcu_prefix = arg_map[CommandLineArgUtil.RCU_PREFIX_SWITCH]

        if CommandLineArgUtil.RCU_SYS_PASS_SWITCH in arg_map:
            self._rcu_sys_pass = arg_map[
                CommandLineArgUtil.RCU_SYS_PASS_SWITCH]

        if CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH in arg_map:
            self._rcu_schema_pass = arg_map[
                CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH]

        if CommandLineArgUtil.DOMAIN_TYPEDEF in arg_map:
            self._domain_typedef = arg_map[CommandLineArgUtil.DOMAIN_TYPEDEF]

        if CommandLineArgUtil.PASSPHRASE_SWITCH in arg_map:
            self._encryption_passphrase = arg_map[
                CommandLineArgUtil.PASSPHRASE_SWITCH]

        if CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH in arg_map:
            self._encrypt_manual = arg_map[
                CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH]

        if CommandLineArgUtil.ONE_PASS_SWITCH in arg_map:
            self._encrypt_one_pass = arg_map[
                CommandLineArgUtil.ONE_PASS_SWITCH]

        if CommandLineArgUtil.USE_ENCRYPTION_SWITCH in arg_map:
            self._use_encryption = arg_map[
                CommandLineArgUtil.USE_ENCRYPTION_SWITCH]

        if CommandLineArgUtil.ARCHIVE_FILE in arg_map:
            self._archive_file = arg_map[CommandLineArgUtil.ARCHIVE_FILE]

        if CommandLineArgUtil.TARGET_VERSION_SWITCH in arg_map:
            self._wl_version = arg_map[
                CommandLineArgUtil.TARGET_VERSION_SWITCH]

        if CommandLineArgUtil.TARGET_MODE_SWITCH in arg_map:
            wlst_mode_string = arg_map[CommandLineArgUtil.TARGET_MODE_SWITCH]
            if wlst_mode_string.lower() == 'online':
                self._wlst_mode = WlstModes.ONLINE
            else:
                self._wlst_mode = WlstModes.OFFLINE

        if self._wl_version is None:
            self._wl_version = self._wls_helper.get_actual_weblogic_version()

        if self._wlst_mode is None:
            self._wlst_mode = WlstModes.OFFLINE

        return

    def get_program_name(self):
        """
        Get the program name of the program that is executing.
        :return: the program name
        """
        return self._program_name

    def get_oracle_home(self):
        """
        Get the Oracle Home.
        :return: the Oracle Home
        """
        return self._oracle_home

    def get_wl_home(self):
        """
        Get the WebLogic Home.
        :return: the WebLogic Home
        """
        return self._wl_home

    def get_java_home(self):
        """
        Get the Java Home.
        :return: the Java Home
        """
        return self._java_home

    def get_domain_home(self):
        """
        Get the Domain Home.
        :return: the Domain Home
        """
        return self._domain_home

    def get_domain_name(self):
        """
        Get the Domain name.
        :return: the Domain name
        """
        return self._domain_name

    def set_domain_home(self, domain_home):
        """
        This method is a hack to allow create to add the domain home after reading the domain name from the model.
        This method is a no-op if the domain home was previously initialized via command-line argument processing.
        :param domain_home: the domain home directory
        """
        if self._domain_home is None and domain_home is not None and len(
                domain_home) > 0:
            self._domain_home = domain_home
            self._domain_name = os.path.basename(self._domain_home)
        return

    def get_domain_parent_dir(self):
        """
        Get the domain parent directory
        :return: the domain parent directory
        """
        return self._domain_parent_dir

    def get_domain_type(self):
        """
        Get the domain type.
        :return: the domain type
        """
        return self._domain_type

    def get_domain_typedef(self):
        """
        Get the domain typedef.
        :return: the domain typedef
        """
        return self._domain_typedef

    def get_admin_url(self):
        """
        Get the admin URL.
        :return: the admin URL
        """
        return self._admin_url

    def get_admin_user(self):
        """
        Get the admin username.
        :return: the admin username
        """
        return self._admin_user

    def get_admin_password(self):
        """
        Get the admin password.
        :return: the admin password
        """
        return self._admin_password

    def get_archive_file_name(self):
        """
        Get the archive file name.
        :return: the archive file name
        """
        return self._archive_file_name

    def get_archive_file(self):
        """
        Get the archive file.
        :return: the archive file
        """
        return self._archive_file

    def get_model_file(self):
        """
        Get the model file.
        :return: the model file
        """
        return self._model_file

    def get_previous_model_file(self):
        """
        Get the previous model file.
        :return: the previous model file
        """
        return self._previous_model_file

    def get_print_usage(self):
        """
        Get the print usage value.
        :return: the print usage value
        """
        return self._print_usage

    def get_folders_only_control_option(self):
        """
        Get the -folders_only command-line switch associated
        with print usage value.
        :return: the -folders_only command-line switch
        """
        return self._folders_only

    def get_attributes_only_control_option(self):
        """
        Get the -attributes_only command-line switch associated
        with print usage value.
        :return: the -attributes_only command-line switch
        """
        return self._attributes_only

    def get_recursive_control_option(self):
        """
        Get the -recursive command-line switch associated
        with print usage value.
        :return: the -recursive command-line switch
        """
        return self._recursive

    def get_variable_file(self):
        """
        Get the variable file.
        :return: the variable file
        """
        return self._variable_file_name

    def is_run_rcu(self):
        """
        Get whether or not to run RCU.
        :return: whether or not to run RCU
        """
        return self._run_rcu

    def get_rcu_database(self):
        """
        Get the RCU database connect string.
        :return: the RCU database connect string
        """
        return self._rcu_database

    def get_rcu_prefix(self):
        """
        Get the RCU prefix.
        :return: the RCU prefix
        """
        return self._rcu_prefix

    def get_rcu_sys_pass(self):
        """
        Get the RCU database SYS user password.
        :return: the RCU database SYS user password
        """
        return self._rcu_sys_pass

    def get_rcu_schema_pass(self):
        """
        Get the RCU schema users' password.
        :return: the RCU schema users' password
        """
        return self._rcu_schema_pass

    def get_encryption_passphrase(self):
        """
        Get the encryption passphrase.
        :return: the encryption passphrase
        """
        return self._encryption_passphrase

    def is_encryption_manual(self):
        """
        Get whether or not the user selected to do manual encryption.
        :return: whether or not the user selected to do manual encryption
        """
        return self._encrypt_manual

    def get_encrypt_one_pass(self):
        """
        Get the password to encrypt manually.
        :return: the password to encrypt manually
        """
        return self._encrypt_one_pass

    def is_using_encryption(self):
        """
        Get whether or not the model is using encryption.
        :return: whether or not the model is using encryption
        """
        return self._use_encryption

    def get_target_wls_version(self):
        """
        Get the target WebLogic version.
        :return: the target WebLogic version
        """
        return self._wl_version

    def get_target_wlst_mode(self):
        """
        Get the target WLST mode.
        :return: the target WLST mode
        """
        return self._wlst_mode

    def is_wlst_online(self):
        """
        Determine if the tool was started using WLST online mode
        :return: True if the tool is in online mode
        """
        return self._wlst_mode == WlstModes.ONLINE

    def is_wlst_offline(self):
        """
        Determine if the tool was started using WLST offline mode
        :return: True if the tool is in offline mode
        """
        return self._wlst_mode == WlstModes.OFFLINE

    def replace_tokens_in_path(self, attribute_name, resource_dict):
        """
        Replace any tokens in a path with the current values.
        :param attribute_name: the attrribute name
        :param resource_dict: the dictionary to use to lookup and replace the attribute value
        """
        separator = ':'
        path_elements = resource_dict[attribute_name].split(':')
        semicolon_path_elements = resource_dict[attribute_name].split(';')
        if len(semicolon_path_elements) > len(path_elements):
            separator = ';'
            path_elements = semicolon_path_elements

        for index, value in enumerate(path_elements):
            path_elements[index] = self.replace_token_string(value)

        result = ''
        for path_element in path_elements:
            if len(result) != 0:
                result += separator
            result += path_element

        resource_dict[attribute_name] = result
        return

    def has_token_prefix(self, path):
        """
        Determines if the specified path begins with one of the known, portable token prefix paths.
        :param path: the path to check for token prefix
        :return: true if the path begins with a known prefix, false otherwise
        """
        return path.startswith(self.__ORACLE_HOME_TOKEN) or \
               path.startswith(self.__WL_HOME_TOKEN) or \
               path.startswith(self.__DOMAIN_HOME_TOKEN) or \
               path.startswith(self.__CURRENT_DIRECTORY_TOKEN) or \
               path.startswith(self.__TEMP_DIRECTORY_TOKEN)

    def replace_tokens(self, resource_type, resource_name, attribute_name,
                       resource_dict):
        """
        Replace the tokens in attribute value with the current value.
        :param resource_type: the resource type (used for logging purposes)
        :param resource_name: the resource name (used for logging purposes)
        :param attribute_name: the attribute name for which to replace tokens
        :param resource_dict: the dictionary to use to lookup and replace the attribute value
        """
        attribute_value = resource_dict[attribute_name]
        if attribute_value.startswith(self.__ORACLE_HOME_TOKEN):
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.__ORACLE_HOME_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              self.get_oracle_home(),
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.__ORACLE_HOME_TOKEN, self.get_oracle_home())
        elif attribute_value.startswith(self.__WL_HOME_TOKEN):
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.__WL_HOME_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              self.get_wl_home(),
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.__WL_HOME_TOKEN, self.get_wl_home())
        elif attribute_value.startswith(self.__DOMAIN_HOME_TOKEN):
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.__DOMAIN_HOME_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              self.get_domain_home(),
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.__DOMAIN_HOME_TOKEN, self.get_domain_home())
        elif attribute_value.startswith(self.__CURRENT_DIRECTORY_TOKEN):
            cwd = path_utils.fixup_path(os.getcwd())
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.__CURRENT_DIRECTORY_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              cwd,
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.__CURRENT_DIRECTORY_TOKEN, cwd)
        elif attribute_value.startswith(self.__TEMP_DIRECTORY_TOKEN):
            temp_dir = path_utils.fixup_path(tempfile.gettempdir())
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.__TEMP_DIRECTORY_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              temp_dir,
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.__TEMP_DIRECTORY_TOKEN, temp_dir)

        return

    def replace_token_string(self, string_value):
        """
        Replace the tokens in string value with the current value of the token.
        :param string_value: the value on which to perform token replacement
        :return: the detokenized value, or the original value if there were no tokens
        """
        if string_value is None:
            result = None
        elif string_value.startswith(self.__ORACLE_HOME_TOKEN):
            result = _replace(string_value, self.__ORACLE_HOME_TOKEN,
                              self.get_oracle_home())
        elif string_value.startswith(self.__WL_HOME_TOKEN):
            result = _replace(string_value, self.__WL_HOME_TOKEN,
                              self.get_wl_home())
        elif string_value.startswith(self.__DOMAIN_HOME_TOKEN):
            result = _replace(string_value, self.__DOMAIN_HOME_TOKEN,
                              self.get_domain_home())
        elif string_value.startswith(self.__CURRENT_DIRECTORY_TOKEN):
            result = _replace(string_value, self.__CURRENT_DIRECTORY_TOKEN,
                              path_utils.fixup_path(os.getcwd()))
        elif string_value.startswith(self.__TEMP_DIRECTORY_TOKEN):
            result = _replace(string_value, self.__TEMP_DIRECTORY_TOKEN,
                              path_utils.fixup_path(tempfile.gettempdir()))
        else:
            result = string_value

        return result

    def tokenize_path(self, path):
        """
        Replace known directories that will be different in the target with tokens denoting the type
        of directory

        :param path: to check for directories to be tokenized
        :return: tokenized path or original path
        """
        my_path = path_utils.fixup_path(path)
        tmp_dir = path_utils.fixup_path(tempfile.gettempdir())
        cwd = path_utils.fixup_path(os.path.dirname(os.path.abspath(__file__)))

        # decide later what is required to be in context home for appropriate exception prevention
        result = my_path
        if my_path:
            if self.get_wl_home() and my_path.startswith(self.get_wl_home()):
                result = my_path.replace(self.get_wl_home(),
                                         self.__WL_HOME_TOKEN)
            elif self.get_domain_home() and my_path.startswith(
                    self.get_domain_home()):
                result = my_path.replace(self.get_domain_home(),
                                         self.__DOMAIN_HOME_TOKEN)
            elif self.get_oracle_home() and my_path.startswith(
                    self.get_oracle_home()):
                result = my_path.replace(self.get_oracle_home(),
                                         self.__ORACLE_HOME_TOKEN)
            elif my_path.startswith(cwd):
                result = my_path.replace(cwd, self.__CURRENT_DIRECTORY_TOKEN)
            elif my_path.startswith(tmp_dir):
                result = my_path.replace(tmp_dir, self.__TEMP_DIRECTORY_TOKEN)

        return result

    def tokenize_classpath(self, classpath):
        """
        Replace known types of directories with a tokens that represent the directory.

        :param classpath: containing a string of directories separated by environment specific classpath separator
        :return: tokenized classpath string
        """
        cp_elements, separator = path_utils.split_classpath(classpath)
        for index, value in enumerate(cp_elements):
            cp_elements[index] = self.tokenize_path(value)

        return separator.join(cp_elements)
Example #8
0
class ModelContext(object):
    """
    This class contains fields derived from the command-line parameters and external configuration files,
    excluding the model file.
    """
    _class_name = "ModelContext"

    ORACLE_HOME_TOKEN = '@@ORACLE_HOME@@'
    WL_HOME_TOKEN = '@@WL_HOME@@'
    DOMAIN_HOME_TOKEN = '@@DOMAIN_HOME@@'
    JAVA_HOME_TOKEN = '@@JAVA_HOME@@'
    CURRENT_DIRECTORY_TOKEN = '@@PWD@@'
    TEMP_DIRECTORY_TOKEN = '@@TMP@@'

    def __init__(self, program_name, arg_map):
        """
        Create a new model context instance.
        Tools should use model_context_helper.create_context(), to ensure that the typedef is initialized correctly.
        Unit tests should use this constructor directly, since typedef files are not deployed.
        :param program_name: the program name, used for logging
        :param arg_map: all the arguments passed to the tool
        """
        self._program_name = program_name
        self._logger = platform_logger.PlatformLogger('wlsdeploy.util')
        self._wls_helper = WebLogicHelper(self._logger)

        self._oracle_home = None
        self._wl_home = None
        self._java_home = None
        self._domain_home = None
        self._domain_name = None
        self._domain_parent_dir = None
        self._domain_type = 'WLS'
        self._domain_typedef = None
        self._admin_url = None
        self._admin_user = None
        self._admin_password = None
        self._archive_file_name = None
        self._archive_file = None
        self._model_file = None
        self._model_sample = False
        self._previous_model_file = None
        self._variable_file_name = None
        self._run_rcu = False
        self._rcu_database = None
        self._rcu_prefix = None
        self._rcu_sys_pass = None
        self._rcu_schema_pass = None
        self._encryption_passphrase = None
        self._encrypt_manual = False
        self._encrypt_one_pass = None
        self._use_encryption = False
        self._wl_version = None
        self._wlst_mode = None
        self._recursive = False
        self._attributes_only = False
        self._folders_only = False
        self._opss_wallet_passphrase = None
        self._opss_wallet = None
        self._update_rcu_schema_pass = False
        self._validation_method = None
        self._rollback_if_restart_required = None
        self._domain_resource_file = None
        self._output_dir = None
        self._target = None
        self._target_configuration = None
        self._variable_injector_file = None
        self._variable_keywords_file = None
        self._variable_properties_file = None
        self._rcu_db_user = '******'

        self._trailing_args = []

        if CommandLineArgUtil.ORACLE_HOME_SWITCH in arg_map:
            self._oracle_home = arg_map[CommandLineArgUtil.ORACLE_HOME_SWITCH]
            self._wl_home = self._wls_helper.get_weblogic_home(
                self._oracle_home)

        if CommandLineArgUtil.JAVA_HOME_SWITCH in arg_map:
            self._java_home = arg_map[CommandLineArgUtil.JAVA_HOME_SWITCH]

        if CommandLineArgUtil.DOMAIN_HOME_SWITCH in arg_map:
            self._domain_home = arg_map[CommandLineArgUtil.DOMAIN_HOME_SWITCH]
            self._domain_name = os.path.basename(self._domain_home)

        if CommandLineArgUtil.DOMAIN_PARENT_SWITCH in arg_map:
            self._domain_parent_dir = arg_map[
                CommandLineArgUtil.DOMAIN_PARENT_SWITCH]

        if CommandLineArgUtil.DOMAIN_TYPE_SWITCH in arg_map:
            self._domain_type = arg_map[CommandLineArgUtil.DOMAIN_TYPE_SWITCH]

        if CommandLineArgUtil.ADMIN_URL_SWITCH in arg_map:
            self._admin_url = arg_map[CommandLineArgUtil.ADMIN_URL_SWITCH]

        if CommandLineArgUtil.ADMIN_USER_SWITCH in arg_map:
            self._admin_user = arg_map[CommandLineArgUtil.ADMIN_USER_SWITCH]

        if CommandLineArgUtil.ADMIN_PASS_SWITCH in arg_map:
            self._admin_password = arg_map[
                CommandLineArgUtil.ADMIN_PASS_SWITCH]

        if CommandLineArgUtil.ARCHIVE_FILE_SWITCH in arg_map:
            self._archive_file_name = arg_map[
                CommandLineArgUtil.ARCHIVE_FILE_SWITCH]

        if CommandLineArgUtil.MODEL_FILE_SWITCH in arg_map:
            self._model_file = arg_map[CommandLineArgUtil.MODEL_FILE_SWITCH]

        if CommandLineArgUtil.MODEL_SAMPLE_SWITCH in arg_map:
            self._model_sample = arg_map[
                CommandLineArgUtil.MODEL_SAMPLE_SWITCH]

        if CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH in arg_map:
            self._previous_model_file = arg_map[
                CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH]

        if CommandLineArgUtil.ATTRIBUTES_ONLY_SWITCH in arg_map:
            self._attributes_only = arg_map[
                CommandLineArgUtil.ATTRIBUTES_ONLY_SWITCH]

        if CommandLineArgUtil.FOLDERS_ONLY_SWITCH in arg_map:
            self._folders_only = arg_map[
                CommandLineArgUtil.FOLDERS_ONLY_SWITCH]

        if CommandLineArgUtil.RECURSIVE_SWITCH in arg_map:
            self._recursive = arg_map[CommandLineArgUtil.RECURSIVE_SWITCH]

        if CommandLineArgUtil.VARIABLE_FILE_SWITCH in arg_map:
            self._variable_file_name = arg_map[
                CommandLineArgUtil.VARIABLE_FILE_SWITCH]

        if CommandLineArgUtil.RUN_RCU_SWITCH in arg_map:
            self._run_rcu = arg_map[CommandLineArgUtil.RUN_RCU_SWITCH]

        if CommandLineArgUtil.RCU_DB_SWITCH in arg_map:
            self._rcu_database = arg_map[CommandLineArgUtil.RCU_DB_SWITCH]

        if CommandLineArgUtil.RCU_PREFIX_SWITCH in arg_map:
            self._rcu_prefix = arg_map[CommandLineArgUtil.RCU_PREFIX_SWITCH]

        if CommandLineArgUtil.RCU_SYS_PASS_SWITCH in arg_map:
            self._rcu_sys_pass = arg_map[
                CommandLineArgUtil.RCU_SYS_PASS_SWITCH]

        if CommandLineArgUtil.RCU_DB_USER_SWITCH in arg_map:
            self._rcu_db_user = arg_map[CommandLineArgUtil.RCU_DB_USER_SWITCH]

        if CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH in arg_map:
            self._rcu_schema_pass = arg_map[
                CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH]

        if CommandLineArgUtil.DOMAIN_TYPEDEF in arg_map:
            self._domain_typedef = arg_map[CommandLineArgUtil.DOMAIN_TYPEDEF]

        if CommandLineArgUtil.PASSPHRASE_SWITCH in arg_map:
            self._encryption_passphrase = arg_map[
                CommandLineArgUtil.PASSPHRASE_SWITCH]

        if CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH in arg_map:
            self._encrypt_manual = arg_map[
                CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH]

        if CommandLineArgUtil.ONE_PASS_SWITCH in arg_map:
            self._encrypt_one_pass = arg_map[
                CommandLineArgUtil.ONE_PASS_SWITCH]

        if CommandLineArgUtil.ROLLBACK_IF_RESTART_REQ_SWITCH in arg_map:
            self._rollback_if_restart_required = arg_map[
                CommandLineArgUtil.ROLLBACK_IF_RESTART_REQ_SWITCH]

        if CommandLineArgUtil.USE_ENCRYPTION_SWITCH in arg_map:
            self._use_encryption = arg_map[
                CommandLineArgUtil.USE_ENCRYPTION_SWITCH]

        if CommandLineArgUtil.ARCHIVE_FILE in arg_map:
            self._archive_file = arg_map[CommandLineArgUtil.ARCHIVE_FILE]

        if CommandLineArgUtil.OPSS_WALLET_PASSPHRASE in arg_map:
            self._opss_wallet_passphrase = arg_map[
                CommandLineArgUtil.OPSS_WALLET_PASSPHRASE]

        if CommandLineArgUtil.OPSS_WALLET_SWITCH in arg_map:
            self._opss_wallet = arg_map[CommandLineArgUtil.OPSS_WALLET_SWITCH]

        if CommandLineArgUtil.UPDATE_RCU_SCHEMA_PASS_SWITCH in arg_map:
            self._update_rcu_schema_pass = True

        if CommandLineArgUtil.VALIDATION_METHOD in arg_map:
            self._validation_method = arg_map[
                CommandLineArgUtil.VALIDATION_METHOD]

        if CommandLineArgUtil.TARGET_VERSION_SWITCH in arg_map:
            self._wl_version = arg_map[
                CommandLineArgUtil.TARGET_VERSION_SWITCH]

        if CommandLineArgUtil.DOMAIN_RESOURCE_FILE_SWITCH in arg_map:
            self._domain_resource_file = arg_map[
                CommandLineArgUtil.DOMAIN_RESOURCE_FILE_SWITCH]

        if CommandLineArgUtil.TRAILING_ARGS_SWITCH in arg_map:
            self._trailing_args = arg_map[
                CommandLineArgUtil.TRAILING_ARGS_SWITCH]

        if CommandLineArgUtil.TARGET_SWITCH in arg_map:
            self._target = arg_map[CommandLineArgUtil.TARGET_SWITCH]

        if CommandLineArgUtil.TARGET_MODE_SWITCH in arg_map:
            wlst_mode_string = arg_map[CommandLineArgUtil.TARGET_MODE_SWITCH]
            if wlst_mode_string.lower() == 'online':
                self._wlst_mode = WlstModes.ONLINE
            else:
                self._wlst_mode = WlstModes.OFFLINE

        if CommandLineArgUtil.OUTPUT_DIR_SWITCH in arg_map:
            self._output_dir = arg_map[CommandLineArgUtil.OUTPUT_DIR_SWITCH]

        if CommandLineArgUtil.VARIABLE_INJECTOR_FILE_SWITCH in arg_map:
            self._variable_injector_file = arg_map[
                CommandLineArgUtil.VARIABLE_INJECTOR_FILE_SWITCH]

        if CommandLineArgUtil.VARIABLE_KEYWORDS_FILE_SWITCH in arg_map:
            self._variable_keywords_file = arg_map[
                CommandLineArgUtil.VARIABLE_KEYWORDS_FILE_SWITCH]

        if CommandLineArgUtil.VARIABLE_PROPERTIES_FILE_SWITCH in arg_map:
            self._variable_properties_file = arg_map[
                CommandLineArgUtil.VARIABLE_PROPERTIES_FILE_SWITCH]

        if self._wl_version is None:
            self._wl_version = self._wls_helper.get_actual_weblogic_version()

        if self._wlst_mode is None:
            self._wlst_mode = WlstModes.OFFLINE

        return

    def get_program_name(self):
        """
        Get the program name of the program that is executing.
        :return: the program name
        """
        return self._program_name

    def get_oracle_home(self):
        """
        Get the Oracle Home.
        :return: the Oracle Home
        """
        return self._oracle_home

    def get_wl_home(self):
        """
        Get the WebLogic Home.
        :return: the WebLogic Home
        """
        return self._wl_home

    def get_java_home(self):
        """
        Get the Java Home.
        :return: the Java Home
        """
        return self._java_home

    def get_domain_home(self):
        """
        Get the Domain Home.
        :return: the Domain Home
        """
        return self._domain_home

    def get_domain_name(self):
        """
        Get the Domain name.
        :return: the Domain name
        """
        return self._domain_name

    def set_domain_home(self, domain_home):
        """
        This method is a hack to allow create to add the domain home after reading the domain name from the model.
        This method is a no-op if the domain home was previously initialized via command-line argument processing.
        :param domain_home: the domain home directory
        """
        if self._domain_home is None and domain_home is not None and len(
                domain_home) > 0:
            self._domain_home = domain_home
            self._domain_name = os.path.basename(self._domain_home)
        return

    def get_domain_parent_dir(self):
        """
        Get the domain parent directory
        :return: the domain parent directory
        """
        return self._domain_parent_dir

    def get_domain_type(self):
        """
        Get the domain type.
        :return: the domain type
        """
        return self._domain_type

    def get_domain_typedef(self):
        """
        Get the domain typedef.
        :return: the domain typedef
        """
        return self._domain_typedef

    def get_domain_resource_file(self):
        """
        Get the domain resource file.
        :return: the domain resource file
        """
        return self._domain_resource_file

    def get_admin_url(self):
        """
        Get the admin URL.
        :return: the admin URL
        """
        return self._admin_url

    def get_admin_user(self):
        """
        Get the admin username.
        :return: the admin username
        """
        return self._admin_user

    def get_admin_password(self):
        """
        Get the admin password.
        :return: the admin password
        """
        return self._admin_password

    def get_archive_file_name(self):
        """
        Get the archive file name.
        :return: the archive file name
        """
        return self._archive_file_name

    def is_rollback_if_restart_required(self):
        """
        Get the rollback if restart required
        :return: true or false
        """
        return self._rollback_if_restart_required

    def get_opss_wallet(self):
        """
        Get the opss wallet.
        :return: the opss wallet
        """
        return self._opss_wallet

    def get_opss_wallet_passphrase(self):
        """
        Get the wallet passphrase.
        :return: the wallet passphrase
        """
        return self._opss_wallet_passphrase

    def get_update_rcu_schema_pass(self):
        """
        Get the update rcu schema password flag
        """
        return self._update_rcu_schema_pass

    def get_validation_method(self):
        """
        Get the validation method.
        :return: the validation method
        """
        if self._validation_method is None:
            self._validation_method = 'strict'
        return self._validation_method

    def set_validation_method(self, method):
        """
        Set the validation method.
        :param method: validation method
        """
        self._validation_method = method

    def get_archive_file(self):
        """
        Get the archive file.
        :return: the archive file
        """
        return self._archive_file

    def get_model_file(self):
        """
        Get the model file.
        :return: the model file
        """
        return self._model_file

    def get_previous_model_file(self):
        """
        Get the previous model file.
        :return: the previous model file
        """
        return self._previous_model_file

    def get_folders_only_control_option(self):
        """
        Get the -folders_only command-line switch for model help tool.
        :return: the -folders_only command-line switch
        """
        return self._folders_only

    def get_attributes_only_control_option(self):
        """
        Get the -attributes_only command-line switch for model help tool.
        :return: the -attributes_only command-line switch
        """
        return self._attributes_only

    def get_recursive_control_option(self):
        """
        Get the -recursive command-line switch for model help tool.
        :return: the -recursive command-line switch
        """
        return self._recursive

    def get_model_sample_option(self):
        """
        Get the -model_sample command-line switch for model help tool.
        :return: the -recursive command-line switch
        """
        return self._model_sample

    def get_variable_file(self):
        """
        Get the variable file.
        :return: the variable file
        """
        return self._variable_file_name

    def is_run_rcu(self):
        """
        Get whether or not to run RCU.
        :return: whether or not to run RCU
        """
        return self._run_rcu

    def get_rcu_database(self):
        """
        Get the RCU database connect string.
        :return: the RCU database connect string
        """
        return self._rcu_database

    def get_rcu_prefix(self):
        """
        Get the RCU prefix.
        :return: the RCU prefix
        """
        return self._rcu_prefix

    def get_rcu_db_user(self):
        """
        Get the RCU DB user.
        :return: the RCU dbUser
        """
        return self._rcu_db_user

    def get_rcu_sys_pass(self):
        """
        Get the RCU database SYS user password.
        :return: the RCU database SYS user password
        """
        return self._rcu_sys_pass

    def get_rcu_schema_pass(self):
        """
        Get the RCU schema users' password.
        :return: the RCU schema users' password
        """
        return self._rcu_schema_pass

    def get_encryption_passphrase(self):
        """
        Get the encryption passphrase.
        :return: the encryption passphrase
        """
        return self._encryption_passphrase

    def get_compare_model_output_dir(self):
        """
        Return the compare model output dir
        :return: output dir for compare models tool
        """
        return self._output_dir

    def get_kubernetes_output_dir(self):
        """
        Return the output directory for generated k8s target.
        :return: output directory
        """
        return self._output_dir

    def get_target_configuration(self):
        """
        Return the target configuration object, based on the target name.
        Lazy-load this the first time it is requested.
        :return: target configuration object
        """
        if self._target_configuration is None:
            configuration_dict = {}

            if self._target:
                target_path = os.path.join('targets', self._target,
                                           'target.json')
                target_configuration_file = path_utils.find_config_path(
                    target_path)
                if os.path.exists(target_configuration_file):
                    file_handle = open(target_configuration_file)
                    configuration_dict = eval(file_handle.read())

            self._target_configuration = TargetConfiguration(
                configuration_dict)

        return self._target_configuration

    def get_target(self):
        return self._target

    def is_targetted_config(self):
        """
        Return the output directory for generated k8s target.
        :return: output directory
        """
        return self._target is not None

    def is_encryption_manual(self):
        """
        Get whether or not the user selected to do manual encryption.
        :return: whether or not the user selected to do manual encryption
        """
        return self._encrypt_manual

    def get_encrypt_one_pass(self):
        """
        Get the password to encrypt manually.
        :return: the password to encrypt manually
        """
        return self._encrypt_one_pass

    def is_using_encryption(self):
        """
        Get whether or not the model is using encryption.
        :return: whether or not the model is using encryption
        """
        return self._use_encryption

    def get_target_wls_version(self):
        """
        Get the target WebLogic version.
        :return: the target WebLogic version
        """
        return self._wl_version

    def get_target_wlst_mode(self):
        """
        Get the target WLST mode.
        :return: the target WLST mode
        """
        return self._wlst_mode

    def get_variable_injector_file(self):
        """
        Get the variable injector file override.
        :return: the variable injector file
        """
        return self._variable_injector_file

    def get_variable_keywords_file(self):
        """
        Get the variable keywords file override.
        :return: the variable keywords file
        """
        return self._variable_keywords_file

    def get_variable_properties_file(self):
        """
        Get the variable properties file override.
        :return: the variable properties file
        """
        return self._variable_properties_file

    def get_trailing_argument(self, index):
        """
        Get the trailing argument at index.
        :param index: the index of the trailing argument
        :return: the trailing argument
        """
        return self._trailing_args[index]

    def is_wlst_online(self):
        """
        Determine if the tool was started using WLST online mode
        :return: True if the tool is in online mode
        """
        return self._wlst_mode == WlstModes.ONLINE

    def is_wlst_offline(self):
        """
        Determine if the tool was started using WLST offline mode
        :return: True if the tool is in offline mode
        """
        return self._wlst_mode == WlstModes.OFFLINE

    def replace_tokens_in_path(self, attribute_name, resource_dict):
        """
        Replace any tokens in a path with the current values.
        :param attribute_name: the attrribute name
        :param resource_dict: the dictionary to use to lookup and replace the attribute value
        """
        separator = ':'
        attribute_value = resource_dict[attribute_name]
        path_elements = attribute_value.split(':')
        semicolon_path_elements = resource_dict[attribute_name].split(';')
        if len(semicolon_path_elements) > len(path_elements):
            separator = ';'
            path_elements = semicolon_path_elements

        for index, value in enumerate(path_elements):
            path_elements[index] = self.replace_token_string(value)

        result = ''
        for path_element in path_elements:
            if len(result) != 0:
                result += separator
            result += path_element

        resource_dict[attribute_name] = result
        return

    def has_token_prefix(self, path):
        """
        Determines if the specified path begins with one of the known, portable token prefix paths.
        :param path: the path to check for token prefix
        :return: true if the path begins with a known prefix, false otherwise
        """
        return path.startswith(self.ORACLE_HOME_TOKEN) or \
            path.startswith(self.WL_HOME_TOKEN) or \
            path.startswith(self.DOMAIN_HOME_TOKEN) or \
            path.startswith(self.JAVA_HOME_TOKEN) or \
            path.startswith(self.CURRENT_DIRECTORY_TOKEN) or \
            path.startswith(self.TEMP_DIRECTORY_TOKEN)

    def replace_tokens(self, resource_type, resource_name, attribute_name,
                       resource_dict):
        """
        Replace the tokens in attribute value with the current value.
        :param resource_type: the resource type (used for logging purposes)
        :param resource_name: the resource name (used for logging purposes)
        :param attribute_name: the attribute name for which to replace tokens
        :param resource_dict: the dictionary to use to lookup and replace the attribute value
        """
        attribute_value = resource_dict[attribute_name]
        uri = URI(attribute_value)
        if uri.getScheme().startsWith('file'):
            attribute_value = uri.getPath()
        if attribute_value.startswith(self.ORACLE_HOME_TOKEN):
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.ORACLE_HOME_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              self.get_oracle_home(),
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.ORACLE_HOME_TOKEN, self.get_oracle_home())
        elif attribute_value.startswith(self.WL_HOME_TOKEN):
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.WL_HOME_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              self.get_wl_home(),
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.WL_HOME_TOKEN, self.get_wl_home())
        elif attribute_value.startswith(self.DOMAIN_HOME_TOKEN):
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.DOMAIN_HOME_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              self.get_domain_home(),
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.DOMAIN_HOME_TOKEN, self.get_domain_home())
        elif attribute_value.startswith(self.JAVA_HOME_TOKEN):
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.JAVA_HOME_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              self.get_domain_home(),
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.JAVA_HOME_TOKEN, self.get_java_home())
        elif attribute_value.startswith(self.CURRENT_DIRECTORY_TOKEN):
            cwd = path_utils.fixup_path(os.getcwd())
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.CURRENT_DIRECTORY_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              cwd,
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.CURRENT_DIRECTORY_TOKEN, cwd)
        elif attribute_value.startswith(self.TEMP_DIRECTORY_TOKEN):
            temp_dir = path_utils.fixup_path(tempfile.gettempdir())
            message = "Replacing {0} in {1} {2} {3} with {4}"
            self._logger.fine(message,
                              self.TEMP_DIRECTORY_TOKEN,
                              resource_type,
                              resource_name,
                              attribute_name,
                              temp_dir,
                              class_name=self._class_name,
                              method_name='_replace_tokens')
            resource_dict[attribute_name] = attribute_value.replace(
                self.TEMP_DIRECTORY_TOKEN, temp_dir)

        return

    def replace_token_string(self, string_value):
        """
        Replace the tokens in string value with the current value of the token.
        :param string_value: the value on which to perform token replacement
        :return: the detokenized value, or the original value if there were no tokens
        """
        if string_value is None:
            result = None
        elif string_value.startswith(self.ORACLE_HOME_TOKEN):
            result = _replace(string_value, self.ORACLE_HOME_TOKEN,
                              self.get_oracle_home())
        elif string_value.startswith(self.WL_HOME_TOKEN):
            result = _replace(string_value, self.WL_HOME_TOKEN,
                              self.get_wl_home())
        elif string_value.startswith(self.DOMAIN_HOME_TOKEN):
            result = _replace(string_value, self.DOMAIN_HOME_TOKEN,
                              self.get_domain_home())
        elif string_value.startswith(self.JAVA_HOME_TOKEN):
            result = _replace(string_value, self.JAVA_HOME_TOKEN,
                              self.get_java_home())
        elif string_value.startswith(self.CURRENT_DIRECTORY_TOKEN):
            result = _replace(string_value, self.CURRENT_DIRECTORY_TOKEN,
                              path_utils.fixup_path(os.getcwd()))
        elif string_value.startswith(self.TEMP_DIRECTORY_TOKEN):
            result = _replace(string_value, self.TEMP_DIRECTORY_TOKEN,
                              path_utils.fixup_path(tempfile.gettempdir()))
        else:
            result = string_value

        return result

    def tokenize_path(self, path):
        """
        Replace known directories that will be different in the target with tokens denoting the type
        of directory

        :param path: to check for directories to be tokenized
        :return: tokenized path or original path
        """
        my_path = path_utils.fixup_path(path)
        wl_home = path_utils.fixup_path(self.get_wl_home())
        domain_home = path_utils.fixup_path(self.get_domain_home())
        oracle_home = path_utils.fixup_path(self.get_oracle_home())
        java_home = path_utils.fixup_path(self.get_java_home())
        tmp_dir = path_utils.fixup_path(tempfile.gettempdir())
        cwd = path_utils.fixup_path(os.path.dirname(os.path.abspath(__file__)))

        # decide later what is required to be in context home for appropriate exception prevention
        result = my_path
        if not string_utils.is_empty(my_path):
            if wl_home is not None and my_path.startswith(wl_home):
                result = my_path.replace(wl_home, self.WL_HOME_TOKEN)
            elif domain_home is not None and my_path.startswith(domain_home):
                result = my_path.replace(domain_home, self.DOMAIN_HOME_TOKEN)
            elif oracle_home is not None and my_path.startswith(oracle_home):
                result = my_path.replace(oracle_home, self.ORACLE_HOME_TOKEN)
            elif java_home is not None and my_path.startswith(java_home):
                result = my_path.replace(java_home, self.JAVA_HOME_TOKEN)
            elif my_path.startswith(cwd):
                result = my_path.replace(cwd, self.CURRENT_DIRECTORY_TOKEN)
            elif my_path.startswith(tmp_dir):
                result = my_path.replace(tmp_dir, self.TEMP_DIRECTORY_TOKEN)

        return result

    def tokenize_classpath(self, classpath):
        """
        Replace known types of directories with a tokens that represent the directory.

        :param classpath: containing a string of directories separated by environment specific classpath separator
        :return: tokenized classpath string
        """
        cp_elements, separator = path_utils.split_classpath(classpath)
        for index, value in enumerate(cp_elements):
            cp_elements[index] = self.tokenize_path(value)

        return separator.join(cp_elements)
Example #9
0
    def __init__(self, program_name, arg_map):
        """
        Create a new model context instance.
        Tools should use model_context_helper.create_context(), to ensure that the typedef is initialized correctly.
        Unit tests should use this constructor directly, since typedef files are not deployed.
        :param program_name: the program name, used for logging
        :param arg_map: all the arguments passed to the tool
        """
        self._program_name = program_name
        self._logger = platform_logger.PlatformLogger('wlsdeploy.util')
        self._wls_helper = WebLogicHelper(self._logger)

        self._oracle_home = None
        self._wl_home = None
        self._java_home = None
        self._domain_home = None
        self._domain_name = None
        self._domain_parent_dir = None
        self._domain_type = 'WLS'
        self._domain_typedef = None
        self._admin_url = None
        self._admin_user = None
        self._admin_password = None
        self._archive_file_name = None
        self._archive_file = None
        self._model_file = None
        self._previous_model_file = None
        self._variable_file_name = None
        self._run_rcu = False
        self._rcu_database = None
        self._rcu_prefix = None
        self._rcu_sys_pass = None
        self._rcu_schema_pass = None
        self._encryption_passphrase = None
        self._encrypt_manual = False
        self._encrypt_one_pass = None
        self._use_encryption = False
        self._wl_version = None
        self._wlst_mode = None
        self._recursive = False
        self._attributes_only = False
        self._folders_only = False
        self._opss_wallet_passphrase = None
        self._opss_wallet = None
        self._update_rcu_schema_pass = False
        self._validation_method = None
        self._rollback_if_restart_required = None
        self._domain_resource_file = None
        self._compare_model_output_dir = None
        self._trailing_args = []

        if CommandLineArgUtil.ORACLE_HOME_SWITCH in arg_map:
            self._oracle_home = arg_map[CommandLineArgUtil.ORACLE_HOME_SWITCH]
            self._wl_home = self._wls_helper.get_weblogic_home(
                self._oracle_home)

        if CommandLineArgUtil.JAVA_HOME_SWITCH in arg_map:
            self._java_home = arg_map[CommandLineArgUtil.JAVA_HOME_SWITCH]

        if CommandLineArgUtil.DOMAIN_HOME_SWITCH in arg_map:
            self._domain_home = arg_map[CommandLineArgUtil.DOMAIN_HOME_SWITCH]
            self._domain_name = os.path.basename(self._domain_home)

        if CommandLineArgUtil.DOMAIN_PARENT_SWITCH in arg_map:
            self._domain_parent_dir = arg_map[
                CommandLineArgUtil.DOMAIN_PARENT_SWITCH]

        if CommandLineArgUtil.DOMAIN_TYPE_SWITCH in arg_map:
            self._domain_type = arg_map[CommandLineArgUtil.DOMAIN_TYPE_SWITCH]

        if CommandLineArgUtil.ADMIN_URL_SWITCH in arg_map:
            self._admin_url = arg_map[CommandLineArgUtil.ADMIN_URL_SWITCH]

        if CommandLineArgUtil.ADMIN_USER_SWITCH in arg_map:
            self._admin_user = arg_map[CommandLineArgUtil.ADMIN_USER_SWITCH]

        if CommandLineArgUtil.ADMIN_PASS_SWITCH in arg_map:
            self._admin_password = arg_map[
                CommandLineArgUtil.ADMIN_PASS_SWITCH]

        if CommandLineArgUtil.ARCHIVE_FILE_SWITCH in arg_map:
            self._archive_file_name = arg_map[
                CommandLineArgUtil.ARCHIVE_FILE_SWITCH]

        if CommandLineArgUtil.MODEL_FILE_SWITCH in arg_map:
            self._model_file = arg_map[CommandLineArgUtil.MODEL_FILE_SWITCH]

        if CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH in arg_map:
            self._previous_model_file = arg_map[
                CommandLineArgUtil.PREVIOUS_MODEL_FILE_SWITCH]

        if CommandLineArgUtil.ATTRIBUTES_ONLY_SWITCH in arg_map:
            self._attributes_only = arg_map[
                CommandLineArgUtil.ATTRIBUTES_ONLY_SWITCH]

        if CommandLineArgUtil.FOLDERS_ONLY_SWITCH in arg_map:
            self._folders_only = arg_map[
                CommandLineArgUtil.FOLDERS_ONLY_SWITCH]

        if CommandLineArgUtil.RECURSIVE_SWITCH in arg_map:
            self._recursive = arg_map[CommandLineArgUtil.RECURSIVE_SWITCH]

        if CommandLineArgUtil.VARIABLE_FILE_SWITCH in arg_map:
            self._variable_file_name = arg_map[
                CommandLineArgUtil.VARIABLE_FILE_SWITCH]

        if CommandLineArgUtil.RUN_RCU_SWITCH in arg_map:
            self._run_rcu = arg_map[CommandLineArgUtil.RUN_RCU_SWITCH]

        if CommandLineArgUtil.RCU_DB_SWITCH in arg_map:
            self._rcu_database = arg_map[CommandLineArgUtil.RCU_DB_SWITCH]

        if CommandLineArgUtil.RCU_PREFIX_SWITCH in arg_map:
            self._rcu_prefix = arg_map[CommandLineArgUtil.RCU_PREFIX_SWITCH]

        if CommandLineArgUtil.RCU_SYS_PASS_SWITCH in arg_map:
            self._rcu_sys_pass = arg_map[
                CommandLineArgUtil.RCU_SYS_PASS_SWITCH]

        if CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH in arg_map:
            self._rcu_schema_pass = arg_map[
                CommandLineArgUtil.RCU_SCHEMA_PASS_SWITCH]

        if CommandLineArgUtil.DOMAIN_TYPEDEF in arg_map:
            self._domain_typedef = arg_map[CommandLineArgUtil.DOMAIN_TYPEDEF]

        if CommandLineArgUtil.PASSPHRASE_SWITCH in arg_map:
            self._encryption_passphrase = arg_map[
                CommandLineArgUtil.PASSPHRASE_SWITCH]

        if CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH in arg_map:
            self._encrypt_manual = arg_map[
                CommandLineArgUtil.ENCRYPT_MANUAL_SWITCH]

        if CommandLineArgUtil.ONE_PASS_SWITCH in arg_map:
            self._encrypt_one_pass = arg_map[
                CommandLineArgUtil.ONE_PASS_SWITCH]

        if CommandLineArgUtil.ROLLBACK_IF_RESTART_REQ_SWITCH in arg_map:
            self._rollback_if_restart_required = arg_map[
                CommandLineArgUtil.ROLLBACK_IF_RESTART_REQ_SWITCH]

        if CommandLineArgUtil.USE_ENCRYPTION_SWITCH in arg_map:
            self._use_encryption = arg_map[
                CommandLineArgUtil.USE_ENCRYPTION_SWITCH]

        if CommandLineArgUtil.ARCHIVE_FILE in arg_map:
            self._archive_file = arg_map[CommandLineArgUtil.ARCHIVE_FILE]

        if CommandLineArgUtil.OPSS_WALLET_PASSPHRASE in arg_map:
            self._opss_wallet_passphrase = arg_map[
                CommandLineArgUtil.OPSS_WALLET_PASSPHRASE]

        if CommandLineArgUtil.OPSS_WALLET_SWITCH in arg_map:
            self._opss_wallet = arg_map[CommandLineArgUtil.OPSS_WALLET_SWITCH]

        if CommandLineArgUtil.UPDATE_RCU_SCHEMA_PASS_SWITCH in arg_map:
            self._update_rcu_schema_pass = True

        if CommandLineArgUtil.VALIDATION_METHOD in arg_map:
            self._validation_method = arg_map[
                CommandLineArgUtil.VALIDATION_METHOD]

        if CommandLineArgUtil.TARGET_VERSION_SWITCH in arg_map:
            self._wl_version = arg_map[
                CommandLineArgUtil.TARGET_VERSION_SWITCH]

        if CommandLineArgUtil.DOMAIN_RESOURCE_FILE_SWITCH in arg_map:
            self._domain_resource_file = arg_map[
                CommandLineArgUtil.DOMAIN_RESOURCE_FILE_SWITCH]

        if CommandLineArgUtil.TRAILING_ARGS_SWITCH in arg_map:
            self._trailing_args = arg_map[
                CommandLineArgUtil.TRAILING_ARGS_SWITCH]

        if CommandLineArgUtil.TARGET_MODE_SWITCH in arg_map:
            wlst_mode_string = arg_map[CommandLineArgUtil.TARGET_MODE_SWITCH]
            if wlst_mode_string.lower() == 'online':
                self._wlst_mode = WlstModes.ONLINE
            else:
                self._wlst_mode = WlstModes.OFFLINE

        if CommandLineArgUtil.COMPARE_MODEL_OUTPUT_DIR_SWITCH in arg_map:
            self._compare_model_output_dir = arg_map[
                CommandLineArgUtil.COMPARE_MODEL_OUTPUT_DIR_SWITCH]

        if self._wl_version is None:
            self._wl_version = self._wls_helper.get_actual_weblogic_version()

        if self._wlst_mode is None:
            self._wlst_mode = WlstModes.OFFLINE

        return
class MBeanInfoAttributes(MBeanAttributes):
    """
    MBeanInfoAttributes extends the MBeanAttributes class. It encapsulates the attribute information found from the
    PropertyDescriptors in the MBeanInfo for the MBean type.
    """

    __class_name = 'MBeanInfoAttributes'

    def __init__(self, model_context, aliases, exception_type, location):
        MBeanAttributes.__init__(self, model_context, aliases, exception_type,
                                 location)

        self.__weblogic_helper = WebLogicHelper(_logger)
        self.__mbean_info_descriptors = None
        self.__mbean_info_map = None

    def get_mbean_attributes(self):
        """
        Return the sorted list of attributes compiled from the MBeanInfo PropertyDescriptors including the
        child MBeans.
        :return: list of all attributes from the MBeanInfo property descriptors, or an empty list if none
        """
        _method_name = 'get_mbean_attributes'
        _logger.entering(class_name=self.__class__.__name__,
                         method_name=_method_name)
        map_to_list = list()
        attributes = self.__get_mbean_info_map()
        if len(attributes) > 0:
            map_to_list = [attribute for attribute in attributes.iterkeys()]
            map_to_list.sort()
        _logger.exiting(class_name=self.__class__.__name__,
                        method_name=_method_name,
                        result=len(map_to_list))
        return map_to_list

    def exists(self, attribute_name):
        """
        Determine if the attribute name exists for the MBean in MBeanInfo.
        :param attribute_name: to search for in the MBeanInfo
        :return: True if the attribute is found in the MBeanInfo
        """
        return attribute_name in self.__get_mbean_info_map()

    def is_child_mbean(self, attribute_name):
        """
        Determine if the attribute exists in MBeanInfo and if the attribute is a child MBean.

        :param attribute_name: to search for in the MBeanInfo
        :return: True if the attribute is a child MBean or None if the attribute is not found in MBeanInfo
        """
        _method_name = 'is_child_mbean'
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            relationship = descriptor.getValue('relationship')
            is_child = relationship == 'containment' or \
                (relationship == 'reference' and self.is_read_only(attribute_name))
            if is_child:
                _logger.finer('WLSDPLY-01780',
                              attribute_name,
                              class_name=self.__class__.__name__,
                              method_name=_method_name)
            return is_child
        return None

    def is_read_only(self, attribute_name):
        """
        Determine if the attribute exists in MBeanInfo and if the attribute is readonly.
        :param attribute_name: to search for in the MBeanInfo
        :return: True if the attribute is readonly or None if the attribute does not exist in MBeanInfo
        """
        if self.exists(attribute_name):
            return self.setter(attribute_name) is None
        return None

    def getter(self, attribute_name):
        """
        Return the read method name string for the attribute in the MBeanInfo.
        :param attribute_name: to search for in the MBeanInfo
        :return: getter for the attribute or None if the attribute does not exist
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            return descriptor.getReadMethod().getName()
        return None

    def is_valid_getter(self, attribute_name):
        """
        Try to invoke the getter method on the mbean_instance. Some of the attributes in the PropertyDescriptors
        have read methods that cannot be invoked on the MBean instance.
        :return: True if can invoke the getter on the MBean instance
        """
        _method_name = 'is_valid_getter'
        _logger.entering(attribute_name,
                         class_name=self.__class__.__name__,
                         method_name=_method_name)

        valid = False
        getter = self.getter(attribute_name)
        if getter is not None:
            valid, __ = self._get_from_bean_proxy(getter)
        _logger.exiting(class_name=self.__class__.__name__,
                        method_name=_method_name,
                        result=Boolean(valid))
        return valid

    def setter(self, attribute_name):
        """
        Return the set method name for the attribute in the MBeanInfo.
        :param attribute_name: to search for in the MBeanInfo
        :return: setter for the attribute or None if the attribute is readonly or the attribute does not exist
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            setter = descriptor.getWriteMethod()
            if setter is not None and str(setter.getReturnType()) == 'void':
                return setter.getName()
        return None

    def is_encrypted(self, attribute_name):
        """
        Determine if the property is an encrypted attribute.
        :param attribute_name: to search for in the MBeanInfo
        :return: True if it is an encrypted attribute or None if the attribute does not exist in the MBeanInfo
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            return descriptor.getValue('encrypted') is True
        return None

    def is_clear_text_encrypted(self, attribute_name):
        """
        The tool does not discover security attributes that are clear text. Determine if the attribute is a
        an attribute returning clear text form of the matching encrypted attribute and skip if True.
        :param attribute_name: name of the attribute to test
        :return: True if the attribute is a clear text security attribute
        """
        return self.is_encrypted(attribute_name) and str(
            self.get_type(attribute_name)) == 'java.lang.String'

    def get_type(self, attribute_name):
        """
        Return the type of the attribute value if the attribute exists in MBeanInfo.
        :param attribute_name: to search for in the MBeanInfo
        :return: Type of the property attribute or None if the attribute does not exist in the MBeanInfo
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        if descriptor is not None:
            return descriptor.getPropertyType()
        return None

    def get_default_value(self, attribute_name):
        """
        Return the default value if the attribute exists in MBeanInfo
        :param attribute_name: to search for in the MBeanInfo
        :return: The default value for the attribute
        """
        descriptor = self.__get_mbean_attribute(attribute_name)
        values = _get_descriptor_values_keys(descriptor)
        if 'defaultValueNull' in values and descriptor.getValue(
                'defaultValueNull') is True:
            default = None
        else:
            default = descriptor.getValue('default')
        return default

    def get_value(self, attribute_name):
        """
        Return the attribute value from the mbean instance.
        :param attribute_name: name of the attribute
        :return: Value of the MBean attribute in the format retrieved from the mbean instance
        """
        value = None
        getter = self.getter(attribute_name)
        if getter is not None:
            __, value = self._get_from_bean_proxy(getter)
        return value

    def __get_mbean_info_map(self):
        if self.__mbean_info_map is None:
            self.__mbean_info_map = dict()
            for descriptor in self.__get_mbean_descriptors():
                self.__mbean_info_map[descriptor.getName()] = descriptor

        return self.__mbean_info_map

    def __get_mbean_descriptors(self):
        _method_name = '__get_mbean_descriptors'
        if self.__mbean_info_descriptors is None:
            mbean_info = self.__weblogic_helper.get_bean_info_for_interface(
                self.get_mbean_interface_name())
            if mbean_info is None:
                ex = exception_helper.create_exception(
                    self._get_exception_type(), 'WLSDPLY-01774',
                    self.get_mbean_interface_name(), self.mbean_string())
                _logger.throwing(ex,
                                 class_name=self.__class__.__name__,
                                 method_name=_method_name)
                raise ex
            self.__mbean_info_descriptors = mbean_info.getPropertyDescriptors()
        return self.__mbean_info_descriptors

    def __get_mbean_attribute(self, attribute):
        descriptor_map = self.__get_mbean_info_map()
        if attribute in descriptor_map:
            return descriptor_map[attribute]
        return None

    def __str__(self):
        return self.__class__.__name__ + self._get_mbean_name()
Example #11
0
class TargetHelper(object):
    """
    Shared code for targeting clusters and servers. Domain create and update use this code.
    """
    __class_name = 'TargetHelper'

    def __init__(self, model, model_context, aliases, exception_type, logger):
        self.logger = logger
        self.model = model
        self.model_context = model_context
        self.alias_helper = AliasHelper(aliases, self.logger, exception_type)
        self.wlst_helper = WlstHelper(exception_type)
        self.wls_helper = WebLogicHelper(self.logger)
        self.exception_type = exception_type
        self.domain_typedef = self.model_context.get_domain_typedef()
        topology = model.get_model_topology()
        if ADMIN_SERVER_NAME in topology:
            self._admin_server_name = topology[ADMIN_SERVER_NAME]
        else:
            self._admin_server_name = DEFAULT_ADMIN_SERVER_NAME

    def target_jrf_groups_to_clusters_servers(self):
        """
        Call applyJRF to for those versions of wlst that cannot target servers to server groups.
        This assigns the JRF resources to all managed servers. If the managed server is in a
        cluster, this method assigns the JRF resources are assigned to the cluster. Else, if
        the managed server is stand-alone, the resources are assigned to the managed server.
        to automatically update the domain.
        """
        _method_name = 'target_jrf_groups_to_clusters_servers'
        self.logger.entering(class_name=self.__class_name, method_name=_method_name)

        location = LocationContext()
        root_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(root_path)
        admin_server_name = self.wlst_helper.get(ADMIN_SERVER_NAME)

        # We need to get the effective list of servers for the domain.  Since any servers
        # referenced in the model have already been created but the templates may have
        # defined new servers not listed in the model, get the list from WLST.
        server_names = self.get_existing_server_names()
        if admin_server_name in server_names:
            server_names.remove(admin_server_name)

        # Get the clusters and and their members
        cluster_map = self._get_clusters_and_members_map()

        # Get the clusters and and their members
        for cluster_name, cluster_servers in cluster_map.iteritems():
            self.logger.info('WLSDPLY-12233', 'Cluster', cluster_name, class_name=self.__class_name,
                             method_name=_method_name)
            self.wlst_helper.apply_jrf(cluster_name, self.model_context)
            for member in cluster_servers:
                if member in server_names:
                    server_names.remove(member)
        for ms_name in server_names:
            self.logger.info('WLSDPLY-12233', 'Managed Server', ms_name, class_name=self.__class_name,
                             method_name=_method_name)
            self.wlst_helper.apply_jrf(ms_name, self.model_context)

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    def target_server_groups_to_servers(self, server_groups_to_target):
        """
        Target the server groups to the servers.
        :param server_groups_to_target: the list of server groups to target
        :raises: BundleAwareException of the specified type: if an error occurs
        """
        _method_name = 'target_server_groups_to_servers'

        self.logger.entering(server_groups_to_target, class_name=self.__class_name, method_name=_method_name)
        if len(server_groups_to_target) == 0:
            return list()

        location = LocationContext()
        root_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(root_path)

        # We need to get the effective list of servers for the domain.  Since any servers
        # referenced in the model have already been created but the templates may have
        # defined new servers not listed in the model, get the list from WLST.
        server_names = self._get_existing_server_names()
        # Get the clusters and and their members
        cluster_map = self._get_clusters_and_members_map()
        # Get any limits that may have been defined in the model
        domain_info = self.model.get_model_domain_info()
        server_group_targeting_limits = \
            dictionary_utils.get_dictionary_element(domain_info, SERVER_GROUP_TARGETING_LIMITS)
        if len(server_group_targeting_limits) > 0:
            server_group_targeting_limits = \
                self._get_server_group_targeting_limits(server_group_targeting_limits, cluster_map)

        self.logger.finer('WLSDPLY-12240', str(server_group_targeting_limits),
                          class_name=self.__class_name, method_name=_method_name)

        # Get the map of server names to server groups to target
        server_to_server_groups_map =\
            self._get_server_to_server_groups_map(self._admin_server_name,
                                                  server_names,
                                                  server_groups_to_target,
                                                  server_group_targeting_limits)  # type: dict
        self.logger.finer('WLSDPLY-12242', str(server_to_server_groups_map), class_name=self.__class_name,
                          method_name=_method_name)

        final_assignment_map = dict()
        # Target servers and dynamic clusters to the server group resources
        if len(server_names) > 0:
            for server, server_groups in server_to_server_groups_map.iteritems():
                if len(server_groups) > 0:
                    if server in server_names:
                        final_assignment_map[server] = server_groups

        #
        # Domain has not targeted the server groups to managed servers (configured), or the
        # domain has no managed servers (configured) but has user server groups. The resources for the
        # user server groups must be targeted before the write/update domain or the write/update will fail.
        # Thus assign the user server groups to the admin server.
        #
        # Because of the interaction of the working context in the different wlst helpers, the dynamic
        # clusters will be applied to the resources separately and after the write/update domain.
        #
        # (From original blurb)
        #  This is really a best effort attempt.  It works for JRF domains but it is certainly possible
        # that it may cause problems with other custom domain types.  Of course, creating a domain with
        # no managed servers is not a primary use case of this tool so do it and hope for the best...
        #
        # (New comment)
        # As we have added the intricacies of the dynamic clusters, if the targeting is to dynamic
        # clusters only, the set server groups with the admin server will get through the write/update domain
        # and the applyJRF with the dynamic cluster should theoretically unset the AdminServer on the user server
        # groups. It works with JRF type domains.

        if len(server_groups_to_target) > 0:
            if len(final_assignment_map) == 0:
                # This is a quickie to fix the issue where server groups are not targeted because no configured
                #  managed servers exist in the domain
                final_assignment_map[server_names[0]] = server_groups_to_target
            else:
                # If a server group or groups is not targeted in the assignments, log it to stdout
                no_targets = [server_target for server_target in server_groups_to_target if server_target not in
                              [server_target for row in final_assignment_map.itervalues() for
                               server_target in server_groups_to_target if server_target in row]]
                if len(no_targets) > 0:
                    self.logger.info('WLSDPLY-12248', no_targets,
                                     class_name=self.__class_name, method_name=_method_name)

        self.logger.exiting(result=str(final_assignment_map), class_name=self.__class_name, method_name=_method_name)
        return final_assignment_map

    def target_server_groups_to_dynamic_clusters(self, server_groups_to_target):
        """
        Target dynamic clusters to dynamic cluster server groups. Dynamic cluster server groups are not user
        expandable. Thus if a dynamic server group is not targeted to a dynamic cluster, don't target to admin
        server. The dynamic cluster server groups are not required to be targeted.
        :param server_groups_to_target: the list of dynamic cluster server groups to target
        :raises: BundleAwareException of the specified type: if an error occurs
        """
        _method_name = 'target_server_groups_to_dynamic_clusters'

        self.logger.entering(server_groups_to_target, class_name=self.__class_name, method_name=_method_name)
        if len(server_groups_to_target) == 0:
            return list()

        location = LocationContext()
        root_path = self.alias_helper.get_wlst_attributes_path(location)
        self.wlst_helper.cd(root_path)

        # Get the clusters and and their members
        cluster_map = self._get_clusters_and_members_map()
        dynamic_cluster_names = list()
        for cluster_name in cluster_map:
            if DYNAMIC_SERVERS in cluster_map[cluster_name]:
                dynamic_cluster_names.append(cluster_name)

        domain_info = self.model.get_model_domain_info()
        dc_server_group_targeting_limits = \
            dictionary_utils.get_dictionary_element(domain_info, DYNAMIC_CLUSTER_SERVER_GROUP_TARGETING_LIMITS)
        if len(dc_server_group_targeting_limits) > 0:
            dc_server_group_targeting_limits = \
                self._get_dynamic_cluster_server_group_targeting_limits(dc_server_group_targeting_limits, cluster_map)
        dynamic_cluster_assigns = \
            self.get_dc_to_server_groups_map(dynamic_cluster_names, server_groups_to_target,
                                             dc_server_group_targeting_limits)  # type: dict
        self.logger.finer('WLSDPLY-12240', str(dc_server_group_targeting_limits),
                          class_name=self.__class_name, method_name=_method_name)

        self.logger.exiting(result=str(dynamic_cluster_assigns), class_name=self.__class_name, method_name=_method_name)
        return dynamic_cluster_assigns

    def target_server_groups(self, server_assigns):
        """
        Perform the targeting of the server groups to server from the list of assignments made in the
        target helper assignment step. This is separate from creating the list of assignments in order
        to control the state of the domain when the target is done.
        :param server_assigns: map of server to server group
        """
        _method_name = 'target_server_groups'
        self.logger.entering(str(server_assigns), class_name=self.__class_name, method_name=_method_name)

        for server, server_groups in server_assigns.iteritems():
            server_name = self.wlst_helper.get_quoted_name_for_wlst(server)
            self.logger.info('WLSDPLY-12224', str(server_groups), server_name,
                             class_name=self.__class_name, method_name=_method_name)
            self.wlst_helper.set_server_groups(server_name, server_groups)

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)

    def target_dynamic_server_groups(self, dynamic_cluster_assigns):
        """
        Dynamic clusters need special handling to assign the server group resources to the dynamic cluster.
        You cannot assign servergroups to a server template. So must search each templates that contain the server group
        for resources and specifically add the dynamic target to the resource target.
        If JRF or RestrictedJRF skip the check and do the applyJRF function to automatically target to the cluster.
        :param dynamic_cluster_assigns: The assignments from domainInfo targeting limits applied to dynamic lusters
        """
        _method_name = 'target_dynamic_server_groups'
        self.logger.entering(str(dynamic_cluster_assigns), class_name=self.__class_name, method_name=_method_name)

        domain_typedef = self.model_context.get_domain_typedef()

        if len(dynamic_cluster_assigns) > 0:
            # assign server group resources to cluster based on the version of WebLogic server version.
            if self.wls_helper.is_dynamic_cluster_server_groups_supported():
                self.target_server_groups(dynamic_cluster_assigns)
            elif self.wls_helper.is_dynamic_cluster_server_group_supported():
                self.target_dynamic_clusters(dynamic_cluster_assigns)
            else:
                self.logger.warning('WLSDPLY-12238', domain_typedef.get_domain_type(),
                                    class_name=self.__class_name, method_name=_method_name)

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)
        return

    def target_dynamic_clusters(self, server_assigns):
        """
        Perform the targeting of a server group to the clusters from the list of assignments made in the
        target helper assignment step. This is separate from creating the list of assignments in order
        to control the state of the domain when the target is done. The version of WebLogic Server
        supports targeting a single server group to a dynamic cluster.
        :param server_assigns: map of server to server group
        """
        _method_name = 'target_dynamic_clusters'
        self.logger.entering(str(server_assigns), class_name=self.__class_name, method_name=_method_name)

        for cluster, server_groups in server_assigns.iteritems():
            cluster_name = self.wlst_helper.get_quoted_name_for_wlst(cluster)
            if len(server_groups) > 1:
                ex = exception_helper.create_exception(self.exception_type, 'WLSDPLY-12256',
                                                       cluster, server_groups)
                self.logger.throwing(ex, class_name=self.__class_name, method_name=_method_name)
                raise ex 
            elif len(server_groups) > 0:
                self.logger.info('WLSDPLY-12255', server_groups[0], cluster_name,
                                 class_name=self.__class_name, method_name=_method_name)
                self.wlst_helper.set_server_group_dynamic_cluster(cluster_name, server_groups[0])

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name)

    def _target_jrf_resources(self, dynamic_cluster_assigns):
        # Target the JRF resources directly using the applyJRF method.
        _method_name = '_target_jrf_resources'
        names_only = list()
        for name in dynamic_cluster_assigns:
            names_only.append(name)
        if self.model_context.is_wlst_online() and \
                self.model_context.get_domain_typedef().is_restricted_jrf_domain_type():
            self.logger.warning('WLSDPLY-12244', str(names_only), class_name=self.__class_name,
                                _method_name=_method_name)
        else:
            self.logger.info('WLSDPLY-12236', str(names_only),
                             class_name=self.__class_name, method_name=_method_name)
            self.wlst_helper.apply_jrf_with_context(names_only, self.model_context)

    def _get_existing_server_names(self):
        """
        Get the list of server names from WLST.
        :return: the list of server names
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = '_get_existing_server_names'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        server_location = LocationContext().append_location(SERVER)
        server_list_path = self.alias_helper.get_wlst_list_path(server_location)
        result = self.wlst_helper.get_existing_object_list(server_list_path)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def _get_clusters_and_members_map(self):
        """
        Get a map keyed by cluster name with values that are a list of member server names
        :return: the cluster name to member server names map
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = '_get_clusters_and_members_map'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        server_location = LocationContext().append_location(SERVER)
        server_list_path = self.alias_helper.get_wlst_list_path(server_location)
        server_names = self.wlst_helper.get_existing_object_list(server_list_path)
        server_token = self.alias_helper.get_name_token(server_location)
        cluster_map = OrderedDict()
        for server_name in server_names:
            server_location.add_name_token(server_token, server_name)
            server_attributes_path = self.alias_helper.get_wlst_attributes_path(server_location)
            self.wlst_helper.cd(server_attributes_path)

            server_attributes_map = self.wlst_helper.lsa()
            cluster_name = dictionary_utils.get_element(server_attributes_map, CLUSTER)
            if string_utils.is_empty(cluster_name):
                # if server is not part of a cluster, continue with the next server
                continue

            if cluster_name not in cluster_map:
                cluster_map[cluster_name] = list()
            cluster_map[cluster_name].append(server_name)

        clusters_location = LocationContext().append_location(CLUSTER)
        cluster_list_path = self.alias_helper.get_wlst_list_path(clusters_location)
        cluster_names = self.wlst_helper.get_existing_object_list(cluster_list_path)
        cluster_token = self.alias_helper.get_name_token(clusters_location)
        # Add the cluster with dynamic servers, if not already in the cluster member list.
        # A cluster may contain both dynamic and configured servers (referred to as mixed cluster).
        # Add a token marking DYNAMIC SERVERS in the member list.
        for cluster_name in cluster_names:
            cluster_location = LocationContext(clusters_location)
            cluster_location.add_name_token(cluster_token, cluster_name)
            cluster_attributes_path = self.alias_helper.get_wlst_attributes_path(cluster_location)
            self.wlst_helper.cd(cluster_attributes_path)
            cluster_location.append_location(DYNAMIC_SERVERS)
            wlst_subfolder_name = self.alias_helper.get_wlst_mbean_type(cluster_location)
            if self.wlst_helper.subfolder_exists(wlst_subfolder_name):
                if cluster_name not in cluster_map:
                    cluster_map[cluster_name] = list()
                cluster_map[cluster_name].append(DYNAMIC_SERVERS)

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=cluster_map)
        return cluster_map

    def get_existing_server_names(self):
        """
        Get the list of server names from WLST.
        :return: the list of server names
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = '_get_existing_server_names'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        server_location = LocationContext().append_location(SERVER)
        server_list_path = self.alias_helper.get_wlst_list_path(server_location)
        result = self.wlst_helper.get_existing_object_list(server_list_path)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def get_existing_cluster_names(self):
        """
        Get the list of cluster names from WLST.
        :return: the list of cluster names
        :raises: BundleAwareException of the specified type: is an error occurs reading from the aliases or WLST
        """
        _method_name = 'get_existing_cluster_names'

        self.logger.entering(class_name=self.__class_name, method_name=_method_name)
        cluster_location = LocationContext().append_location(CLUSTER)
        cluster_list_path = self.alias_helper.get_wlst_list_path(cluster_location)
        result = self.wlst_helper.get_existing_object_list(cluster_list_path)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def _get_server_group_targeting_limits(self, server_group_targeting_limits, clusters_map):
        """
        Get any server group targeting limits specified in the model, converting any cluster
        names to the list of members.  This method assumes that the limits dictionary is not
        None or empty.
        :param server_group_targeting_limits: the raw server group targeting_limits from the model
        :param clusters_map: the map of cluster names to member server names
        :return: the map of server groups to server names to target
        """
        _method_name = '_get_server_group_targeting_limits'

        self.logger.entering(str(server_group_targeting_limits), str(clusters_map),
                             class_name=self.__class_name, method_name=_method_name)
        sg_targeting_limits = copy.deepcopy(server_group_targeting_limits)
        for server_group_name, sg_targeting_limit in sg_targeting_limits.iteritems():
            if type(sg_targeting_limit) is str:
                if MODEL_LIST_DELIMITER in sg_targeting_limit:
                    sg_targeting_limit = sg_targeting_limit.split(MODEL_LIST_DELIMITER)
                else:
                    # convert a single value into a list of one...
                    new_list = list()
                    new_list.append(sg_targeting_limit)
                    sg_targeting_limit = new_list

            # Convert any references to a cluster name into the list of member server names
            new_list = list()
            for target_name in sg_targeting_limit:
                target_name = target_name.strip()
                if target_name in clusters_map:
                    cluster_members = dictionary_utils.get_element(clusters_map, target_name)
                    if DYNAMIC_SERVERS in cluster_members:
                        # This will need special handling to target server group resources
                        cluster_members.remove(DYNAMIC_SERVERS)
                    new_list.extend(cluster_members)
                else:
                    # Assume it is a server name and add it to the new list
                    # Stand-alone Managed Servers were not added to the cluster: server_name_list map
                    # which was built from the existing servers and clusters.
                    new_list.append(target_name)
            sg_targeting_limits[server_group_name] = new_list

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=sg_targeting_limits)
        return sg_targeting_limits

    def _get_dynamic_cluster_server_group_targeting_limits(self, targeting_limits, clusters_map):
        """
        Get any server group targeting limits specified in the model, converting any cluster
        names to the list of members.  This method assumes that the limits dictionary is not
        None or empty.
        :param targeting_limits: the raw server group targeting_limits from the model
        :param clusters_map: the map of cluster names to member server names
        :return: the map of server groups to server names to target
        """
        _method_name = '_get_dynamic_cluster_server_group_targeting_limits'

        self.logger.entering(str(targeting_limits), str(clusters_map),
                             class_name=self.__class_name, method_name=_method_name)
        dc_sg_targeting_limits = copy.deepcopy(targeting_limits)
        for server_group_name, dc_sg_targeting_limit in dc_sg_targeting_limits.iteritems():
            if type(dc_sg_targeting_limit) is str:
                if MODEL_LIST_DELIMITER in dc_sg_targeting_limit:
                    dc_sg_targeting_limit = dc_sg_targeting_limit.split(MODEL_LIST_DELIMITER)
                else:
                    # convert a single value into a list of one...
                    new_list = list()
                    new_list.append(dc_sg_targeting_limit)
                    dc_sg_targeting_limit = new_list

            # Convert any references to a cluster name into the list of member server names
            new_list = list()
            for target_name in dc_sg_targeting_limit:
                target_name = target_name.strip()
                if target_name in clusters_map:
                    cluster_members = dictionary_utils.get_element(clusters_map, target_name)
                    if DYNAMIC_SERVERS in cluster_members:
                        # This will need special handling to target server group resources
                        cluster_members.remove(DYNAMIC_SERVERS)
                        cluster_members.append(target_name)
                        new_list.extend(cluster_members)
            dc_sg_targeting_limits[server_group_name] = new_list

        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=dc_sg_targeting_limits)
        return dc_sg_targeting_limits

    def _get_server_to_server_groups_map(self, admin_server_name, server_names, server_groups, sg_targeting_limits):
        """
        Get the map of server names to the list of server groups to target to that server.
        :param admin_server_name: the admin server name
        :param server_names: the list of server names
        :param server_groups: the complete list of server groups that will, by default, be targeted to
                              all managed servers unless the server is listed in the targeting limits map
        :param sg_targeting_limits: the targeting limits map
        :return: the map of server names to the list of server groups to target to that server
        """
        _method_name = '_get_server_to_server_groups_map'

        self.logger.entering(admin_server_name, str(server_names), str(server_groups), str(sg_targeting_limits),
                             class_name=self.__class_name, method_name=_method_name)
        result = OrderedDict()
        revised_server_groups = self._revised_list_server_groups(server_groups, sg_targeting_limits)
        for server_name in server_names:
            server_groups_for_server = self.__get_server_groups_for_entity(server_name, sg_targeting_limits)
            if len(server_groups_for_server) > 0:
                result[server_name] = server_groups_for_server
            elif server_name != admin_server_name:
                # By default, we only target managed servers unless explicitly listed in the targeting limits
                result[server_name] = list(revised_server_groups)
            else:
                result[admin_server_name] = list()

        if admin_server_name not in result:
            result[admin_server_name] = list()
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def get_dc_to_server_groups_map(self, dynamic_cluster_names, server_groups, dc_sg_targeting_limits):
        """
        Remake the map for each dynamic cluster name and its server groups. If the dynamic cluster is not
        specifically targeted by the dynamic cluster server group targeting limits, targt any remaining
        server groups not in the targeting limits, to any remaining typedef dynamic cluster server group targets.
        :param dynamic_cluster_names: list of dynamic clusters in the domain
        :param server_groups: list of dynamic server groups in the typedef
        :param dc_sg_targeting_limits: list of dynamic cluster to server group targeting limits from the domainInfo
        :return: result: map of dynamic cluster to server groups
        """
        _method_name = 'get_dc_to_server_groups_list'

        self.logger.entering(str(dynamic_cluster_names), str(server_groups), str(dc_sg_targeting_limits),
                                 class_name=self.__class_name, method_name=_method_name)
        result = OrderedDict()
        revised_server_groups = self._revised_list_server_groups(server_groups, dc_sg_targeting_limits)
        for cluster_name in dynamic_cluster_names:
            server_groups_for_cluster = \
                self.__get_server_groups_for_entity(cluster_name, dc_sg_targeting_limits)
            if len(server_groups_for_cluster) > 0:
                result[cluster_name] = server_groups_for_cluster
            else:
                result[cluster_name] = list(revised_server_groups)
            self.logger.finer('WLSDPLY-12239', result[cluster_name], cluster_name,
                              class_name=self.__class_name, method_name=_method_name)
        self.logger.exiting(class_name=self.__class_name, method_name=_method_name, result=result)
        return result

    def _revised_list_server_groups(self, server_groups, sg_targeting_limits):
        """
        Remove all server groups that are explicitly targeted to a cluster, server set or stand-alone
        managed server.
        :param server_groups: list of server groups applied by the extension templates
        :param sg_targeting_limits: list of targeting from the domainInfo section
        :return: server group list with the specific targeted server groups removed
        """
        _method_name = '_revised_list_server_groups'
        self.logger.entering(sg_targeting_limits, class_name=self.__class_name, method_name=_method_name)
        result = list()
        targeted_server_groups = sg_targeting_limits.keys()
        for server_group in server_groups:
            if server_group not in targeted_server_groups:
                result.append(server_group)
        return result

    def __get_server_groups_for_entity(self, entity_name, sg_targeting_limits):
        """
        Get the servers groups to target for a given server or dynamic cluster name.
        :param entity_name: the server or dynamic_cluster name
        :param sg_targeting_limits: the targeting limits
        :return: the list of server groups to target to the specified entity name, or None
                 if the entity name does not appear in the targeting limits
        """
        _method_name = '__get_server_groups_for_entity'
        result = list()
        for server_group, entity_names_list in sg_targeting_limits.iteritems():
            if entity_name in entity_names_list:
                result.append(server_group)
        if len(result) > 0:
            self.logger.fine('WLSDPLY-12243', entity_name, result, class_name=self.__class_name,
                             method_name=_method_name)
        return result
class Discoverer(object):
    """
    Discoverer contains the private methods used to facilitate discovery of the domain information by its subclasses.
    """

    def __init__(self, model_context, base_location, wlst_mode, aliases=None, credential_injector=None):
        """
        :param model_context: context about the model for this instance of discover domain
        :param base_location: to look for common weblogic resources. By default this is the global path or '/'
        :param wlst_mode: offline or online
        :param aliases: optional, aliases object to use
        :param credential_injector: optional, injector to collect credentials
        """
        self._model_context = model_context
        self._base_location = base_location
        self._wlst_mode = wlst_mode
        if aliases:
            self._aliases = aliases
        else:
            self._aliases = Aliases(self._model_context, wlst_mode=self._wlst_mode,
                                    exception_type=ExceptionType.DISCOVER)
        self._credential_injector = credential_injector
        self._att_handler_map = OrderedDict()
        self._custom_folder = CustomFolderHelper(self._aliases, _logger, self._model_context, ExceptionType.DISCOVER,
                                                 self._credential_injector)
        self._weblogic_helper = WebLogicHelper(_logger)
        self._wlst_helper = WlstHelper(ExceptionType.DISCOVER)
        self._mbean_utils = MBeanUtils(self._model_context, self._aliases, ExceptionType.DISCOVER)
        self._wls_version = self._weblogic_helper.get_actual_weblogic_version()

    def discover_domain_mbean(self, model_top_folder_name):
        """
        Discover the domain specific MBean and its configuration attributes.
        :return: model name for domain MBean:dictionary containing the discovered Domain MBean attributes
        """
        _method_name = 'discover_domain_mbean'
        _logger.entering(model_top_folder_name, class_name=_class_name, method_name=_method_name)
        result = OrderedDict()
        location = LocationContext(self._base_location)
        location.append_location(model_top_folder_name)
        name = self._find_singleton_name_in_folder(location)
        if name is not None:
            _logger.info('WLSDPLY-06644', model_top_folder_name, class_name=_class_name, method_name=_method_name)
            location.add_name_token(self._aliases.get_name_token(location), name)
            self._populate_model_parameters(result, location)
            # if any subfolders exist, discover
            self._discover_subfolders(result, location)
        _logger.exiting(class_name=_class_name, method_name=_method_name)
        return model_top_folder_name, result

    # methods for use only by the subclasses
    def _populate_model_parameters(self, dictionary, location):
        """
        Populate the model dictionary with the attribute values discovered at the current location. Perform
        any special processing for a specific attribute before storing into the model dictionary.
        :param dictionary: where to store the discovered attributes
        :param location: context containing current location information
        :return: dictionary of model attribute name and wlst value
        """
        _method_name = '_populate_model_parameters'
        wlst_path = self._aliases.get_wlst_attributes_path(location)
        _logger.finer('WLSDPLY-06100', wlst_path, class_name=_class_name, method_name=_method_name)

        if not self.wlst_cd(wlst_path, location):
            return

        wlst_lsa_params = self._get_attributes_for_current_location(location)
        _logger.finest('WLSDPLY-06102', self._wlst_helper.get_pwd(), wlst_lsa_params, class_name=_class_name,
                       method_name=_method_name)
        wlst_get_params = self._get_required_attributes(location)
        _logger.finest('WLSDPLY-06103', str(location), wlst_get_params,
                       class_name=_class_name, method_name=_method_name)
        if wlst_lsa_params is not None:
            for wlst_lsa_param in wlst_lsa_params:
                if wlst_lsa_param in wlst_get_params:
                    success, wlst_value = self._get_attribute_value_with_get(wlst_lsa_param, wlst_path)
                    if not success:
                        continue
                else:
                    _logger.finer('WLSDPLY-06131', wlst_lsa_param, class_name=_class_name, method_name=_method_name)
                    wlst_value = wlst_lsa_params[wlst_lsa_param]

                # if attribute was never set (online only), don't add to the model
                if not self._wlst_helper.is_set(wlst_lsa_param):
                    _logger.finest('WLSDPLY-06157', wlst_lsa_param, str(location), class_name=_class_name,
                                   method_name=_method_name)
                    continue

                self._add_to_dictionary(dictionary, location, wlst_lsa_param, wlst_value, wlst_path)

        # These will come after the lsa / get params in the ordered dictionary
        wlst_extra_params = self._get_additional_parameters(location)
        _logger.finest('WLSDPLY-06149', str(location), wlst_extra_params,
                       class_name=_class_name, method_name=_method_name)
        if wlst_extra_params is not None:
            for wlst_extra_param in wlst_extra_params:
                if wlst_extra_param in wlst_get_params:
                    success, wlst_value = self._get_attribute_value_with_get(wlst_extra_param, wlst_path)
                    if success:
                        self._add_to_dictionary(dictionary, location, wlst_extra_param, wlst_value, wlst_path)
                    else:
                        _logger.info('WLSDPLY-06152', wlst_extra_param, location.get_folder_path(),
                                     class_name=_class_name, method_name=_method_name)
                elif self._is_defined_attribute(location, wlst_extra_param):
                    _logger.info('WLSDPLY-06154', wlst_extra_param, location.get_folder_path(),
                                 class_name=_class_name, method_name=_method_name)
                else:
                    _logger.info('WLSDPLY-06153', wlst_extra_param, location.get_folder_path(),
                                 class_name=_class_name, method_name=_method_name)

    def _get_attribute_value_with_get(self, wlst_get_param, wlst_path):
        _method_name = '_get_attribute_value_with_get'
        _logger.finest('WLSDPLY-06104', wlst_get_param, class_name=_class_name, method_name=_method_name)
        success = False
        wlst_value = None
        try:
            wlst_value = self._wlst_helper.get(wlst_get_param)
            success = True
        except DiscoverException, pe:
            _logger.warning('WLSDPLY-06127', wlst_get_param, wlst_path, pe.getLocalizedMessage(),
                            class_name=_class_name, method_name=_method_name)
        return success, wlst_value
def __check_and_customize_model(model, model_context, aliases,
                                credential_injector):
    """
    Customize the model dictionary before persisting. Validate the model after customization for informational
    purposes. Any validation errors will not stop the discovered model to be persisted.
    :param model: completely discovered model, before any tokenization
    :param model_context: configuration from command-line
    :param aliases: used for validation if model changes are made
    :param credential_injector: injector created to collect and tokenize credentials, possibly None
    """
    _method_name = '__check_and_customize_model'
    __logger.entering(class_name=_class_name, method_name=_method_name)

    if filter_helper.apply_filters(model.get_model(), "discover",
                                   model_context):
        __logger.info('WLSDPLY-06014',
                      _class_name=_class_name,
                      method_name=_method_name)

    # target config always present in model context, default config if not declared
    target_configuration = model_context.get_target_configuration()

    # if target config declared, use the validation method it contains (lax, etc.)
    if model_context.is_targetted_config():
        validation_method = target_configuration.get_validation_method()
        model_context.set_validation_method(validation_method)

    credential_cache = None
    if credential_injector is not None:
        credential_cache = credential_injector.get_variable_cache()

        # Generate k8s create secret script
        if target_configuration.uses_credential_secrets():
            target_configuration_helper.generate_k8s_script(
                model_context, credential_cache, model.get_model())

        # if target handles credential configuration, clear property cache to keep out of variables file.
        if model_context.get_target_configuration().manages_credentials():
            credential_cache.clear()

    # Apply the injectors specified in model_variable_injector.json, or in the target configuration.
    # Include the variable mappings that were collected in credential_cache.
    variable_injector = VariableInjector(
        _program_name, model.get_model(), model_context,
        WebLogicHelper(__logger).get_actual_weblogic_version(),
        credential_cache)

    inserted, variable_model, variable_file_name = variable_injector.inject_variables_keyword_file(
    )

    if inserted:
        model = Model(variable_model)
    try:
        validator = Validator(model_context,
                              wlst_mode=__wlst_mode,
                              aliases=aliases)

        # no variables are generated by the discover tool
        validator.validate_in_tool_mode(
            model.get_model(),
            variables_file_name=variable_file_name,
            archive_file_name=model_context.get_archive_file_name())
    except ValidateException, ex:
        __logger.warning('WLSDPLY-06015',
                         ex.getLocalizedMessage(),
                         class_name=_class_name,
                         method_name=_method_name)
    def __init__(self, program_name, arg_map):
        """
        Create a new model context instance.
        Tools should use model_context_helper.create_context(), to ensure that the typedef is initialized correctly.
        Unit tests should use this constructor directly, since typedef files are not deployed.
        :param program_name: the program name, used for logging
        :param arg_map: all the arguments passed to the tool
        """
        self._program_name = program_name
        self._logger = platform_logger.PlatformLogger('wlsdeploy.util')
        self._wls_helper = WebLogicHelper(self._logger)

        self._oracle_home = None
        self._wl_home = None
        self._java_home = None
        self._domain_home = None
        self._domain_name = None
        self._domain_parent_dir = None
        self._domain_type = 'WLS'
        self._domain_typedef = None
        self._admin_url = None
        self._admin_user = None
        self._admin_password = None
        self._archive_file_name = None
        self._archive_file = None
        self._model_file = None
        self._previous_model_file = None
        self._variable_file_name = None
        self._run_rcu = False
        self._rcu_database = None
        self._rcu_prefix = None
        self._rcu_sys_pass = None
        self._rcu_schema_pass = None
        self._encryption_passphrase = None
        self._encrypt_manual = False
        self._encrypt_one_pass = None
        self._use_encryption = False
        self._wl_version = None
        self._wlst_mode = None
        self._recursive = False
        self._attributes_only = False
        self._folders_only = False
        self._opss_wallet_passphrase = None
        self._opss_wallet = None
        self._update_rcu_schema_pass = False
        self._validation_method = None
        self._rollback_if_restart_required = None
        self._domain_resource_file = None
        self._output_dir = None
        self._target = None
        self._target_configuration = None
        self._variable_injector_file = None
        self._variable_keywords_file = None
        self._variable_properties_file = None
        self._rcu_db_user = self.DB_USER_DEFAULT
        self._discard_current_edit = False
        self._model_config = None
        self._ignore_missing_archive_entries = False

        self._trailing_args = []

        if self._wl_version is None:
            self._wl_version = self._wls_helper.get_actual_weblogic_version()

        if self._wlst_mode is None:
            self._wlst_mode = WlstModes.OFFLINE

        self.__copy_from_args(arg_map)

        return