From a7fb5d20f093ec5e595a13581aee26371f18fb87 Mon Sep 17 00:00:00 2001 From: Nathan T Denny Date: Tue, 4 Jun 2024 09:48:14 -0400 Subject: [PATCH] changed yaml to ruamel.yaml for better block text output; changed SUCCESS, FAILED, CRASHED to have a default data object of None; guard rails CRASHED now includes report with traceback stack formatted. --- bin/bastion.py | 140 ++++++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 67 deletions(-) diff --git a/bin/bastion.py b/bin/bastion.py index 176cc8a..f03d483 100755 --- a/bin/bastion.py +++ b/bin/bastion.py @@ -4,9 +4,10 @@ import os import pathlib import logging -import json +import traceback -import yaml +from ruamel.yaml import YAML +from ruamel.yaml.scalarstring import PreservedScalarString logger = logging.getLogger() logging.basicConfig(level = logging.DEBUG) @@ -39,35 +40,35 @@ b. anchor (full) if drift >= policy """ -def SUCCESS(doc, obj): +def SUCCESS(doc, obj = None): return { 'reply': { 'status': '200', 'message': 'Ok' }, - 'body': doc, + 'report': doc, 'data': obj } -def FAILED(doc, obj): +def FAILED(doc, obj = None): return { 'reply': { 'status': '400', 'message': 'Bad Request' }, - 'body': doc, + 'report': doc, 'data': obj } -def CRASHED(doc, obj): +def CRASHED(doc, obj = None): return { 'reply': { 'status': '500', 'message': 'Internal Application Error (crash)' }, - 'body': doc, + 'report': doc, 'data': obj } @@ -128,17 +129,15 @@ def vault(self, name, site = None): def run(self): comargs = sys.argv[1:] comdex = dict(enumerate(sys.argv[1:])) - #verb = comargs.get(0, 'help') menu = [ ("help", self.do_help), - ("export zone assets", self.do_export_zone_assets), - ("export site list", self.do_export_site_list), - ("export asset manifest", self.do_export_asset_manifest), ("backup asset", self.do_backup_asset), ("update asset", self.do_update_asset), ("backup zone", self.do_backup_zone), - ("update zone", self.do_update_zone) + ("update zone", self.do_update_zone), + ("export zone assets", self.do_export_zone_assets), + ("list zone assets", self.do_list_zone_assets) ] action = self.do_help #-- default is to show the help. @@ -149,9 +148,13 @@ def run(self): try: answer = action(comargs, comdex) except Exception as err: - answer = CRASHED(str(err)) + tb = traceback.format_exception(err) + answer = CRASHED( ''.join(tb), tb ) - sys.stdout.write( yaml.dump(answer, default_flow_style = False) ) + yaml = YAML() + yaml.default_flow_style = False + answer['report'] = PreservedScalarString(answer['report']) + yaml.dump(answer, sys.stdout) if answer['reply']['status'][0] in ('1','2','3'): sys.exit(0) else: @@ -166,17 +169,25 @@ def do_help(self, comargs, comdex): #---------------------- #-- backup operations | #---------------------- + def do_backup_zone(self, zone): + raise NotImplementedError + + def do_update_zone(self, zone): + raise NotImplementedError + + def do_update_asset(self, comargs, comdex): + raise NotImplementedError + def do_backup_asset(self, comargs, comdex): """ backup asset {ARK} """ ark = ARK(comdex[2]) -# print(ark) site = self.site(ark.site) asset = site.asset(ark) vault = self.vault(asset.policy.vault) vault.provision(ark) - flag, stdout, stderr = vault.htar(asset) + flag, stdout, stderr = vault.push(asset) if flag: return SUCCESS(stdout, {'stdout': stdout}) else: @@ -196,59 +207,54 @@ def do_export_site_list(self, comargs, comdex): return SUCCESS(report) def do_export_zone_assets(self, comargs, comdex): - spec = comdex[3] - vname = comdex[4] - ark = ARK("[{}]".format(spec)) - vault = self.vault(vname) - zone = ark.zone - assets = vault.assets(ark.site, ark.zone) - report = { - 'vault': vname, - 'site': ark.site, - 'zone': ark.zone, - 'assets': list(assets) - } - return SUCCESS(report) + """ + export zone assets {ark} + """ + spec = comdex[3] + ark = ARK(spec) + site = self.site( ark.site ) + zone = site.zone( ark.zone ) + assets = { } + for asset in zone.assets: + assets[asset.name] = {'ARK': str(asset.ARK), 'badge': asset.badge} - def do_export_asset_manifest(self, comargs, comdex): - raise NotImplementedError + manifest = "\n".join(["* {}".format(asset.name) for asset in zone.assets]) + report = """ +# {site} +## {zone} +{assets} + """.format(site = ark.site, zone = ark.zone, assets = manifest) + + return SUCCESS(report.strip(), assets) + + def do_list_zone_assets(self, comargs, comdex): + return self.do_export_zone_assets(comargs, comdex) if __name__ == '__main__': app = App().configured() - app.run( ) - #comdex = dict(enumerate(sys.argv[1:])) - #rusina = app.site('rusina') - #fortress = app.vault('fortress', rusina) - #ark = ARK(comdex[2]) - #ds = rusina.asset(ark) - #fortress.provision(ark) - - -#bastion site {site} backup -#bastion zone {zone} backup -#bastion manifest {zone} -#bastion backups tidy idifhub -#bastion backups update idifhub -#bastion backups catalog idifhub -#bastion keytab refresh fortress -#bastion zone { } restore -#bastion asset { } restore -#bastion asset { } backup -#bastion zone { } backup - -#bastion restore asset { } -#bastion restore zone { } -#bastion backup asset { } -#bastion backup zone { } -#bastion update asset { } -#bastion update zone { } -#bastion export zone assets { } -#bastion export asset manifest { } -#bastion export site list - -#bastion export asset manifest @idifhub:LiDAR/QL2023_IN_18 {fortress} -#bastion export site list {fortress} -#bastion export zone assets @idifhub:LiDAR {fortress} -#bastion backup asset [@idifhub:LiDAR/QL2023_IN_18] + if sys.argv[1] != 'shell': + app.run( ) + +#bastion backup site {site} +#bastion backup zone {ark} +#bastion backup asset {ark} + +#bastion update site {site} +#bastion update zone {ark} +#bastion update asset {ark} + +#bastion refresh keytab {vault} + +#bastion restore zone {ark} +#bastion restore asset {ark} +#bastion restore site {site} + +#bastion [list|export] zone assets {ark} +#bastion [list|export] site assets {ark} +#bastion [list|export] zones {site} +#bastion [list|export] sites + +#bastion [list|export] anchors {ark} +#bastion [list|export] snaps {ark}