2121
2222 2. Cross-Environment Reference (Root Path):
2323 Syntax: `${staging.DEBUG}`
24- - Environment: Different environment (e.g., `dev `).
24+ - Environment: Different environment (e.g., `staging `).
2525 - Path: Root path (`/`) of the specified environment.
2626 - Secret Key: `DEBUG`
2727 - Description: References a secret named `DEBUG` in the root path of the `staging` environment.
4545"""
4646
4747
48+ def split_path_and_key (ref : str ) -> tuple :
49+ """
50+ Splits a reference string into path and key components.
51+
52+ Args:
53+ ref (str): The reference string to split.
54+
55+ Returns:
56+ tuple: A tuple containing the path and key.
57+ """
58+ last_slash_index = ref .rfind ("/" )
59+ if last_slash_index != - 1 :
60+ path = ref [:last_slash_index ]
61+ key_name = ref [last_slash_index + 1 :]
62+ else :
63+ path = "/"
64+ key_name = ref
65+
66+ # Ensure path starts with a slash
67+ if not path .startswith ("/" ):
68+ path = "/" + path
69+
70+ return path , key_name
71+
72+
4873def resolve_secret_reference (ref : str , secrets_dict : Dict [str , Dict [str , Dict [str , str ]]], phase : 'Phase' , current_application_name : str , current_env_name : str ) -> str :
4974 """
5075 Resolves a single secret reference to its actual value by fetching it from the specified environment.
@@ -55,50 +80,42 @@ def resolve_secret_reference(ref: str, secrets_dict: Dict[str, Dict[str, Dict[st
5580
5681 Args:
5782 ref (str): The secret reference string, which could be a local or cross-environment reference.
58- current_env_name ( str): The current environment name, used for resolving local references .
83+ secrets_dict (Dict[ str, Dict[str, Dict[str, str]]]): A dictionary containing known secrets .
5984 phase ('Phase'): An instance of the Phase class to fetch secrets.
85+ current_application_name (str): The name of the current application.
86+ current_env_name (str): The current environment name, used for resolving local references.
6087
6188 Returns:
62- str: The resolved secret value.
63-
64- Raises:
65- ValueError: If the current environment name is not provided, or the secret is not found.
89+ str: The resolved secret value or the original reference if not resolved.
6690 """
67-
6891 env_name = current_env_name
69- path = "/" # Default root path
92+ path = "/" # Default root path
7093 key_name = ref
7194
7295 # Parse the reference to identify environment, path, and secret key.
73- if "." in ref : # Cross-environment references, split by the first dot to get environment and the rest.
96+ if "." in ref : # Cross-environment references
7497 parts = ref .split ("." , 1 )
7598 env_name , rest = parts [0 ], parts [1 ]
76- last_slash_index = rest .rfind ("/" )
77- if last_slash_index != - 1 :
78- path = rest [:last_slash_index ]
79- key_name = rest [last_slash_index + 1 :]
80- else :
81- key_name = rest
82- elif "/" in ref : # Local reference with specified path
83- last_slash_index = ref .rfind ("/" )
84- path = ref [:last_slash_index ]
85- key_name = ref [last_slash_index + 1 :]
86-
87- # Adjust for leading slash in path if not present
88- if not path .startswith ("/" ):
89- path = "/" + path
99+ path , key_name = split_path_and_key (rest )
100+ else : # Local reference
101+ path , key_name = split_path_and_key (ref )
90102
91103 try :
92104 # Lookup with environment, path, and key
93- if env_name in secrets_dict and path in secrets_dict [env_name ] and key_name in secrets_dict [env_name ][path ]:
94- return secrets_dict [env_name ][path ][key_name ]
95- else :
96- # Handle fallback for cross-environment or missing secrets
97- if env_name != current_env_name :
98- fetched_secrets = phase .get (env_name = env_name , app_name = current_application_name , keys = [key_name ], path = path )
99- for secret in fetched_secrets :
100- if secret ["key" ] == key_name :
101- return secret ["value" ]
105+ if env_name in secrets_dict :
106+ # Try to find the secret in the exact path
107+ if path in secrets_dict [env_name ] and key_name in secrets_dict [env_name ][path ]:
108+ return secrets_dict [env_name ][path ][key_name ]
109+
110+ # For local references, try to find the secret in the root path only if the original path was root
111+ if env_name == current_env_name and path == "/" and '/' in secrets_dict [env_name ] and key_name in secrets_dict [env_name ]['/' ]:
112+ return secrets_dict [env_name ]['/' ][key_name ]
113+
114+ # If the secret is not found in secrets_dict, try to fetch it from Phase
115+ fetched_secrets = phase .get (env_name = env_name , app_name = current_application_name , keys = [key_name ], path = path )
116+ for secret in fetched_secrets :
117+ if secret ["key" ] == key_name :
118+ return secret ["value" ]
102119 except EnvironmentNotFoundException :
103120 pass
104121
@@ -116,14 +133,13 @@ def resolve_all_secrets(value: str, all_secrets: List[Dict[str, str]], phase: 'P
116133
117134 Args:
118135 value (str): The input string containing one or more secret references.
119- current_env_name ( str): The current environment name for resolving local references .
136+ all_secrets (List[Dict[ str, str]] ): A list of all known secrets .
120137 phase ('Phase'): An instance of the Phase class to fetch secrets.
138+ current_application_name (str): The name of the current application.
139+ current_env_name (str): The current environment name for resolving local references.
121140
122141 Returns:
123142 str: The input string with all secret references resolved to their actual values.
124-
125- Raises:
126- ValueError: If the current environment name is not provided.
127143 """
128144
129145 secrets_dict = {}
0 commit comments