def test_query(self, drvmock): cmduuid = 'someuuid' dnd = BetterDummyNodeDriver(1) drvmock.return_value = dnd # Get the existing instance id node = dnd.list_nodes()[0] instid = node.name cmd = Command(action='query', target=NewContextAWS(instance=instid)) # That a request to query a command response = self.test_client.get('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # Is successful self.assertEqual(response.status_code, 200) # and returns a valid OpenC2 response dcmd = _deseropenc2(response.data) # and matches the node state self.assertEqual(dcmd.status_text, node.state) # and has the same command id self.assertEqual(response.headers['X-Request-ID'], cmduuid) # that when the instance does not exist dnd.list_nodes()[0].destroy() # That a request to query a command the returns nothing response = self.test_client.get('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # Is successful self.assertEqual(response.status_code, 200) # and returns a valid OpenC2 response dcmd = _deseropenc2(response.data) # and that the status is 404 (instance not found) self.assertEqual(dcmd.status, 404) # and has the instance id self.assertEqual(dcmd.status_text, 'instance not found') # That when we post the same command as a get request response = self.test_client.post('/ec2', data=_seropenc2(cmd)) # that it fails self.assertEqual(response.status_code, 400)
def test_start(self, drvmock): cmduuid = 'someuuid' dnd = BetterDummyNodeDriver(1) drvmock.return_value = dnd # Get the existing instance id instid = dnd.list_nodes()[0].name node = dnd.list_nodes()[0] node.stop_node() self.assertEqual(node.state, NodeState.STOPPED) cmd = Command(action=START, target=NewContextAWS(instance=instid)) # That a request to start an instance response = self.test_client.post('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # Is successful self.assertEqual(response.status_code, 200) # and returns a valid OpenC2 response dcmd = _deseropenc2(response.data) # and has the same command id self.assertEqual(response.headers['X-Request-ID'], cmduuid) # and that the image was started self.assertEqual(node.state, NodeState.RUNNING) # That when we get the same command as a get request response = self.test_client.get('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # that it fails self.assertEqual(response.status_code, 400)
def test_cmdfailure(self): cmduuid = 'weoiud' ami = 'owiejp' failmsg = 'this is a failure message' cmd = Command(action=CREATE, target=NewContextAWS(image=ami)) oc2resp = OpenC2Response(status=500, status_text=failmsg) # that a constructed CommandFailure failure = CommandFailure(cmd, failmsg, cmduuid, 500) # when handled r = handle_commandfailure(failure) # has the correct status code self.assertEqual(r.status_code, 500) # has the correct mime-type self.assertEqual(r.content_type, 'application/openc2-rsp+json;version=1.0') # has the correct body self.assertEqual(r.data, _seropenc2(oc2resp).encode('utf-8')) # and the command id in the header self.assertEqual(r.headers['X-Request-ID'], cmduuid) # that a constructed CommandFailure failure = CommandFailure(cmd, failmsg, cmduuid, 500) # when handled r = handle_commandfailure(failure) # has the correct status code self.assertEqual(r.status_code, 500)
def ec2route(): app.logger.debug('received msg: %s' % repr(request.data)) try: cmdid = request.headers['X-Request-ID'] except KeyError: resp = make_response('missing X-Request-ID header'.encode('us-ascii'), 400) resp.charset = 'us-ascii' resp.mimetype = 'text/plain' return resp req = _deseropenc2(request.data) ncawsargs = {} status = 200 clddrv = get_clouddriver() try: if hasattr(req.target, 'instance'): inst = req.target.instance if request.method == 'POST' and req.action == CREATE: ami = req.target['image'] img = MagicMock() img.id = ami try: inst = req.target.instance except AttributeError: inst = next(nameiter) r = clddrv.create_node(image=img, name=inst, **createnodekwargs) inst = r.name app.logger.debug('started ami %s, instance id: %s' % (ami, inst)) res = inst ncawsargs['instance'] = inst elif request.method == 'POST' and req.action == START: get_node(inst).start() res = '' elif request.method == 'POST' and req.action == STOP: if not get_node(inst).stop_node(): raise RuntimeError('unable to stop instance: %s' % repr(inst)) res = '' elif request.method == 'POST' and req.action == DELETE: get_node(inst).destroy() res = '' elif request.method in ('GET', 'POST') and req.action == 'query': insts = [x for x in clddrv.list_nodes() if x.name == inst] if insts: res = str(insts[0].state) else: res = 'instance not found' status = 404 else: raise Exception('unhandled request') except Exception as e: app.logger.debug('generic failure: %s' % repr(e)) app.logger.debug(traceback.format_exc()) raise CommandFailure(req, repr(e), cmdid) if ncawsargs: kwargs = dict(results=NewContextAWS(**ncawsargs)) else: kwargs = {} resp = OpenC2Response(status=status, status_text=res, **kwargs) app.logger.debug('replied msg: %s' % repr(_seropenc2(resp))) resp = make_response(_seropenc2(resp)) # Copy over the command id from the request resp.headers['X-Request-ID'] = request.headers['X-Request-ID'] return resp
def test_stop(self, drvmock): cmduuid = 'someuuid' dnd = BetterDummyNodeDriver(1) drvmock.return_value = dnd # Get the existing instance id instid = dnd.list_nodes()[0].name node = dnd.list_nodes()[0] self.assertEqual(node.state, NodeState.RUNNING) cmd = Command(allow_custom=True, action=STOP, target=NewContextAWS(instance=instid)) # That a request to stop an instance response = self.test_client.post('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # Is successful self.assertEqual(response.status_code, 200) # and returns a valid OpenC2 response dcmd = _deseropenc2(response.data) # and has the same command id self.assertEqual(response.headers['X-Request-ID'], cmduuid) # and that the image was stopped self.assertEqual(node.state, NodeState.STOPPED) # That when we get the same command as a get request response = self.test_client.get('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # that it fails self.assertEqual(response.status_code, 400) with patch.object(dnd, 'stop_node') as sn: # that when a stop command cmd = Command(action=STOP, target=NewContextAWS(instance=instid)) # and it returns an error sn.return_value = False # That a request to stop an instance response = self.test_client.post('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # fails self.assertEqual(response.status_code, 400) # that it has a Response body resp = _deseropenc2(response.data) # that it is an ERR self.assertEqual(resp.status, 400) # that it references the correct command self.assertEqual(response.headers['X-Request-ID'], cmduuid)
def test_create(self, drvmock, nameiter): cmduuid = 'someuuid' ami = 'Ubuntu 9.10' instname = 'somename' # that the name is return by nameiter nameiter.__next__.return_value = instname cmd = Command(action=CREATE, target=NewContextAWS(image=ami)) # Note that 0, creates two nodes, not zero, so create one instead dnd = BetterDummyNodeDriver(1) dnd.list_nodes()[0].destroy() self.assertEqual(len(dnd.list_nodes()), 0) drvmock.return_value = dnd # That a request to create a command response = self.test_client.post('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # Is successful self.assertEqual(response.status_code, 200) # and returns a valid OpenC2 response dcmd = _deseropenc2(response.data) # that the status is correct self.assertEqual(dcmd.status, 200) # and that the image was run self.assertEqual(len(dnd.list_nodes()), 1) # and has the correct instance id node = dnd.list_nodes()[0] runinstid = node.name self.assertEqual(runinstid, instname) self.assertEqual(dcmd.results['instance'], runinstid) # and was launched w/ the correct size self.assertEqual(node.size.name, createnodekwargs['size']) # and has the same command id self.assertEqual(response.headers['X-Request-ID'], cmduuid) # clean up previously launched instance dnd.list_nodes()[0].destroy() # That a request to create a command w/ instance name instname = 'anotherinstancename' cmd = Command(action=CREATE, target=NewContextAWS(image=ami, instance=instname)) response = self.test_client.post('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # Is successful self.assertEqual(response.status_code, 200) # and returns a valid OpenC2 response dcmd = _deseropenc2(response.data) # that the status is correct self.assertEqual(dcmd.status, 200) # and that the image was run self.assertEqual(len(dnd.list_nodes()), 1) # and has the correct instance id node = dnd.list_nodes()[0] runinstid = node.name self.assertEqual(runinstid, instname) self.assertEqual(dcmd.results['instance'], runinstid) # That when we get the same command as a get request response = self.test_client.get('/ec2', data=_seropenc2(cmd), headers={'X-Request-ID': cmduuid}) # that it fails self.assertEqual(response.status_code, 400)