Пример #1
0
class DomainResourceExtractor:
    """
    Create a domain resource file for use with Kubernetes deployment.
    """
    _class_name = "DomainResourceExtractor"

    # the name field keys corresponding to named model elements
    NAME_KEY_MAP = {CHANNELS: 'channelName', CLUSTERS: CLUSTER_NAME}

    def __init__(self, model, model_context, aliases, logger):
        self._model = model
        self._model_context = model_context
        self._aliases = AliasHelper(aliases, logger, ExceptionType.DEPLOY)
        self._logger = logger
        return

    def extract(self):
        """
        Deploy resource model elements at the domain level, including multi-tenant elements.
        """
        _method_name = 'extract'

        resource_file = self._model_context.get_domain_resource_file()
        self._logger.info("WLSDPLY-10000",
                          resource_file,
                          method_name=_method_name,
                          class_name=self._class_name)

        # create the target file directory, if needed
        resource_dir = File(resource_file).getParentFile()
        if (not resource_dir.isDirectory()) and (not resource_dir.mkdirs()):
            mkdir_ex = exception_helper.create_deploy_exception(
                'WLSDPLY-10001', resource_dir)
            raise mkdir_ex

        # build the resource file structure from the kubernetes section of the model
        resource_dict = self._create_domain_resource_dictionary()

        # revise the resource file structure with values from command line, and elsewhere in model
        self._update_resource_dictionary(resource_dict)

        # write the resource file structure to the output file
        writer = PythonToFile(resource_dict)

        writer.write_to_file(resource_file)
        return

    def _create_domain_resource_dictionary(self):
        """
        Build the resource file structure from the kubernetes section of the model.
        :return: the resource file structure
        """
        kubernetes_map = self._model.get_model_kubernetes()

        resource_dict = PyOrderedDict()

        attribute_location = self._aliases.get_model_section_attribute_location(
            KUBERNETES)
        top_attributes_map = self._aliases.get_model_attribute_names_and_types(
            attribute_location)
        top_folders = self._aliases.get_model_section_top_level_folder_names(
            KUBERNETES)

        self._process_fields(kubernetes_map, top_folders, top_attributes_map,
                             LocationContext(), resource_dict)
        return resource_dict

    def _process_fields(self, model_dict, folder_names, attributes_map,
                        location, target_dict):
        """
        Transfer folders and attributes from the model dictionary to the target domain resource dictionary.
        For the top level, the folders and attributes are not derived directly from the location.
        :param model_dict: the source model dictionary
        :param folder_names: the names of the folders at this location
        :param attributes_map: the map of attribute names to types for this location
        :param location: the location used for alias processing
        :param target_dict: the target dictionary for the domain resource file.
       """
        for key, model_value in model_dict.items():
            if key in attributes_map.keys():
                type_name = attributes_map[key]
                target_dict[key] = _get_target_value(model_value, type_name)

            elif key in folder_names:
                child_location = LocationContext(location).append_location(key)

                if self._aliases.supports_multiple_mbean_instances(
                        child_location):
                    target_dict[key] = self._build_dictionary_list(
                        key, model_value, child_location)
                else:
                    if key not in target_dict:
                        target_dict[key] = PyOrderedDict()
                    target_child_dict = target_dict[key]
                    self._process_location_fields(model_value, child_location,
                                                  target_child_dict)
        return

    def _process_location_fields(self, model_dict, location, target_dict):
        """
        Transfer folders and attributes from the model dictionary to the target domain resource dictionary.
        Below the top level, the folders and attributes can be derived from the location.
        :param model_dict: the source model dictionary
        :param location: the location used for alias processing
        :param target_dict: the target dictionary for the domain resource file.
       """
        attributes_map = self._aliases.get_model_attribute_names_and_types(
            location)
        folder_names = self._aliases.get_model_subfolder_names(location)
        self._process_fields(model_dict, folder_names, attributes_map,
                             location, target_dict)
        return

    def _build_dictionary_list(self, model_key, name_dictionary, location):
        """
        Build a dictionary list object based on the name dictionary and location.
        :param name_dictionary: a dictionary containing named levels
        :param location: the location used for alias resolution
        :return:
        """
        child_list = DictionaryList()
        for name in name_dictionary:
            model_named_dict = name_dictionary[name]
            name_key = self._get_name_key(model_key)
            target_list_dict = PyOrderedDict()
            target_list_dict[name_key] = name
            self._process_location_fields(model_named_dict, location,
                                          target_list_dict)
            child_list.append(target_list_dict)
        return child_list

    def _get_name_key(self, key):
        """
        Return the key to be used for the name in a dictionary list element.
        :param key: the folder key in the model
        :return: the name key
        """
        key = dictionary_utils.get_element(self.NAME_KEY_MAP, key)
        if key is not None:
            return key
        return 'name'

    def _update_resource_dictionary(self, resource_dict):
        """
        Revise the resource file structure with values from defaults, command line, and elsewhere in model
        :param resource_dict: the resource file dictionary
        """
        _method_name = '_update_resource_dictionary'

        # add API version if not present
        if API_VERSION not in resource_dict:
            resource_dict[API_VERSION] = DEFAULT_API_VERSION

        # add kind if not present
        if KIND not in resource_dict:
            resource_dict[KIND] = DEFAULT_KIND

        # add a metadata section if not present, since we'll at least add name
        if METADATA not in resource_dict:
            resource_dict[METADATA] = PyOrderedDict()
        metadata_section = resource_dict[METADATA]

        # if metadata name not present, use the domain name from the model, or default
        if K_NAME not in metadata_section:
            domain_name = dictionary_utils.get_element(
                self._model.get_model_topology(), NAME)
            if domain_name is None:
                domain_name = DEFAULT_WLS_DOMAIN_NAME
            metadata_section[K_NAME] = domain_name

        # add a spec section if not present, since we'll at least add domain home
        if SPEC not in resource_dict:
            resource_dict[SPEC] = PyOrderedDict()
        spec_section = resource_dict[SPEC]

        # only set domain home if it is not present in spec section
        if DOMAIN_HOME not in spec_section:
            spec_section[DOMAIN_HOME] = self._model_context.get_domain_home()

        # only set image if it is not present in spec section
        if IMAGE not in spec_section:
            spec_section[IMAGE] = DEFAULT_IMAGE

        # imagePullSecrets is required unless imagePullPolicy is Never
        pull_secrets_required = True
        if IMAGE_PULL_POLICY in spec_section:
            policy = str(spec_section[IMAGE_PULL_POLICY])
            pull_secrets_required = (policy != NEVER)

        # if imagePullSecrets required and not present, add a list with one FIX ME value
        if pull_secrets_required and (IMAGE_PULL_SECRETS not in spec_section):
            secrets_list = DictionaryList()
            secrets_list.append({'name': DEFAULT_IMAGE_PULL_SECRETS})
            spec_section[IMAGE_PULL_SECRETS] = secrets_list

        # if webLogicCredentialsSecret not present, add it using the FIX ME value
        if WEBLOGIC_CREDENTIALS_SECRET not in spec_section:
            spec_section[
                WEBLOGIC_CREDENTIALS_SECRET] = DEFAULT_WEBLOGIC_CREDENTIALS_SECRET

        # only update clusters if section is not present in spec section
        if CLUSTERS not in spec_section:
            topology = self._model.get_model_topology()
            model_clusters = dictionary_utils.get_dictionary_element(
                topology, CLUSTER)
            if len(model_clusters) > 0:
                cluster_list = DictionaryList()
                spec_section[CLUSTERS] = cluster_list
                for cluster_name, cluster_values in model_clusters.items():
                    server_count = k8s_helper.get_server_count(
                        cluster_name, cluster_values, self._model.get_model())
                    cluster_dict = PyOrderedDict()
                    cluster_dict[CLUSTER_NAME] = cluster_name
                    cluster_dict[REPLICAS] = server_count

                    self._logger.info("WLSDPLY-10002",
                                      cluster_name,
                                      server_count,
                                      method_name=_method_name,
                                      class_name=self._class_name)
                    cluster_list.append(cluster_dict)
        return
