bubble up an error code when something goes wrong with import/export

This commit is contained in:
Sarabraj Singh 2022-06-10 14:48:36 -04:00
parent 35a5f93182
commit babd6f0975
No known key found for this signature in database
GPG Key ID: DB2C5CAED943C5BE
2 changed files with 26 additions and 3 deletions

View File

@ -90,6 +90,7 @@ class ApiV2(base.Base):
return None
if post_fields is None: # Deprecated endpoint or insufficient permissions
log.error("Object export failed: %s", _page.endpoint)
self._has_error = True
return None
# Note: doing _page[key] automatically parses json blob strings, which can be a problem.
@ -110,6 +111,7 @@ class ApiV2(base.Base):
pass
if resource is None:
log.error("Unable to infer endpoint for %r on %s.", key, _page.endpoint)
self._has_error = True
continue
related = self._filtered_list(resource, _page.json[key]).results[0]
else:
@ -119,12 +121,14 @@ class ApiV2(base.Base):
if rel_endpoint is None: # This foreign key is unreadable
if post_fields[key].get('required'):
log.error("Foreign key %r export failed for object %s.", key, _page.endpoint)
self._has_error = True
return None
log.warning("Foreign key %r export failed for object %s, setting to null", key, _page.endpoint)
continue
rel_natural_key = rel_endpoint.get_natural_key(self._cache)
if rel_natural_key is None:
log.error("Unable to construct a natural key for foreign key %r of object %s.", key, _page.endpoint)
self._has_error = True
return None # This foreign key has unresolvable dependencies
fields[key] = rel_natural_key
@ -169,6 +173,7 @@ class ApiV2(base.Base):
natural_key = _page.get_natural_key(self._cache)
if natural_key is None:
log.error("Unable to construct a natural key for object %s.", _page.endpoint)
self._has_error = True
return None
fields['natural_key'] = natural_key
@ -260,6 +265,7 @@ class ApiV2(base.Base):
except (exc.Common, AssertionError) as e:
identifier = asset.get("name", None) or asset.get("username", None) or asset.get("hostname", None)
log.error(f"{endpoint} \"{identifier}\": {e}.")
self._has_error = True
log.debug("post_data: %r", post_data)
continue
@ -294,6 +300,7 @@ class ApiV2(base.Base):
pass
except exc.Common as e:
log.error("Role assignment failed: %s.", e)
self._has_error = True
log.debug("post_data: %r", {'id': role_page['id']})
def _assign_membership(self):
@ -324,17 +331,21 @@ class ApiV2(base.Base):
for item in related_set:
rel_page = self._cache.get_by_natural_key(item)
if rel_page is None:
continue # FIXME
log.error("Could not find matching object in Tower for imported relation, item: %r", item)
self._has_error = True
continue
if rel_page['id'] in existing:
continue
try:
post_data = {'id': rel_page['id']}
endpoint.post(post_data)
log.error("endpoint: %s, id: %s", endpoint.endpoint, rel_page['id'])
self._has_error = True
except exc.NoContent: # desired exception on successful (dis)association
pass
except exc.Common as e:
log.error("Object association failed: %s.", e)
self._has_error = True
log.debug("post_data: %r", post_data)
else: # It is a create set
self._cache.get_page(endpoint)

View File

@ -144,6 +144,8 @@ class Import(CustomCommand):
client.authenticate()
client.v2.import_assets(data)
self._has_error = getattr(client.v2, '_has_error', False)
return {}
@ -174,7 +176,11 @@ class Export(CustomCommand):
kwargs = {resource: getattr(parsed, resource, None) for resource in EXPORTABLE_RESOURCES}
client.authenticate()
return client.v2.export_assets(**kwargs)
data = client.v2.export_assets(**kwargs)
self._has_error = getattr(client.v2, '_has_error', False)
return data
def parse_resource(client, skip_deprecated=False):
@ -183,6 +189,8 @@ def parse_resource(client, skip_deprecated=False):
metavar='resource',
)
_system_exit = 0
# check if the user is running a custom command
for command in CustomCommand.__subclasses__():
client.subparsers[command.name] = subparsers.add_parser(command.name, help=command.help_text)
@ -210,6 +218,10 @@ def parse_resource(client, skip_deprecated=False):
parser = client.subparsers[resource]
command = CustomCommand.registry[resource]()
response = command.handle(client, parser)
if getattr(command, '_has_error', False):
_system_exit = 1
if response:
_filter = client.get_config('filter')
if resource == 'config' and client.get_config('format') == 'human':
@ -221,7 +233,7 @@ def parse_resource(client, skip_deprecated=False):
connection = None
formatted = format_response(Page.from_json(response, connection=connection), fmt=client.get_config('format'), filter=_filter)
print(formatted)
raise SystemExit()
raise SystemExit(_system_exit)
else:
return resource