Skip to content

Commit

Permalink
WIP Update profile merging to match Node SDK
Browse files Browse the repository at this point in the history
Signed-off-by: Timothy Johnson <[email protected]>
  • Loading branch information
t1m0thyj committed Sep 28, 2023
1 parent 41bbe7e commit 1f4821a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 56 deletions.
25 changes: 17 additions & 8 deletions src/core/zowe/core_for_zowe_sdk/config_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -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(".")

81 changes: 33 additions & 48 deletions src/core/zowe/core_for_zowe_sdk/profile_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
"""
Expand Down Expand Up @@ -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,
)
Expand Down Expand Up @@ -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 = {
Expand All @@ -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]

Expand Down

0 comments on commit 1f4821a

Please sign in to comment.