Пример #2
0
class ModelHelpPrinter(object):
    """
    Class for printing the recognized model metadata to STDOUT.
    """
    def __init__(self, aliases, logger):
        """
        :param aliases: A reference to an Aliases class instance
        :param logger: A reference to the platform logger to write to, if a log entry needs to be made
        """
        self._logger = logger
        self._alias_helper = AliasHelper(aliases, self._logger,
                                         ExceptionType.CLA)

    def print_model_help(self, model_path, control_option, as_sample=False):
        """
        Prints out the help information for a given '''model_path'''. '''model_path''' needs to be specified
        using the following pattern:

                <model_section>[:/<section_folder>[/<section_subfolder>|...]]

        Examples:
                'domainInfo', 'domainInfo:' or 'domainInfo:/' (all 3 are equivalent)
                'topology:/Server'
                'resources:/JDBCSystemResource/JdbcResource/JDBCDriverParams'
                'appDeployments:/Application'

        :param model_path: a formatted string containing the model path
        :param control_option: a command-line switch that controls what is output
        :param as_sample: specifies that a model sample should be output
        :raises CLAException: if a problem is encountered
        """

        # print filter information, if not NORMAL
        if control_option == ControlOptions.RECURSIVE:
            print
            print _format_message('WLSDPLY-10102')
        elif control_option == ControlOptions.FOLDERS_ONLY:
            print
            print _format_message('WLSDPLY-10103')
        elif control_option == ControlOptions.ATTRIBUTES_ONLY:
            print
            print _format_message('WLSDPLY-10104')

        model_path_tokens = self._parse_model_path(model_path)

        section_name = model_path_tokens[0]
        valid_section_folder_keys = self._alias_helper.get_model_section_top_level_folder_names(
            section_name)

        if as_sample:
            sample_printer = ModelSamplePrinter(self._alias_helper,
                                                self._logger)
            sample_printer.print_model_sample(model_path_tokens,
                                              control_option)
        else:
            if model_path_tokens[0] == 'top':
                self._print_model_top_level_help()
            elif len(model_path_tokens) == 1:
                self._print_model_section_help(section_name,
                                               valid_section_folder_keys,
                                               control_option)
            else:
                self._print_model_folder_help(model_path_tokens,
                                              valid_section_folder_keys,
                                              control_option)

    def _parse_model_path(self, model_path):
        """
        Parse the specified model_path into a Python list of elements.
        The first element will be the section name.
        If not specified, the section name will be derived from the first path element.
        :param model_path: a string contain the model path to parse
        :return: a python list containing the section name, then each folder element
        :raises: CLAException if the path cannot be parsed, or the section name is invalid
        """
        _method_name = '_parse_model_path'

        self._logger.entering(model_path,
                              class_name=_class_name,
                              method_name=_method_name)

        match = MODEL_PATH_PATTERN.match(model_path)
        if match is None:
            ex = exception_helper.create_cla_exception('WLSDPLY-10108',
                                                       model_path)
            self._logger.throwing(ex,
                                  class_name=_class_name,
                                  method_name=_method_name)
            raise ex

        self._logger.finest('match.group(1)={0}, match.group(2)={1}',
                            str(match.group(1)),
                            str(match.group(2)),
                            class_name=_class_name,
                            method_name=_method_name)

        section = match.group(1)
        path = match.group(2)

        folders = []
        if path is not None:
            for folder in path.split('/'):
                # trailing or duplicate slashes may cause empty folder name
                if len(folder) > 0:
                    folders.append(folder)

        if section is None:
            section = self._get_section_for_folder_list(folders)

        section = section.replace(':', '')

        top_level_keys = model.get_model_top_level_keys()

        # 'top' is a special case for listing the sections
        all_section_keys = ['top']
        all_section_keys.extend(top_level_keys)

        if section not in all_section_keys:
            ex = exception_helper.create_cla_exception(
                'WLSDPLY-10109', section, str(', '.join(top_level_keys)))
            self._logger.throwing(ex,
                                  class_name=_class_name,
                                  method_name=_method_name)
            raise ex

        model_path_tokens = [section]
        model_path_tokens.extend(folders)
        return model_path_tokens

    def _get_section_for_folder_list(self, folder_list):
        """
        Derive the section name from the first folder in the specified list.
        :param folder_list: the list of folders in the model path
        :return: the section name
        :raises: CLAException if the section name cannot be determined
        """
        _method_name = '_get_section_for_folder_list'
        top_folder = folder_list[0]

        for section in KNOWN_TOPLEVEL_MODEL_SECTIONS:
            folder_keys = self._alias_helper.get_model_section_top_level_folder_names(
                section)
            if top_folder in folder_keys:
                return section

        ex = exception_helper.create_cla_exception('WLSDPLY-10101', top_folder)
        self._logger.throwing(ex,
                              class_name=_class_name,
                              method_name=_method_name)
        raise ex

    def _print_model_top_level_help(self):
        """
        Prints out all the valid section names for a model.
        The -recursive flag is disregarded for this case.
        """
        _method_name = '_print_model_top_level_help'
        self._logger.finest('sections={0}',
                            KNOWN_TOPLEVEL_MODEL_SECTIONS,
                            class_name=_class_name,
                            method_name=_method_name)

        title = _format_message('WLSDPLY-10113')

        # Print 'All Sections:' header
        print
        _print_indent(title, 0)
        print

        for section in KNOWN_TOPLEVEL_MODEL_SECTIONS:
            _print_indent(section, 1)

    def _print_model_section_help(self, section_name,
                                  valid_section_folder_keys, control_option):
        """
        Prints the help for a section of a model, when just the section_name[:] is provided
        :param section_name: the name of the model section
        :param valid_section_folder_keys: list of the valid top folders in the specified section
        :param control_option: A command-line switch that controls what is output to STDOUT
        """
        _method_name = '_print_model_section_help'

        self._logger.finest('1 section_name={0}',
                            section_name,
                            class_name=_class_name,
                            method_name=_method_name)

        location_path = '%s:' % section_name
        self._logger.finest('1 location_path={0}',
                            location_path,
                            class_name=_class_name,
                            method_name=_method_name)

        model_section = _format_message('WLSDPLY-10106', location_path)

        # Print 'Section: <model_section>' label and field
        print
        _print_indent(model_section, 0)

        if model_help_utils.show_attributes(control_option):
            attributes_location = self._alias_helper.get_model_section_attribute_location(
                section_name)
            if attributes_location is not None:
                self._print_attributes_help(attributes_location, 1)

        if model_help_utils.show_folders(control_option):
            print
            _print_indent(_format_message('WLSDPLY-10107'), 1)
            valid_section_folder_keys.sort()

            for section_folder_key in valid_section_folder_keys:
                _print_indent(section_folder_key, 2)

                if control_option == ControlOptions.RECURSIVE:
                    model_location = LocationContext().append_location(
                        section_folder_key)
                    self._print_subfolders_help(model_location, control_option,
                                                2)

    def _print_model_folder_help(self, model_path_tokens,
                                 valid_section_folder_keys, control_option):
        """
        Prints the help for a folder in a model, when more than just the section_name[:] is provided.
        The section name in the first token was already validated.
        :param model_path_tokens: a Python list of path elements built from model path
        :param valid_section_folder_keys: A list of valid folder names for the model section in the path
        :param control_option: A command-line switch that controls what is output to STDOUT
        """
        _method_name = '_print_model_folder_help'

        self._logger.finest(
            '1 model_path_tokens={0}, control_option={1}, valid_section_folder_keys={0}',
            str(model_path_tokens),
            ControlOptions.from_value(control_option),
            str(valid_section_folder_keys),
            class_name=_class_name,
            method_name=_method_name)

        section_name = model_path_tokens[0]
        top_folder = model_path_tokens[1]
        if top_folder not in valid_section_folder_keys:
            ex = exception_helper.create_cla_exception(
                'WLSDPLY-10110', section_name + ':', top_folder,
                ', '.join(valid_section_folder_keys))
            self._logger.throwing(ex,
                                  class_name=_class_name,
                                  method_name=_method_name)
            raise ex

        # Populate the location context using model_path_tokens[1:]
        model_location = LocationContext()
        for folder_key in model_path_tokens[1:]:
            model_location.append_location(folder_key)
            name_token = self._alias_helper.get_name_token(model_location)
            if name_token is not None:
                model_location.add_name_token(name_token, '%s-0' % folder_key)

            self._logger.finest('2 model_location={0}',
                                model_location,
                                class_name=_class_name,
                                method_name=_method_name)

        folder_path = '/'.join(model_path_tokens[1:])
        model_path = _format_message('WLSDPLY-10105',
                                     '%s:/%s' % (section_name, folder_path))
        type_name = self._get_folder_type_name(model_location)
        if type_name is not None:
            model_path += " (" + type_name + ")"

        # Print 'Path: <model_section>' header
        print
        _print_indent(model_path, 0)

        if model_help_utils.show_attributes(control_option):
            # Print the attributes associated with location context
            self._print_attributes_help(model_location, 1)

        if model_help_utils.show_folders(control_option):
            # Print the folders associated with location context
            print
            _print_indent(_format_message('WLSDPLY-10107'), 1)
            self._print_subfolders_help(model_location, control_option, 1)

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

    def _print_subfolders_help(self, model_location, control_option,
                               indent_level):
        """
        Prints the help for the folders in a model location, without header or leading space.
        :param model_location: the model location being worked on
        :param control_option: a command-line switch that controls what is output to STDOUT
        :param indent_level: the level to indent by, before printing output
        """
        _method_name = '_print_subfolders_help'

        valid_subfolder_keys = self._alias_helper.get_model_subfolder_names(
            model_location)
        self._logger.finest(
            '3 aliases.get_model_subfolder_names(model_location) returned: {0}',
            str(valid_subfolder_keys),
            class_name=_class_name,
            method_name=_method_name)

        if not valid_subfolder_keys:
            return

        valid_subfolder_keys.sort()

        for key in valid_subfolder_keys:
            model_location.append_location(key)
            name_token = self._alias_helper.get_name_token(model_location)
            if name_token is not None:
                model_location.add_name_token(name_token, '%s-0' % key)

            self._logger.finest('3 model_location={0}',
                                model_location,
                                class_name=_class_name,
                                method_name=_method_name)

            text = key
            type_name = self._get_folder_type_name(model_location)
            if type_name is not None:
                text += " (" + type_name + ")"

            _print_indent(text, indent_level + 1)

            if control_option == ControlOptions.RECURSIVE:
                # Call this method recursively
                self._print_subfolders_help(model_location, control_option,
                                            indent_level + 1)

            model_location.pop_location()

    def _print_attributes_help(self, model_location, indent_level):
        """
        Prints out the help for the attributes in a model location
        :param model_location: An object containing data about the model location being worked on
        :param indent_level: The level to indent by, before printing output
        """
        _method_name = '_print_attributes_help'

        attr_infos = self._alias_helper.get_model_attribute_names_and_types(
            model_location)
        self._logger.finer('WLSDPLY-05012',
                           str(model_location),
                           str(attr_infos),
                           class_name=_class_name,
                           method_name=_method_name)

        # Print 'Valid Attributes:' area label
        print
        _print_indent(_format_message('WLSDPLY-10111'), indent_level)

        if attr_infos:
            maxlen = 0
            for key in attr_infos:
                if len(key) > maxlen:
                    maxlen = len(key)
            formatted_string = '%-' + str(maxlen) + 's\t%s'

            attr_list = attr_infos.keys()
            attr_list.sort()
            for attr_name in attr_list:
                msg = formatted_string % (attr_name, attr_infos[attr_name])
                _print_indent(msg, indent_level + 1)

    def _get_folder_type_name(self, location):
        """
        Return text indicating the type of a folder, such as "multiple".
        :param location: the location to be checked
        :return: name of the folder type to be displayed, or None
        """
        if self._alias_helper.is_artificial_type_folder(location):
            return None
        if self._alias_helper.supports_multiple_mbean_instances(location):
            return "multiple"
        return None
