From 1f4821ad4340ffc2b5efe054360a65d1db049782 Mon Sep 17 00:00:00 2001 From: Timothy Johnson Date: Thu, 28 Sep 2023 16:15:24 -0400 Subject: [PATCH] WIP Update profile merging to match Node SDK Signed-off-by: Timothy Johnson --- .../zowe/core_for_zowe_sdk/config_file.py | 25 ++++-- .../zowe/core_for_zowe_sdk/profile_manager.py | 81 ++++++++----------- 2 files changed, 50 insertions(+), 56 deletions(-) diff --git a/src/core/zowe/core_for_zowe_sdk/config_file.py b/src/core/zowe/core_for_zowe_sdk/config_file.py index b9e01b3d..a2d47581 100644 --- a/src/core/zowe/core_for_zowe_sdk/config_file.py +++ b/src/core/zowe/core_for_zowe_sdk/config_file.py @@ -120,7 +120,14 @@ def init_from_file( setting filepath (or if not set, autodiscover the file) """ if self.filepath is None: - self.autodiscover_config_dir() + try: + self.autodiscover_config_dir() + except FileNotFoundError: + pass + + if self.filepath is None or not os.path.isfile(self.filepath): + warnings.warn(f"Config file does not exist at {self.filepath}") + return with open(self.filepath, encoding="UTF-8", mode="r") as fileobj: profile_jsonc = commentjson.load(fileobj) @@ -132,10 +139,9 @@ def init_from_file( if self.schema_property and validate_schema: self.validate_schema() - # loading secure props is done in load_profile_properties - # since we want to try loading secure properties only when - # we know that the profile has saved properties - # self.load_secure_props() + + CredentialManager.load_secure_props() + self.secure_props = CredentialManager.secure_props.get(self.filepath, {}) def validate_schema( self @@ -355,9 +361,7 @@ def load_profile_properties(self, profile_name: str) -> dict: # load secure props only if there are secure fields - if secure_fields: - CredentialManager.load_secure_props() - self.secure_props = CredentialManager.secure_props.get(self.filepath, {}) + if secure_fields and self.secure_props: # load properties with key as profile.{profile_name}.properties.{*} for (key, value) in self.secure_props.items(): if re.match( @@ -372,3 +376,8 @@ def load_profile_properties(self, profile_name: str) -> dict: # self._missing_secure_props.extend(secure_fields) return props + + def load_secure_properties(self, profile_name: str): + secure_props = {} + lst = profile_name.split(".") + diff --git a/src/core/zowe/core_for_zowe_sdk/profile_manager.py b/src/core/zowe/core_for_zowe_sdk/profile_manager.py index 2e8a4eec..23c6e695 100644 --- a/src/core/zowe/core_for_zowe_sdk/profile_manager.py +++ b/src/core/zowe/core_for_zowe_sdk/profile_manager.py @@ -162,7 +162,6 @@ def get_profile( cfg: ConfigFile, profile_name: Optional[str], profile_type: Optional[str], - config_type: Optional[str], validate_schema: Optional[bool] = True, ) -> Profile: """ @@ -232,7 +231,7 @@ def get_profile( ) except Exception as exc: warnings.warn( - f"Could not load {config_type} '{cfg.filename}' at '{cfg.filepath}'" + f"Could not load '{cfg.filename}' at '{cfg.filepath}'" f"because {type(exc).__name__}'{exc}'.", ConfigNotFoundWarning, ) @@ -273,58 +272,44 @@ def load( if not self._show_warnings: warnings.simplefilter("ignore") - config_layers = { - "Project User Config": self.project_user_config, - "Project Config": self.project_config, - "Global User Config": self.global_user_config, - "Global Config": self.global_config, - } profile_props: dict = {} - schema_path = None env_var: dict = {} - missing_secure_props = [] # track which secure props were not loaded - loaded_cfg: dict = {} - - for i, (config_type, cfg) in enumerate(config_layers.items()): - - profile_loaded = self.get_profile( - cfg, profile_name, profile_type, config_type, validate_schema - ) - # How about we update by iterating each layer and at last we will get the merged layer - # TODO Why don't user and password show up here for Project User Config? - # Probably need to update load_profile_properties method in config_file.py - if profile_loaded.name and not profile_name: - profile_name = ( - profile_loaded.name - ) # Define profile name that will be merged from other layers - profile_props = {**profile_loaded.data, **profile_props} - + defaults_merged: dict = {} + profiles_merged: dict = {} + cfg_name = None + + for cfg_layer in (self.project_user_config, self.project_config, self.global_user_config, self.global_config): + if cfg_layer.profiles is None: + cfg_layer.init_from_file(validate_schema) + if cfg_layer.defaults: + for name, value in cfg_layer.defaults.items(): + defaults_merged[name] = defaults_merged.get(name, value) + if not cfg_name and cfg_layer.name: + cfg_name = cfg_layer.name + + usrProject = self.project_user_config.profiles or {} + project = self.project_config.profiles or {} + project_temp = always_merger.merge(deepcopy(usrProject), project) + + usrGlobal = self.global_user_config.profiles or {} + glbal = self.global_config.profiles or {} + global_temp = always_merger.merge(deepcopy(usrGlobal), glbal) + + profiles_merged = project_temp + for name, value in global_temp.items(): + if name not in profiles_merged: + profiles_merged[name] = value + + cfg = ConfigFile(type="Merged Config", name=cfg_name, profiles=profiles_merged, defaults=defaults_merged) + profile_loaded = self.get_profile(cfg, profile_name, profile_type, validate_schema) + if profile_loaded: + profile_props = profile_loaded.data missing_secure_props.extend(profile_loaded.missing_secure_props) - - if i == 1 and profile_props: - break # Skip loading from global config if profile was found in project config - - usrProject = self.project_user_config.profiles - project = self.project_config.profiles - - # Creating copies of the usrProject and project objects - usrProjectCopy = deepcopy(usrProject) - projectCopy = deepcopy(project) - prjt = always_merger.merge(usrProject, project) - - usrGlobal = self.global_user_config.profiles - glbal = self.global_config.profiles - - # Creating copies of the usrGlobal and glbal objects - usrGlobalCopy = deepcopy(usrGlobal) - glbalCopy = deepcopy(glbal) - glbl = always_merger.merge(usrGlobal, glbal) - if override_with_env: - env_var = {**self.get_env(cfg)} + env_var = {**self.get_env(cfg)} if profile_type != BASE_PROFILE: profile_props = { @@ -343,7 +328,7 @@ def load( warnings.resetwarnings() - for k, v in profile_props.items(): + for k in profile_props.keys(): if k in env_var: profile_props[k] = env_var[k]