def _do__cmd(self, target, action, exc, env=dict(), echo=False, doexec=False): """ Execute a sub process as part of a action, and handle the subsequent step if env=False, do not use the reflex environ settings, just the default os """ if not env: env = self.env # convert any ${vars} in exe list env_exc = [] for elem in exc: env_exc.append(self.sed_env(elem, {}, '', env=env)) # pull first arg from env{PATH} fqexc = self._executable(env_exc) if not fqexc: raise ValueError("Cannot execute: {}".format(exc[0])) extcfg = '' if action.get('config', "n/a") == "stdin" and self.extcfg: if isinstance(self.extcfg, str): extcfg = json4store(self.extcfg) else: # the App object exports a dictionary extcfg = json4store(self.extcfg.export()) if echo: formatted = [] for arg in fqexc: if ' ' in arg: formatted.append(json.dumps(arg)) else: formatted.append(arg) self.NOTIFY("Execute:\n\n\t" + " ".join(formatted) + "\n") self.DEBUG("command: " + str(fqexc)) self.notifyfd.flush() self.outputfd.flush() if doexec: # pylint: disable=inconsistent-return-statements # this is the end os.execv(fqexc[0], fqexc) else: proc = subprocess.Popen(fqexc, stdin=subprocess.PIPE, env=env) if extcfg: proc.stdin.write(extcfg.encode()) proc.stdin.close() proc.wait() if proc.returncode > 0: return self._do_failure(target, action, proc.returncode) return self._do_success(target, action)
def env_cli(self, argv, args, cli): """ Print bash friendly environment declarations. Intended to be used in a manner like: ```eval $(launch env name)``` """ name, argv = self.get_target(*argv) export = "export " if args.get('--noexport', False): export = "" try: self.launch_service_prep(name, commit=False) for key in sorted(self.launch_config.setenv): #_expanded: value = self.launch_config.setenv[key] if export: value = json4store(value) self.OUTPUT('{}{}={}'.format(export, key, value)) except rfx.NotFoundError: self.ABORT(traceback.format_exc(0))
def _get_content_ref(self, conf): ref = conf.content.ref if isinstance(ref, str): data = deep_get(conf, ref) elif isinstance(ref, list): self.DEPRECATE( "conf.content.ref should be a string in x.z.y notation.") data = _deep_get(conf, *ref) else: raise ValueError( "Unrecognized data type for conf.content.ref ({})".format( type(conf.content.ref))) if conf.content.get('type', 'text/plain') == 'application/json': if isinstance(data, dictlib.Obj): data = data.__original__() data = json4store(data) # pylint: disable=line-too-long return getattr(self, "_decode_" + conf.content.get('encoding', 'none'))( strio.StringIO(data))
def instance_ping(self, obj_target, obj_data): """special instance update ping""" path = "instance-ping/" + str(obj_target) return self._call(requests.put, path, data=json4store(obj_data))
def patch(self, obj_type, obj_target, obj_data): """session PATCH""" path = obj_type + "/" + str(obj_target) + "?merge=true" return self._call(requests.put, path, data=json4store(obj_data))
def update(self, obj_type, obj_target, obj_data): """session UPDATE""" path = obj_type + "/" + str(obj_target) return self._call(requests.put, path, data=json4store(obj_data))
def create(self, obj_type, obj_data): """session CREATE""" return self._call(requests.post, obj_type, data=json4store(obj_data))
def test_functional(schema, base, tester, baseurl, args): # schema.initialize(verbose=False, reset=True) tester.okcmp("REST Health Check", tester, tester.fcall, [requests.get, baseurl + "/health"], {}, # "X-Request-Id": "test-request-id1"}, r'Response \[204\]') tester.okcmp("Unauthorized", tester, tester.fcall, [requests.get, baseurl + "/config"], {}, # "X-Request-Id": "test-request-id2"}, r'Response \[401\]') user_attrs = abac.attrs_skeleton(token_nbr=100, token_name='master') tester.get_master_key() if not tester.okcmp("Authorized", tester, tester.rest_newauth, [requests.get, baseurl + "/token"], {}, r'Response \[200\]'): print("Cannot continue") sys.exit(1) samples = dictlib.Obj({ 'pipeline': { 'mcreate': { 'name': 'gallifrey', 'title': 'Prydonian Academy' }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { 'name': 'gallifrey' }, '-mcreate-expect': [r'Response \[400\]', r'message": "Pipeline named.*already exists'], 'mupdate': { 'name': 'gallifrey', 'title': 'College of Cardinals', 'id': 1 }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'title": "College of Cardinals'], 'mmerge': { 'name': 'gallifrey', 'launch': {'this': 'now'} }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'launch": {"this'] }, 'config': { 'mcreate': { 'type': 'parameter', 'name': 'tardis' }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { 'name': 'tardis' }, '-mcreate-expect': [r'Response \[400\]', r'message": "Object validate'], 'mupdate': { 'type': 'parameter', 'name': 'tardis', 'id': 1, 'exports': ["sonic"], }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'exports": \["sonic.notfound'], 'mmerge': { 'name': 'tardis', 'exports': ["screwdriver"], }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'exports": \["screwdriver.notfound'] }, 'service': { 'mcreate': { 'config': 'tardis', 'pipeline': 'gallifrey', 'stage': 'stage', 'region': 'arcadia', 'name': 'gallifrey-prd' }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { 'region': 'arcadia', 'name': 'gallifrey-prd' }, '-mcreate-expect': [r'Response \[400\]', r'message": "Object validate'], 'mupdate': { 'config': 'tardis', 'pipeline': 'gallifrey', 'stage': 'prd', 'region': 'arcadia', 'name': 'gallifrey-prd', 'id': 1 }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'stage": "prd'], 'mmerge': { 'name': 'gallifrey-prd', 'pipeline': "screwdriver", }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'pipeline": "screwdriver'] }, 'instance': { 'mcreate': { 'name': 'gallifrey-1', 'service': 'gallifrey-prd', 'status': 'ok', 'address': {} }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { 'name': 'gallifrey-1' }, '-mcreate-expect': [r'Response \[400\]', r'message": "Object validate'], 'mupdate': { 'name': 'gallifrey-1', 'id': 1, 'service': 'gallifrey-prd', 'status': 'failed', 'address': {} }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'status": "failed'], 'mmerge': { 'name': 'gallifrey-1', 'address': {'host': 'there'} }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'address": {"host": "there'] }, 'build': { 'mcreate': { 'name': 'gallifrey-1600', 'application': 'gallifrey', 'version': '1600', 'state': 'ready' }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { }, '-mcreate-expect': [r'Response \[400\]', r'message": "Object validate'], 'mupdate': { 'name': 'gallifrey-1600', 'id': 1, 'application': 'gallifrey', 'version': '1600', 'state': 'failed' }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'state": "failed'], 'mmerge': { 'name': 'gallifrey-1', 'status': {'starting': 'up'} }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'status": {"starting": "up'] }, 'state': { 'mcreate': { 'name': 'versions', 'application': 'gallifrey', 'version': '1600', 'state': 'ready' }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { }, '-mcreate-expect': [r'Response \[400\]', r'message": "Object validate'], 'mupdate': { 'name': 'versions', 'id': 1, 'application': 'gallifrey', 'version': '1600', 'state': 'failed' }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'state": "failed'], 'mmerge': { 'name': 'versions', 'status': {'starting': 'up'} }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'status": {"starting": "up'] }, 'apikey': { 'mcreate': { 'name': 'the-doctor', }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { 'id': 200, 'name': 'boo' }, '-mcreate-expect': [r'Response \[400\]', r'message": "id must be left undef'], 'mupdate': { 'name': 'the-doctor', 'id': 101, # hate using fixed #'s 'description': 'bow ties are cool' }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'description": "bow ties are cool'], 'mmerge': { 'name': 'the-doctor', 'description': 'who' }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'description": "who'] }, 'group': { 'mcreate': { 'name': 'timelords', 'type': 'Apikey', 'group': ['the-doctor'] }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { 'name': 'timelords2', 'id': 1, 'group': ['the-master'] }, '-mcreate-expect': [r'Response \[400\]', r'message": "Object validate'], 'mupdate': { 'name': 'timelords', 'type': 'Apikey', 'id': 1, 'group': ['the-master'] }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'group": \["the-master'], 'mmerge': { 'name': 'timelords', 'group': ['the-doctor', 'the-master'] }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'group": \["the', r'the-master.notfound', r'the-doctor.10'] }, 'policy': { 'mcreate': { 'name': 'timelords', 'policy': 'True' }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { 'name': 'tardises', 'policy': '! a tardis' }, '-mcreate-expect': [r'Response \[400\]', r'message": "Cannot prepare policy'], 'mupdate': { 'id': 101, # garr static values lame 'policy': 'False' }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'policy": "False'], 'mmerge': { 'name': 'timelords', 'description': 'do not trust the master' }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'description": "do not trust'] }, 'policyscope': { 'mcreate': { 'name': 'timelords', 'policy': 'timelords', 'actions': 'admin', 'type': 'targeted', 'objects': [], 'matches': 'True' }, 'mcreate-expect': [r'Response \[201\]'], '-mcreate': { 'name': 'tardises', 'policy': 'timelords', 'actions': 'bob', 'objects': [], 'type': 'targeted', 'matches': '! good' }, '-mcreate-expect': [r'Response \[400\]', r'message": "Cannot prepare match'], 'mupdate': { 'name': 'timelords', 'objects': [], 'policy': 'timelords', 'type': 'targeted', 'matches': 'False', 'actions': 'read, write, ADMIN' }, 'mupdate-expect': [r'status": "updated'], 'mupdate-validate': [r'matches": "False', r'actions": "admin"'], 'mmerge': { 'name': 'timelords', 'description': 'do not trust the master' }, 'mmerge-expect': [r'status": "updated'], 'mmerge-validate': [r'description": "do not trust'] } }) # order matters, otherwise I would use sample.keys() for obj in ('pipeline', 'config', 'service', 'instance', 'build', 'apikey', 'group', 'policy', 'policyscope', 'state'): odata = samples[obj].mcreate tester.okcmp("REST create " + obj, tester, tester.rest_useauth, [requests.post, baseurl + "/" + obj], {"data": json4store(samples[obj].mcreate), 'headers':{'Content-Type':'application/json', 'X-Request-Id': 'test-request-id1', }}, *samples[obj].mcreate_expect) tester.okcmp("REST create " + obj + " (w/failure)", tester, tester.rest_useauth, [requests.post, baseurl + "/" + obj], {"data": json4store(samples[obj]._mcreate), 'headers':{'Content-Type':'application/json'}}, *samples[obj]._mcreate_expect) name = odata.get('name', odata.get('id', "bork")) tester.okcmp("REST get " + obj, tester, tester.rest_useauth, [requests.get, baseurl + "/" + obj + "/" + name], {}, r'name": "' + name) tester.okcmp("REST get " + obj + " (w/failure)", tester, tester.rest_useauth, [requests.get, baseurl + "/" + obj + "/notfound"], {}, r'status": "failed', r'Response \[404\]', r'Unable to load') tester.okcmp("REST update " + obj, tester, tester.rest_useauth, [requests.put, baseurl + "/" + obj + "/" + name], {"data": json4store(samples[obj].mupdate), 'headers':{'Content-Type':'application/json'}}, *samples[obj].mupdate_expect) tester.okcmp("REST get " + obj, tester, tester.rest_useauth, [requests.get, baseurl + "/" + obj + "/" + name], {}, *samples[obj].mupdate_validate) tester.okcmp("REST update/merge " + obj, tester, tester.rest_useauth, [requests.put, baseurl + "/" + obj + "/" + name + "?merge=True"], {"data": json4store(samples[obj].mmerge), 'headers':{'Content-Type':'application/json'}}, *samples[obj].mmerge_expect) tester.okcmp("REST get " + obj, tester, tester.rest_useauth, [requests.get, baseurl + "/" + obj + "/" + name], {}, *samples[obj].mmerge_validate) tester.okcmp("REST delete " + obj, tester, tester.rest_useauth, [requests.delete, baseurl + "/" + obj + "/" + name], {}, r'status": "deleted') # recreate for others to reference tester.okcmp("REST create " + obj, tester, tester.rest_useauth, [requests.post, baseurl + "/" + obj], {"data": json4store(samples[obj].mcreate), 'headers':{'Content-Type':'application/json'}}, *samples[obj].mcreate_expect)
def __repr__(self): return json4store(self.export()) #, indent=2)
def __repr__(self): """Return a text representation of the object""" return json4store(self.conf)