Пример #3
0
class UsagePrinter(object):
    """
    Class for printing the recognized metadata for a model file, to STDOUT. This output is referred to as the usage.
    """
    ControlOptions = Enum(['RECURSIVE', 'FOLDERS_ONLY', 'ATTRIBUTES_ONLY'])

    def __init__(self, aliases, logger):
        """

        :param aliases: A reference to an Aliases class instance
        :param logger: A reference to the platform logger to write to, if a log entry needs to be made
        """

        self._logger = logger
        self._aliases = aliases
        self._alias_helper = AliasHelper(self._aliases, self._logger,
                                         ExceptionType.VALIDATE)

    def print_model_path_usage(self, model_path, control_option):
        """
        Prints out the usage information for a given '''model_path'''. '''model_path''' needs to be specified
        using the following pattern:

                <model_section>[:/<section_folder>[/<section_subfolder>|...]]

        Examples:
                'domainInfo', 'domainInfo:' or 'domainInfo:/' (all 3 are rquivalent)
                'topology:/Server'
                'resources:/JDBCSystemResource/JdbcResource/JDBCDriverParams'
                'appDeployments:/Application'

        :param model_path: A forward-slash delimited string contain the model path to print usage for
        :param control_option: A command-line switch that controls what is output to STDOUT
        :return:
        :raises ValidationException: if an AliasException is raised during an invocation of an aliases API call.
        """

        model_path_tokens = self.__create_model_path_tokens(model_path)

        top_level_key = model_path_tokens[0]

        if control_option == self.ControlOptions.RECURSIVE:
            print validation_utils.format_message('WLSDPLY-05100')
        elif control_option == self.ControlOptions.FOLDERS_ONLY:
            print validation_utils.format_message('WLSDPLY-05101')
        elif control_option == self.ControlOptions.ATTRIBUTES_ONLY:
            print validation_utils.format_message('WLSDPLY-05102')

        validation_utils.print_blank_lines()

        section_name = model_path_tokens[0]
        valid_section_folder_keys = self._aliases.get_model_section_top_level_folder_names(
            section_name)

        if len(model_path_tokens) == 1:
            self.__print_top_level_usage(top_level_key,
                                         valid_section_folder_keys,
                                         control_option)
        else:
            self.__print_model_section_usage(model_path_tokens,
                                             valid_section_folder_keys,
                                             control_option)

        return

    def __print_top_level_usage(self, top_level_key, valid_section_folder_keys,
                                control_option):
        """
        Prints out the usage for a section of a model, when just the section_name[:[/}} is provided

        :param top_level_key: The name of one of the model sections
        :param valid_section_folder_keys: Python list of the valid model section names
        :param control_option: A command-line switch that controls what is output to STDOUT
        :return:
        """

        _method_name = '__print_top_level_usage'

        self._logger.finest('1 top_level_key={0}',
                            top_level_key,
                            class_name=_class_name,
                            method_name=_method_name)

        location_path = '%s:' % top_level_key
        self._logger.finest('1 location_path={0}',
                            location_path,
                            class_name=_class_name,
                            method_name=_method_name)

        model_section = validation_utils.format_message(
            'WLSDPLY-05104', location_path)

        # Print 'Section: <model_section>' label and field
        validation_utils.print_indent(model_section, 0)
        validation_utils.print_blank_lines()

        validation_location = LocationContext()
        attributes_location = self._alias_helper.get_model_section_attribute_location(
            top_level_key)

        if attributes_location is not None:
            self.__print_attributes_usage(attributes_location, 1)

        if control_option == self.ControlOptions.FOLDERS_ONLY:
            validation_utils.print_indent(
                validation_utils.format_message('WLSDPLY-05105'), 1)
            valid_section_folder_keys.sort()

        for section_folder_key in valid_section_folder_keys:
            if control_option == self.ControlOptions.FOLDERS_ONLY:
                validation_utils.print_indent(section_folder_key, 2)

            elif control_option == self.ControlOptions.RECURSIVE:
                validation_location.append_location(section_folder_key)

                name_token = self._alias_helper.get_name_token(
                    validation_location)
                if name_token is not None:
                    validation_location.add_name_token(
                        name_token, '%s-0' % section_folder_key)

                self._logger.finest('1 validation_location={0}',
                                    validation_location,
                                    class_name=_class_name,
                                    method_name=_method_name)

                location_path = '%s:%s' % (
                    top_level_key, validation_location.get_folder_path())
                model_path = validation_utils.format_message(
                    'WLSDPLY-05103', location_path)

                validation_utils.print_blank_lines()
                validation_utils.print_indent(model_path, 0)
                validation_utils.print_blank_lines()

                self.__print_folders_usage(validation_location, control_option,
                                           1)
                validation_location.pop_location()
        return

    def __print_model_section_usage(self, model_path_tokens,
                                    valid_section_folder_keys, control_option):
        """
        Prints out the usage for a section of a model, when more than just the section_name[:[/}} is provided

        :param model_path_tokens: A Python list of path elements built from model path
        :param valid_section_folder_keys: A list of valid folder names for the model section the
        usage is being printed for
        :param control_option: A command-line switch that controls what is output to STDOUT
        :return:
        """

        _method_name = '__print_model_section_usage'

        self._logger.finest('1 model_path_tokens={0}, control_option={1}',
                            str(model_path_tokens),
                            self.ControlOptions.from_value(control_option),
                            class_name=_class_name,
                            method_name=_method_name)
        self._logger.finest('1 valid_section_folder_keys={0}',
                            str(valid_section_folder_keys),
                            class_name=_class_name,
                            method_name=_method_name)

        self.__validate_section_folder_path(model_path_tokens,
                                            valid_section_folder_keys)

        validation_location = LocationContext()

        model_path = validation_utils.format_message(
            'WLSDPLY-05103',
            '%s:/%s' % (model_path_tokens[0], '/'.join(model_path_tokens[1:])))

        # Print 'Path: <model_section>' header
        validation_utils.print_indent(model_path, 0)
        validation_utils.print_blank_lines()

        # Populate the location context using model_path_tokens[1:]
        for folder_key in model_path_tokens[1:]:
            validation_location.append_location(folder_key)
            name_token = self._alias_helper.get_name_token(validation_location)
            if name_token is not None:
                validation_location.add_name_token(name_token,
                                                   '%s-0' % folder_key)

            self._logger.finest('2 validation_location={0}',
                                validation_location,
                                class_name=_class_name,
                                method_name=_method_name)

        # Print the attributes associated with location context
        self.__print_attributes_usage(validation_location, 1)

        if control_option != self.ControlOptions.ATTRIBUTES_ONLY:
            # Print the folders associated with location context
            self.__print_folders_usage(validation_location, control_option, 1)

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

    def __print_folders_usage(self, validation_location, control_option,
                              indent_level):
        """
        Prints out the usage for the folders in a model location

        :param validation_location: An object containing data about the model location being worked on
        :param control_option: A command-line switch that controls what is output to STDOUT
        :param indent_level: The level to indent by, before printing output
        :return:
        """

        _method_name = '__print_folders_usage'

        valid_subfolder_keys = self._alias_helper.get_model_subfolder_names(
            validation_location)
        self._logger.finest(
            '3 aliases.get_model_subfolder_names(validation_location) returned: {0}',
            str(valid_subfolder_keys),
            class_name=_class_name,
            method_name=_method_name)

        if not valid_subfolder_keys:
            return

        validation_utils.print_indent(
            validation_utils.format_message('WLSDPLY-05105'), indent_level)
        valid_subfolder_keys.sort()

        for key in valid_subfolder_keys:
            validation_location.append_location(key)
            name_token = self._alias_helper.get_name_token(validation_location)
            if name_token is not None:
                validation_location.add_name_token(name_token, '%s-0' % key)

            self._logger.finest('3 validation_location={0}',
                                validation_location,
                                class_name=_class_name,
                                method_name=_method_name)

            validation_utils.print_indent(key, indent_level + 1)

            if control_option != self.ControlOptions.FOLDERS_ONLY:
                self.__print_attributes_usage(validation_location,
                                              indent_level + 2)

            if control_option == self.ControlOptions.RECURSIVE:
                # Call this __print_folders_usage() function recursively
                self.__print_folders_usage(validation_location, control_option,
                                           indent_level + 2)

            validation_location.pop_location()

        return

    def __print_attributes_usage(self, validation_location, indent_level):
        """
        Prints out the usage for the attributes in a model location

        :param validation_location: An object containing data about the model location being worked on
        :param indent_level: The level to indent by, before printing output
        :return:
        """
        _method_name = '__print_attributes_usage'

        attr_infos = self._alias_helper.get_model_attribute_names_and_types(
            validation_location)
        self._logger.finer('WLSDPLY-05012',
                           str(validation_location),
                           str(attr_infos),
                           class_name=_class_name,
                           method_name=_method_name)

        _print_attr_infos(attr_infos, indent_level)
        return

    def __create_model_path_tokens(self, model_path=''):
        """
        Creates a Python list from the elements in the specified model_path.

        :param model_path: A forward-slash delimited string contain the model path to print usage for
        :return:
        """
        _method_name = '__create_model_path_tokens'

        self._logger.entering(model_path,
                              class_name=_class_name,
                              method_name=_method_name)

        if model_path[-1:] != ':':
            m = MODEL_PATH_PATTERN.match(model_path)
            if m is None:
                ex = exception_helper.create_validate_exception(
                    'WLSDPLY-05106', model_path)
                self._logger.throwing(ex,
                                      class_name=_class_name,
                                      method_name=_method_name)
                raise ex

            self._logger.finest('m.group(1)={0}, m.group(3)={1}',
                                str(m.group(1)),
                                str(m.group(3)),
                                class_name=_class_name,
                                method_name=_method_name)

        # Replace any ':' in model_path with '', then split it on '/' into a list
        model_path_tokens = model_path.replace(':', '').split('/')

        # Remove any blank list items caused by the user entering
        # extraneous '/' characters.
        while '' in model_path_tokens:
            del model_path_tokens[model_path_tokens.index('')]

        recognized_top_level_keys = model.get_model_top_level_keys()
        self._logger.finest('recognized_top_level_keys={0}',
                            str(recognized_top_level_keys),
                            class_name=_class_name,
                            method_name=_method_name)

        top_level_key = model_path_tokens[0]

        if top_level_key not in recognized_top_level_keys:
            ex = exception_helper.create_validate_exception(
                'WLSDPLY-05107', top_level_key,
                '%s' % ', '.join(recognized_top_level_keys))
            self._logger.throwing(ex,
                                  class_name=_class_name,
                                  method_name=_method_name)
            raise ex

        return model_path_tokens

    def __validate_section_folder_path(self, model_path_tokens,
                                       valid_section_folder_keys):
        """
        Verifies that a model path element is in the specified valid_section_folder_keys list.

        :param model_path_tokens: A Python list of path elements built from model path
        :param valid_section_folder_keys: A Python list of folder names
        :return:
        """
        _method_name = '__validate_section_folder_path'

        if model_path_tokens[1] not in valid_section_folder_keys:
            ex = exception_helper.create_validate_exception(
                'WLSDPLY-05108', '%s:/' % model_path_tokens[0],
                '%s' % '/'.join(model_path_tokens[1:]),
                '%s' % ', '.join(valid_section_folder_keys))
            self._logger.throwing(ex,
                                  class_name=_class_name,
                                  method_name=_method_name)
            raise ex

        return
