Skip to content

Commit

Permalink
Merge pull request #106 from duplocloud/DUPLO-25413
Browse files Browse the repository at this point in the history
Duplo 25413
  • Loading branch information
duplocloud-matt authored Oct 9, 2024
2 parents c49ecd8 + fd5a1bd commit be35481
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Fixed handling of case in name/value keys in environment variables as backend permits both.
- Fixes issue in service update argument where strategy required three dashes.
- Gracefully handles situations where user attempts to merge with a service that has no existing env vars.

## [0.2.36] - 2024-09-25

### Fixed
Expand Down
51 changes: 45 additions & 6 deletions src/duplo_resource/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,26 +229,65 @@ def update_env(self,
```
Args:
name (str): The name of the service to update.
setvar/-V (list): A list of key value pairs to set as environment variables.
strategy/strat (str): The merge strategy to use for env vars. Valid options are "merge" or "replace". Default is merge.
deletevar/-D (list): A list of keys to delete from the environment variables.
"""
service = self.find(name)
# Returns an array of key and value mappings with provided keys
def new_env_vars(setvar, key_name="Name", value_name="Value"):
return [{key_name: i[0], value_name: i[1]} for i in setvar]

def detect_case_format(env_list):
# Check if the environment variables are using upper, lower, or mixed case for Name and Value
if all('Name' in env and 'Value' in env for env in env_list):
return "title"
elif all('name' in env and 'value' in env for env in env_list):
return "lower"
# No consistent standard
return "mixed"

service = self.find(name)
currentDockerconfig = loads(service["Template"]["OtherDockerConfig"])
currentEnv = currentDockerconfig.get("Env", [])
newEnv = []
if setvar is not None:
newEnv = [{"Name": i[0], "Value": i[1]} for i in setvar]
# Check if user is attempting to merge against a null Env. If so, set currentEnv to empty.
if currentEnv is None and strategy == "merge":
self.duplo.logger.warn("Specified \"merge\" strategy on a service with"
" no environment variables defined, should use "
" \"replace\". Proceeding anyway")
currentEnv = []
case_format = detect_case_format(currentEnv)
if strategy == 'merge':
d = {d['Name']: d for d in currentEnv + newEnv}
try:
if case_format == "title":
newEnv = new_env_vars(setvar) if setvar is not None else []
d = {env['Name']: env for env in currentEnv + newEnv}
elif case_format == "lower":
newEnv = new_env_vars(setvar, key_name="name", value_name="value") if setvar is not None else []
d = {env['name']: env for env in currentEnv + newEnv}
else:
self.duplo.logger.warn("Possible attempt to merge env vars with"
" inconsistent Name/Value key case."
" Normalzing to capitalized"
" \"Name\" and \"Value\"")
norm_currentEnv = [{k.capitalize(): v for k, v in env.items()} for env in currentEnv]
newEnv = new_env_vars(setvar,) if setvar is not None else []
d = {env['Name']: env for env in norm_currentEnv + newEnv}
except KeyError:
raise DuploError("Could not merge new and existing environment variables")
mergedvars = list(d.values())
currentDockerconfig['Env'] = mergedvars
else:
newEnv = new_env_vars(setvar) if setvar is not None else []
currentDockerconfig['Env'] = newEnv
if deletevar is not None:
for key in deletevar:
currentDockerconfig['Env'] = [d for d in currentDockerconfig['Env'] if d['Name'] != key]
try:
currentDockerconfig['Env'] = [d for d in currentDockerconfig['Env'] if d['Name'] != key]
except KeyError:
currentDockerconfig['Env'] = [d for d in currentDockerconfig['Env'] if d['name'] != key]
payload = {
"Name": name,
"OtherDockerConfig": dumps(currentDockerconfig),
Expand Down
2 changes: 1 addition & 1 deletion src/duplocloud/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
nargs=2,
metavar=('key', 'value'))

STRATEGY = Arg("-strategy", "-strat",
STRATEGY = Arg("strategy", "-strat",
help='The merge strategy to use for env vars. Valid options are \"merge\" or \"replace\". Default is merge.',
choices=['merge', 'replace'],
default = 'merge')
Expand Down

0 comments on commit be35481

Please sign in to comment.