diff --git a/juju/client/facade.py b/juju/client/facade.py index 2fa16dcd..8211ee5b 100644 --- a/juju/client/facade.py +++ b/juju/client/facade.py @@ -661,6 +661,26 @@ async def rpc(self, msg): @classmethod def from_json(cls, data): + def _parse_nested_list_entry(expr, result_dict): + if isinstance(expr, str): + if '>' in expr or '>=' in expr: + # something like juju >= 2.9.31 + i = expr.index('>') + _key = expr[:i].strip() + _value = expr[i:].strip() + result_dict[_key] = _value + else: + # this is a simple entry + result_dict[expr] = '' + elif isinstance(expr, dict): + for _, v in expr.items(): + _parse_nested_list_entry(v, result_dict) + elif isinstance(expr, list): + for v in expr: + _parse_nested_list_entry(v, result_dict) + else: + raise TypeError(f"Unexpected type of entry in assumes expression: {expr}") + if isinstance(data, cls): return data if isinstance(data, str): @@ -680,16 +700,7 @@ def from_json(cls, data): # check: https://juju.is/docs/sdk/assumes # assumes are in the form of a list d = {} - for entry in data: - if '>' in entry or '>=' in entry: - # something like juju >= 2.9.31 - i = entry.index('>') - key = entry[:i].strip() - value = entry[i:].strip() - d[key] = value - else: - # this is a simple entry - d[entry] = '' + _parse_nested_list_entry(data, d) return cls(**d) return None diff --git a/juju/utils.py b/juju/utils.py index 86f49588..bc72be94 100644 --- a/juju/utils.py +++ b/juju/utils.py @@ -546,12 +546,13 @@ def should_upgrade_resource(available_resource, existing_resources): """ # should upgrade resource? res_name = available_resource.get('Name', available_resource.get('name')) - # no, if it's upload - if existing_resources[res_name].origin == 'upload': - return False - # no, if we already have it (and upstream doesn't have a newer res available) + # do we have it already? if res_name in existing_resources: + # no upgrade, if it's upload + if existing_resources[res_name].origin == 'upload': + return False + # no upgrade, if upstream doesn't have a newer revision of the resource available available_rev = available_resource.get('Revision', available_resource.get('revision', -1)) u_fields = existing_resources[res_name].unknown_fields existing_rev = u_fields.get('Revision', u_fields.get('revision', -1))