class PrepareModel:
    """
      This is the main driver for the caller.  It compares two model files whether they are json or yaml format.
    """
    def __init__(self, model_files, model_context, logger, output_dir=None):
        self.model_files = model_files
        self.output_dir = output_dir
        self.model_context = model_context
        self._aliases = Aliases(model_context=model_context, wlst_mode=WlstModes.OFFLINE)
        self._alias_helper = AliasHelper(self._aliases, logger, ExceptionType.COMPARE)
        self._logger = logger
        self._name_tokens_location = LocationContext()
        self._name_tokens_location.add_name_token('DOMAIN', "testdomain")
        self.current_dict = None
        self.cache =  OrderedDict()
        self.secrets_to_generate = sets.Set()

    def __walk_model_section(self, model_section_key, model_dict, valid_section_folders):
        _method_name = '__validate_model_section'

        if model_section_key not in model_dict.keys():
            return

        # only specific top-level sections have attributes
        attribute_location = self._alias_helper.get_model_section_attribute_location(model_section_key)

        valid_attr_infos = []
        path_tokens_attr_keys = []

        if attribute_location is not None:
            valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(attribute_location)
            path_tokens_attr_keys = self._alias_helper.get_model_uses_path_tokens_attribute_names(attribute_location)

        model_section_dict = model_dict[model_section_key]
        for section_dict_key, section_dict_value in model_section_dict.iteritems():
            # section_dict_key is either the name of a folder in the
            # section, or the name of an attribute in the section.
            validation_location = LocationContext()

            model_folder_path = model_section_key + ":/"
            if section_dict_key in valid_attr_infos:
                # section_dict_key is the name of an attribute in the section
                self.__walk_attribute(section_dict_key, section_dict_value, valid_attr_infos,
                                      path_tokens_attr_keys, model_folder_path, attribute_location)

            elif section_dict_key in valid_section_folders:
                # section_dict_key is a folder under the model section

                # Append section_dict_key to location context
                validation_location.append_location(section_dict_key)

                # Call self.__validate_section_folder() passing in section_dict_value as the model_node to process
                self.__walk_section_folder(section_dict_value, validation_location)


    def __walk_section_folder(self, model_node, validation_location):
        _method_name = '__validate_section_folder'

        model_folder_path = self._alias_helper.get_model_folder_path(validation_location)

        if self._alias_helper.supports_multiple_mbean_instances(validation_location):

            for name in model_node:
                expanded_name = name

                new_location = LocationContext(validation_location)

                name_token = self._alias_helper.get_name_token(new_location)

                if name_token is not None:
                    new_location.add_name_token(name_token, expanded_name)

                value_dict = model_node[name]

                self.__walk_model_node(value_dict, new_location)

        elif self._alias_helper.requires_artificial_type_subfolder_handling(validation_location):

            for name in model_node:
                expanded_name = name

                new_location = LocationContext(validation_location)

                name_token = self._alias_helper.get_name_token(new_location)

                if name_token is not None:
                    new_location.add_name_token(name_token, expanded_name)

                value_dict = model_node[name]

                self.__walk_model_node(value_dict, new_location)

        else:
            name_token = self._alias_helper.get_name_token(validation_location)

            if name_token is not None:
                name = self._name_tokens_location.get_name_for_token(name_token)

                if name is None:
                    name = '%s-0' % name_token

                validation_location.add_name_token(name_token, name)

            self.__walk_model_node(model_node, validation_location)

    def __walk_model_node(self, model_node, validation_location):
        _method_name = '__process_model_node'

        valid_folder_keys = self._alias_helper.get_model_subfolder_names(validation_location)
        valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(validation_location)
        model_folder_path = self._alias_helper.get_model_folder_path(validation_location)

        for key, value in model_node.iteritems():

            if key in valid_folder_keys:
                new_location = LocationContext(validation_location).append_location(key)

                if self._alias_helper.is_artificial_type_folder(new_location):
                    # key is an ARTIFICIAL_TYPE folder
                    valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(new_location)

                    self.__walk_attributes(value, valid_attr_infos, new_location)
                else:
                    self.__walk_section_folder(value, new_location)

            elif key in valid_attr_infos:
                # aliases.get_model_attribute_names_and_types(location) filters out
                # attributes that ARE NOT valid in the wlst_version being used, so if
                # we're in this section of code we know key is a bonafide "valid" attribute
                valid_data_type = valid_attr_infos[key]
                if valid_data_type in ['properties']:
                    valid_prop_infos = {}
                    properties = validation_utils.get_properties(value)
                    self.__walk_properties(properties, valid_prop_infos, validation_location)

                else:
                    path_tokens_attr_keys = \
                        self._alias_helper.get_model_uses_path_tokens_attribute_names(validation_location)

                    self.__walk_attribute(key, value, valid_attr_infos, path_tokens_attr_keys, model_folder_path,
                                          validation_location)

    def __walk_attributes(self, attributes_dict, valid_attr_infos, validation_location):
        _method_name = '__validate_attributes'

        path_tokens_attr_keys = self._alias_helper.get_model_uses_path_tokens_attribute_names(validation_location)

        model_folder_path = self._alias_helper.get_model_folder_path(validation_location)

        for attribute_name, attribute_value in attributes_dict.iteritems():
            self.__walk_attribute(attribute_name, attribute_value, valid_attr_infos, path_tokens_attr_keys,
                                  model_folder_path, validation_location)

    def __walk_attribute(self, attribute_name, attribute_value, valid_attr_infos, path_tokens_attr_keys,
                         model_folder_path, validation_location):
        _method_name = '__validate_attribute'

        if attribute_name in valid_attr_infos:
            expected_data_type = valid_attr_infos[attribute_name]

            if expected_data_type == 'password':
                self.__substitute_password_with_token(model_folder_path, attribute_name, validation_location)

        self._logger.exiting(class_name=_class_name, method_name=_method_name)

    def __walk_properties(self, properties_dict, valid_prop_infos, validation_location):
        _method_name = '__walk_properties'

        for property_name, property_value in properties_dict.iteritems():
            valid_prop_infos[property_name] = validation_utils.get_python_data_type(property_value)
            self.__walk_property(property_name, property_value, valid_prop_infos, validation_location)


    def __walk_property(self, property_name, property_value, valid_prop_infos, model_folder_path, validation_location):

        _method_name = '__walk_property'

        self._logger.entering(property_name, property_value, str(valid_prop_infos), model_folder_path,
                              class_name=_class_name, method_name=_method_name)

        if property_name in valid_prop_infos:
            expected_data_type = valid_prop_infos[property_name]
            if expected_data_type == 'password':
                self.__substitute_password_with_token(model_folder_path, property_name, validation_location)


    def __format_variable_name(self, location, attribute):
        _method_name = '__format_variable_name'
        def __traverse_location(iterate_location, name_list, last_folder=None, last_folder_short=None):
            current_folder = iterate_location.get_current_model_folder()
            if current_folder == model_constants.DOMAIN:
                if last_folder is not None:
                    # If a short name is not defined for the top level folder, use the full name
                    if len(last_folder_short) == 0:
                        last_folder_short = last_folder
                    name_list.insert(0, last_folder_short)
            else:
                current_folder = iterate_location.get_current_model_folder()
                short_folder = self._aliases.get_folder_short_name(iterate_location)
                if last_folder_short is not None:
                    name_list.insert(0, last_folder_short)
                try:
                    if not self._aliases.is_artificial_type_folder(location) and \
                            (self._aliases.supports_multiple_mbean_instances(iterate_location) or
                             self._aliases.is_custom_folder_allowed(iterate_location)):
                        name_token = self._aliases.get_name_token(iterate_location)
                        name = iterate_location.get_name_for_token(name_token)
                        name_list.insert(0, name)
                        iterate_location.remove_name_token(name_token)
                    iterate_location.pop_location()
                except AliasException, ae:
                    self._logger.warning('WLSDPLY-19531', str(location), attribute, ae.getLocalizedMessage(),
                                    class_name=_class_name, method_name=_method_name)
                __traverse_location(iterate_location, name_list, current_folder, short_folder)
            return name_list

        short_list = __traverse_location(LocationContext(location), list())
        short_name = ''
        for node in short_list:
            if node is not None and len(node) > 0:
                short_name += node + '.'
        short_name += attribute
        _fake_name_replacement = re.compile('.fakename')
        _white_space_replacement = re.compile('\s')
        short_name = short_name.replace('/', '.')
        short_name = _white_space_replacement.sub('-', short_name)
        short_name = _fake_name_replacement.sub('', short_name)

        return short_name
