From 7dbbd06f6f27ef37d39ae6873b676ac0e58229f0 Mon Sep 17 00:00:00 2001 From: richard_killen Date: Wed, 29 Jan 2025 18:42:33 +0000 Subject: [PATCH] Set production and secure modes before initial domain write --- .../main/python/wlsdeploy/aliases/aliases.py | 4 +- .../wlsdeploy/tool/create/domain_creator.py | 45 ++++++++++++++++++- .../tool/validate/create_content_validator.py | 16 ++++++- .../tool/validate/domain_info_validator.py | 18 +++++++- .../tool/validate/model_validator.py | 13 +++++- .../deploy/messages/wlsdeploy_rb.properties | 1 + 6 files changed, 90 insertions(+), 7 deletions(-) diff --git a/core/src/main/python/wlsdeploy/aliases/aliases.py b/core/src/main/python/wlsdeploy/aliases/aliases.py index fc882a63c9..96bfdf7031 100644 --- a/core/src/main/python/wlsdeploy/aliases/aliases.py +++ b/core/src/main/python/wlsdeploy/aliases/aliases.py @@ -1,5 +1,5 @@ """ -Copyright (c) 2017, 2024, Oracle and/or its affiliates. +Copyright (c) 2017, 2025, Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. """ import array @@ -535,7 +535,7 @@ def get_wlst_attribute_name_and_value(self, location, model_attribute_name, mode if attribute_info and not self.__is_wlst_attribute_read_only_or_ignored(location, attribute_info): wlst_attribute_name = attribute_info[WLST_NAME] uses_path_tokens = USES_PATH_TOKENS in attribute_info and \ - string_utils.to_boolean(attribute_info[USES_PATH_TOKENS]) + alias_utils.convert_boolean(attribute_info[USES_PATH_TOKENS]) data_type = attribute_info[WLST_TYPE] if data_type == 'password': diff --git a/core/src/main/python/wlsdeploy/tool/create/domain_creator.py b/core/src/main/python/wlsdeploy/tool/create/domain_creator.py index b88148c628..6b7a440719 100644 --- a/core/src/main/python/wlsdeploy/tool/create/domain_creator.py +++ b/core/src/main/python/wlsdeploy/tool/create/domain_creator.py @@ -1,5 +1,5 @@ """ -Copyright (c) 2017, 2024, Oracle and/or its affiliates. +Copyright (c) 2017, 2025, Oracle and/or its affiliates. Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. """ import os @@ -10,6 +10,7 @@ from weblogic.security.internal import SerializedSystemIni from weblogic.security.internal.encryption import ClearOrEncryptedService +from wlsdeploy.aliases import alias_utils from wlsdeploy.aliases.location_context import LocationContext from wlsdeploy.aliases.model_constants import ADMIN_PASSWORD from wlsdeploy.aliases.model_constants import ADMIN_SERVER_NAME @@ -36,6 +37,8 @@ from wlsdeploy.aliases.model_constants import PRODUCTION_MODE_ENABLED from wlsdeploy.aliases.model_constants import RESOURCE_GROUP from wlsdeploy.aliases.model_constants import RESOURCE_GROUP_TEMPLATE +from wlsdeploy.aliases.model_constants import SECURE_MODE +from wlsdeploy.aliases.model_constants import SECURE_MODE_ENABLED from wlsdeploy.aliases.model_constants import SECURITY from wlsdeploy.aliases.model_constants import SECURITY_CONFIGURATION from wlsdeploy.aliases.model_constants import SERVER @@ -551,6 +554,8 @@ def __set_core_domain_params(self): use_sample_db = str_helper.to_string(use_sample_db) self.wlst_helper.set_option_if_needed(USE_SAMPLE_DATABASE, use_sample_db) + self.__set_secure_and_production_modes() + self.__set_domain_name() self.__set_admin_password() self.__set_admin_server_name() @@ -946,6 +951,42 @@ def __set_admin_server_name(self): else: self._admin_server_name = self.__default_admin_server_name + def __set_secure_and_production_modes(self): + """ + Set secure and production mode enabled before initial writeDomain + """ + root_location = LocationContext() + domain_name_token = self.aliases.get_name_token(root_location) + root_location.add_name_token(domain_name_token, self._domain_name) + + production_mode_enabled = dictionary_utils.get_element(self._topology, PRODUCTION_MODE_ENABLED) + if production_mode_enabled is not None: + wlst_name = self.aliases.get_wlst_attribute_name(root_location, PRODUCTION_MODE_ENABLED) + production_mode_enabled = alias_utils.convert_boolean(production_mode_enabled) + self.wlst_helper.set(wlst_name, production_mode_enabled) + + if production_mode_enabled: # check for secure mode specified, may be disabled + security_config_folder = dictionary_utils.get_dictionary_element(self._topology, SECURITY_CONFIGURATION) + secure_mode_folder = dictionary_utils.get_dictionary_element(security_config_folder, SECURE_MODE) + secure_mode_enabled = dictionary_utils.get_element(secure_mode_folder, SECURE_MODE_ENABLED) + if secure_mode_enabled is not None: + secure_mode_enabled = alias_utils.convert_boolean(secure_mode_enabled) + secure_location = LocationContext(root_location) + secure_location.append_location(SECURITY_CONFIGURATION) + + # secure mode doesn't exist in older WLS versions + code, message = self.aliases.is_valid_model_folder_name(secure_location, SECURE_MODE) + if code == ValidationCodes.VALID: + existing_subfolder_names = deployer_utils.get_existing_object_list(secure_location, self.aliases) + deployer_utils.create_and_cd(secure_location, existing_subfolder_names, self.aliases) + secure_location.append_location(SECURE_MODE) + existing_subfolder_names = deployer_utils.get_existing_object_list(secure_location, self.aliases) + deployer_utils.create_and_cd(secure_location, existing_subfolder_names, self.aliases) + + wlst_name = self.aliases.get_wlst_attribute_name(secure_location, SECURE_MODE_ENABLED) + self.wlst_helper.set(wlst_name, secure_mode_enabled) + self.wlst_helper.cd('/') + def __set_domain_attributes(self): """ Set the Domain attributes @@ -989,7 +1030,7 @@ def __create_boot_dot_properties(self): return if PRODUCTION_MODE_ENABLED in self._topology: - if string_utils.to_boolean(self._topology[PRODUCTION_MODE_ENABLED]): + if alias_utils.convert_boolean(self._topology[PRODUCTION_MODE_ENABLED]): return system_ini = SerializedSystemIni.getEncryptionService(self._domain_home) diff --git a/core/src/main/python/wlsdeploy/tool/validate/create_content_validator.py b/core/src/main/python/wlsdeploy/tool/validate/create_content_validator.py index a2057bcbb0..6df2c9c2be 100644 --- a/core/src/main/python/wlsdeploy/tool/validate/create_content_validator.py +++ b/core/src/main/python/wlsdeploy/tool/validate/create_content_validator.py @@ -1,5 +1,5 @@ """ -Copyright (c) 2023, 2024, Oracle and/or its affiliates. +Copyright (c) 2023, 2025, Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. """ from java.lang import Boolean @@ -35,13 +35,16 @@ from wlsdeploy.aliases.model_constants import RCU_PREFIX from wlsdeploy.aliases.model_constants import RCU_SCHEMA_PASSWORD from wlsdeploy.aliases.model_constants import REALM +from wlsdeploy.aliases.model_constants import SECURE_MODE from wlsdeploy.aliases.model_constants import SECURITY from wlsdeploy.aliases.model_constants import SECURITY_CONFIGURATION +from wlsdeploy.aliases.model_constants import SERVER_START_MODE from wlsdeploy.aliases.model_constants import STORE_TYPE_SSO from wlsdeploy.aliases.model_constants import SYSTEM_PASSWORD_VALIDATOR from wlsdeploy.aliases.model_constants import TNS_ENTRY from wlsdeploy.aliases.model_constants import TOPOLOGY from wlsdeploy.aliases.model_constants import USER +from wlsdeploy.aliases.validation_codes import ValidationCodes from wlsdeploy.exception import exception_helper from wlsdeploy.logging.platform_logger import PlatformLogger from wlsdeploy.tool.create import rcudbinfo_helper @@ -98,6 +101,17 @@ def validate_domain_info_section(self, model_dict): self._model_context.get_model_file(), class_name=self._class_name, method_name=_method_name) domain_info_dict = dictionary_utils.get_dictionary_element(model_dict, DOMAIN_INFO) + + # secure mode doesn't exist in older WLS versions. + # valid start mode values were already checked in regular validation. + server_start_mode = dictionary_utils.get_element(domain_info_dict, SERVER_START_MODE) + if server_start_mode == 'secure': + secure_location = LocationContext().append_location(SECURITY_CONFIGURATION) + code, _message = self._aliases.is_valid_model_folder_name(secure_location, SECURE_MODE) + if code != ValidationCodes.VALID: + self._logger.severe('WLSDPLY-05314', server_start_mode, DOMAIN_INFO, SERVER_START_MODE, + class_name=self._class_name, method_name=_method_name) + rcu_info_dict = dictionary_utils.get_dictionary_element(domain_info_dict, RCU_DB_INFO) self.__validate_rcu_db_info_section(rcu_info_dict) diff --git a/core/src/main/python/wlsdeploy/tool/validate/domain_info_validator.py b/core/src/main/python/wlsdeploy/tool/validate/domain_info_validator.py index aa341201a1..6598134ccb 100644 --- a/core/src/main/python/wlsdeploy/tool/validate/domain_info_validator.py +++ b/core/src/main/python/wlsdeploy/tool/validate/domain_info_validator.py @@ -1,5 +1,5 @@ """ -Copyright (c) 2024, Oracle and/or its affiliates. +Copyright (c) 2024, 2025, Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. """ from oracle.weblogic.deploy.create import RCURunner @@ -23,6 +23,7 @@ from wlsdeploy.aliases.model_constants import RCU_TEMP_TBLSPACE from wlsdeploy.aliases.model_constants import REMOTE_RESOURCE from wlsdeploy.aliases.model_constants import SERVER_GROUP_TARGETING_LIMITS +from wlsdeploy.aliases.model_constants import SERVER_START_MODE from wlsdeploy.aliases.model_constants import STORE_TYPE_SSO from wlsdeploy.aliases.model_constants import WLS_POLICIES from wlsdeploy.aliases.model_constants import WLS_ROLES @@ -74,6 +75,12 @@ 't3s' ] +SERVER_START_MODES = [ + 'dev', + 'prod', + 'secure' +] + DEPRECATED_DB_TYPES = [ RCURunner.ORACLE_DB_TYPE, RCURunner.ORACLE_ATP_DB_TYPE, @@ -135,12 +142,21 @@ def _validate_attribute(self, attribute_name, attribute_value, valid_attr_infos, """ Extend this method to perform additional validation of the targeting limits attributes. """ + _method_name = "_validate_attribute" ModelValidator._validate_attribute(self, attribute_name, attribute_value, valid_attr_infos, path_tokens_attr_keys, model_folder_path, validation_location) if attribute_name in [SERVER_GROUP_TARGETING_LIMITS, DYNAMIC_CLUSTER_SERVER_GROUP_TARGETING_LIMITS]: self.__validate_server_group_targeting_limits(attribute_name, attribute_value, model_folder_path) + if attribute_name == SERVER_START_MODE: + # None is returned if tokens remain, already validated depending on validation mode + server_start_mode = self._resolve_value(attribute_value, SERVER_START_MODE) + if server_start_mode and (server_start_mode not in SERVER_START_MODES): + self._logger.severe( + 'WLSDPLY-05302', server_start_mode, DOMAIN_INFO, SERVER_START_MODE, + ', '.join(SERVER_START_MODES), class_name=_class_name, method_name=_method_name) + # Override def _validate_single_path_in_archive(self, path, attribute_name, model_folder_path): """ diff --git a/core/src/main/python/wlsdeploy/tool/validate/model_validator.py b/core/src/main/python/wlsdeploy/tool/validate/model_validator.py index f99b6bcff2..0f7c342636 100644 --- a/core/src/main/python/wlsdeploy/tool/validate/model_validator.py +++ b/core/src/main/python/wlsdeploy/tool/validate/model_validator.py @@ -1,5 +1,5 @@ """ -Copyright (c) 2017, 2024, Oracle and/or its affiliates. +Copyright (c) 2017, 2025, Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. """ @@ -627,6 +627,17 @@ def _get_validation_value(self, model_dict, attribute_name): :return: the value to use for additional validation checks """ value = dictionary_utils.get_element(model_dict, attribute_name) + return self._resolve_value(value, attribute_name) + + def _resolve_value(self, value, attribute_name): + """ + Get the resolved value of the specified attribute, de-tokenizing as needed. + If unresolved tokens remain in the value, None is returned to prevent further checks. + Validation has already checked for unresolved variables, depending on validation mode. + :param value: the value to be examined + :param attribute_name: the name of the attribute to be examined, for logging + :return: the value to use for additional validation checks + """ if isinstance(value, (str, unicode)) and variables.has_tokens(value): value = variables.substitute_attribute(value, self._variable_properties, self._model_context, attribute_name=attribute_name) diff --git a/core/src/main/resources/oracle/weblogic/deploy/messages/wlsdeploy_rb.properties b/core/src/main/resources/oracle/weblogic/deploy/messages/wlsdeploy_rb.properties index e5ba0476bd..984b59c163 100644 --- a/core/src/main/resources/oracle/weblogic/deploy/messages/wlsdeploy_rb.properties +++ b/core/src/main/resources/oracle/weblogic/deploy/messages/wlsdeploy_rb.properties @@ -689,6 +689,7 @@ WLSDPLY-05310={0} field {1} must be specified if {2} is specified WLSDPLY-05311=Prepended path {0} for {1} field {2} is an archive path, and no archive file is specified WLSDPLY-05312=Prepended path {0} for {1} field {2} is an archive path, and not found in any archive file WLSDPLY-05313=Value {0} is invalid for {1} {2} field {3}, must be one of {4} +WLSDPLY-05314=Value {0} is invalid for {1} field {2}, secure mode is not supported in this WLS version # oracle/weblogic/deploy/validate/PasswordValidator.java WLSDPLY-05400=Password validation failed because the username was not provided