Пример #5
0
class PrepareModel:
    """
      This is the main driver for the caller.  It compares two model files whether they are json or yaml format.
    """
    def __init__(self, model_files, model_context, logger, output_dir=None):
        self.model_files = model_files
        self.output_dir = output_dir
        self.model_context = model_context
        self._aliases = Aliases(model_context=model_context,
                                wlst_mode=WlstModes.OFFLINE)
        self._alias_helper = AliasHelper(self._aliases, logger,
                                         ExceptionType.COMPARE)
        self._logger = logger
        self._name_tokens_location = LocationContext()
        self._name_tokens_location.add_name_token('DOMAIN', "testdomain")
        self.current_dict = None
        self.cache = OrderedDict()
        self.secrets_to_generate = sets.Set()

    def __walk_model_section(self, model_section_key, model_dict,
                             valid_section_folders):
        _method_name = '__validate_model_section'

        if model_section_key not in model_dict.keys():
            return

        # only specific top-level sections have attributes
        attribute_location = self._alias_helper.get_model_section_attribute_location(
            model_section_key)

        valid_attr_infos = []
        path_tokens_attr_keys = []

        if attribute_location is not None:
            valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(
                attribute_location)
            path_tokens_attr_keys = self._alias_helper.get_model_uses_path_tokens_attribute_names(
                attribute_location)

        model_section_dict = model_dict[model_section_key]
        for section_dict_key, section_dict_value in model_section_dict.iteritems(
        ):
            # section_dict_key is either the name of a folder in the
            # section, or the name of an attribute in the section.
            validation_location = LocationContext()

            model_folder_path = model_section_key + ":/"
            if section_dict_key in valid_attr_infos:
                # section_dict_key is the name of an attribute in the section
                self.__walk_attribute(section_dict_key, section_dict_value,
                                      valid_attr_infos, path_tokens_attr_keys,
                                      model_folder_path, attribute_location)

            elif section_dict_key in valid_section_folders:
                # section_dict_key is a folder under the model section

                # Append section_dict_key to location context
                validation_location.append_location(section_dict_key)

                # Call self.__validate_section_folder() passing in section_dict_value as the model_node to process
                self.__walk_section_folder(section_dict_value,
                                           validation_location)

    def __walk_section_folder(self, model_node, validation_location):
        _method_name = '__validate_section_folder'

        model_folder_path = self._alias_helper.get_model_folder_path(
            validation_location)

        if self._alias_helper.supports_multiple_mbean_instances(
                validation_location):

            for name in model_node:
                expanded_name = name

                new_location = LocationContext(validation_location)

                name_token = self._alias_helper.get_name_token(new_location)

                if name_token is not None:
                    new_location.add_name_token(name_token, expanded_name)

                value_dict = model_node[name]

                self.__walk_model_node(value_dict, new_location)

        elif self._alias_helper.requires_artificial_type_subfolder_handling(
                validation_location):

            for name in model_node:
                expanded_name = name

                new_location = LocationContext(validation_location)

                name_token = self._alias_helper.get_name_token(new_location)

                if name_token is not None:
                    new_location.add_name_token(name_token, expanded_name)

                value_dict = model_node[name]

                self.__walk_model_node(value_dict, new_location)

        else:
            name_token = self._alias_helper.get_name_token(validation_location)

            if name_token is not None:
                name = self._name_tokens_location.get_name_for_token(
                    name_token)

                if name is None:
                    name = '%s-0' % name_token

                validation_location.add_name_token(name_token, name)

            self.__walk_model_node(model_node, validation_location)

    def __walk_model_node(self, model_node, validation_location):
        _method_name = '__process_model_node'

        valid_folder_keys = self._alias_helper.get_model_subfolder_names(
            validation_location)
        valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(
            validation_location)
        model_folder_path = self._alias_helper.get_model_folder_path(
            validation_location)

        for key, value in model_node.iteritems():

            if key in valid_folder_keys:
                new_location = LocationContext(
                    validation_location).append_location(key)

                if self._alias_helper.is_artificial_type_folder(new_location):
                    # key is an ARTIFICIAL_TYPE folder
                    valid_attr_infos = self._alias_helper.get_model_attribute_names_and_types(
                        new_location)

                    self.__walk_attributes(value, valid_attr_infos,
                                           new_location)
                else:
                    self.__walk_section_folder(value, new_location)

            elif key in valid_attr_infos:
                # aliases.get_model_attribute_names_and_types(location) filters out
                # attributes that ARE NOT valid in the wlst_version being used, so if
                # we're in this section of code we know key is a bonafide "valid" attribute
                valid_data_type = valid_attr_infos[key]
                if valid_data_type in ['properties']:
                    valid_prop_infos = {}
                    properties = validation_utils.get_properties(value)
                    self.__walk_properties(properties, valid_prop_infos,
                                           model_folder_path,
                                           validation_location)

                else:
                    path_tokens_attr_keys = \
                        self._alias_helper.get_model_uses_path_tokens_attribute_names(validation_location)

                    self.__walk_attribute(key, value, valid_attr_infos,
                                          path_tokens_attr_keys,
                                          model_folder_path,
                                          validation_location)

    def __walk_attributes(self, attributes_dict, valid_attr_infos,
                          validation_location):
        _method_name = '__validate_attributes'

        path_tokens_attr_keys = self._alias_helper.get_model_uses_path_tokens_attribute_names(
            validation_location)

        model_folder_path = self._alias_helper.get_model_folder_path(
            validation_location)

        for attribute_name, attribute_value in attributes_dict.iteritems():
            self.__walk_attribute(attribute_name, attribute_value,
                                  valid_attr_infos, path_tokens_attr_keys,
                                  model_folder_path, validation_location)

    def __walk_attribute(self, attribute_name, attribute_value,
                         valid_attr_infos, path_tokens_attr_keys,
                         model_folder_path, validation_location):
        _method_name = '__walk_attribute'

        if attribute_name in valid_attr_infos:
            expected_data_type = valid_attr_infos[attribute_name]

            if (expected_data_type == 'password') or (attribute_name
                                                      == ADMIN_USERNAME):
                self.__substitute_password_with_token(model_folder_path,
                                                      attribute_name,
                                                      validation_location)

        self._logger.exiting(class_name=_class_name, method_name=_method_name)

    def __walk_properties(self, properties_dict, valid_prop_infos,
                          model_folder_path, validation_location):
        _method_name = '__walk_properties'

        for property_name, property_value in properties_dict.iteritems():
            valid_prop_infos[
                property_name] = validation_utils.get_python_data_type(
                    property_value)
            self.__walk_property(property_name, property_value,
                                 valid_prop_infos, model_folder_path,
                                 validation_location)

    def __walk_property(self, property_name, property_value, valid_prop_infos,
                        model_folder_path, validation_location):

        _method_name = '__walk_property'

        self._logger.entering(property_name,
                              property_value,
                              str(valid_prop_infos),
                              model_folder_path,
                              class_name=_class_name,
                              method_name=_method_name)

        if property_name in valid_prop_infos:
            expected_data_type = valid_prop_infos[property_name]
            if expected_data_type == 'password':
                self.__substitute_password_with_token(model_folder_path,
                                                      property_name,
                                                      validation_location)

    def __substitute_password_with_token(self, model_path, attribute_name,
                                         validation_location):
        """
        Add the secret for the specified attribute to the cache.
        If the target specifies credentials_method: secrets, substitute the secret token into the model.
        :param model_path: text representation of the model path
        :param attribute_name: the name of the attribute or (property)
        :param validation_location: the model location
        """
        model_path_tokens = model_path.split('/')
        tokens_length = len(model_path_tokens)
        variable_name = variable_injector_functions.format_variable_name(
            validation_location, attribute_name, self._aliases)
        if tokens_length > 1:
            credentials_method = self.model_context.get_target_configuration(
            ).get_credentials_method()

            # by default, don't do any assignment to attribute
            model_value = None

            # use attribute name for admin password
            if model_path_tokens[0] == 'domainInfo:' and model_path_tokens[
                    1] == '':
                cache_key = attribute_name
            else:
                cache_key = variable_name

            # for normal secrets, assign the secret name to the attribute
            if credentials_method == SECRETS_METHOD:
                model_value = target_configuration_helper.format_as_secret_token(
                    cache_key)
                self.cache[cache_key] = ''

            # for config override secrets, assign a placeholder password to the attribute.
            # config overrides will be used to override the value in the target domain.
            if credentials_method == CONFIG_OVERRIDES_SECRETS_METHOD:
                model_value = PASSWORD_PLACEHOLDER
                self.cache[cache_key] = ''

            if model_value is not None:
                p_dict = self.current_dict
                for index in range(0, len(model_path_tokens)):
                    token = model_path_tokens[index]
                    if token == '':
                        break
                    if token[-1] == ':':
                        token = token[:-1]
                    p_dict = p_dict[token]

                p_dict[attribute_name] = model_value

    def walk(self):
        """
        Replace password attributes in each model file with secret tokens, and write each model.
        Generate a script to create the required secrets.
        Create any additional output specified for the target environment.
        """
        _method_name = "walk"

        model_file_name = None

        try:
            model_file_list = self.model_files.split(',')
            for model_file in model_file_list:
                self.cache.clear()
                if os.path.splitext(model_file)[1].lower() == ".yaml":
                    model_file_name = model_file
                    FileToPython(model_file_name, True).parse()

                aliases = Aliases(model_context=self.model_context,
                                  wlst_mode=WlstModes.OFFLINE)

                validator = Validator(self.model_context,
                                      aliases,
                                      wlst_mode=WlstModes.OFFLINE)

                # Just merge and validate but without substitution
                model_dictionary = cla_helper.merge_model_files(
                    model_file_name, None)

                variable_file = self.model_context.get_variable_file()
                if not os.path.exists(variable_file):
                    variable_file = None

                return_code = validator.validate_in_tool_mode(
                    model_dictionary,
                    variables_file_name=variable_file,
                    archive_file_name=None)

                if return_code == Validator.ReturnCode.STOP:
                    self._logger.severe('WLSDPLY-05705', model_file_name)
                    return VALIDATION_FAIL

                self.current_dict = model_dictionary

                self.__walk_model_section(
                    model.get_model_domain_info_key(), self.current_dict,
                    aliases.get_model_section_top_level_folder_names(
                        DOMAIN_INFO))

                self.__walk_model_section(
                    model.get_model_topology_key(), self.current_dict,
                    aliases.get_model_topology_top_level_folder_names())

                self.__walk_model_section(
                    model.get_model_resources_key(), self.current_dict,
                    aliases.get_model_resources_top_level_folder_names())

                self.current_dict = self._apply_filter_and_inject_variable(
                    self.current_dict, self.model_context, validator)

                file_name = os.path.join(self.output_dir,
                                         os.path.basename(model_file_name))
                fos = JFileOutputStream(file_name, False)
                writer = JPrintWriter(fos, True)
                pty = PythonToYaml(self.current_dict)
                pty._write_dictionary_to_yaml_file(self.current_dict, writer)
                writer.close()

            self.cache.clear()
            for key in self.secrets_to_generate:
                self.cache[key] = ''

            # use a merged, substituted, filtered model to get domain name and create additional target output.
            full_model_dictionary = cla_helper.load_model(
                _program_name, self.model_context, self._alias_helper,
                "discover", WlstModes.OFFLINE)

            target_configuration_helper.generate_k8s_script(
                self.model_context, self.cache, full_model_dictionary)

            # create any additional outputs from full model dictionary
            target_configuration_helper.create_additional_output(
                Model(full_model_dictionary), self.model_context,
                self._alias_helper, ExceptionType.VALIDATE)

        except ValidateException, te:
            self._logger.severe('WLSDPLY-20009',
                                _program_name,
                                model_file_name,
                                te.getLocalizedMessage(),
                                error=te,
                                class_name=_class_name,
                                method_name=_method_name)
            ex = exception_helper.create_compare_exception(
                te.getLocalizedMessage(), error=te)
            self._logger.throwing(ex,
                                  class_name=_class_name,
                                  method_name=_method_name)
            return VALIDATION_FAIL
        except VariableException, ve:
            self._logger.severe('WLSDPLY-20009',
                                _program_name,
                                model_file_name,
                                ve.getLocalizedMessage(),
                                error=ve,
                                class_name=_class_name,
                                method_name=_method_name)
            ex = exception_helper.create_compare_exception(
                ve.getLocalizedMessage(), error=ve)
            self._logger.throwing(ex,
                                  class_name=_class_name,
                                  method_name=_method_name)
            return VALIDATION_FAIL