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 ec2route(): app.logger.debug('received msg: %s' % ` request.data `) req = _deseropenc2(request.data) try: if request.method == 'POST' and req.action == CREATE: ami = req.modifiers['image'] r = get_bec2().run_instances(ImageId=ami, MinCount=1, MaxCount=1) inst = r['Instances'][0]['InstanceId'] app.logger.debug('started ami %s, instance id: %s' % (ami, inst)) res = inst elif request.method == 'POST' and req.action == START: r = get_bec2().start_instances( InstanceIds=[req.modifiers['instance']]) res = '' elif request.method == 'POST' and req.action == STOP: r = get_bec2().stop_instances( InstanceIds=[req.modifiers['instance']]) res = '' elif request.method == 'POST' and req.action == DELETE: r = get_bec2().terminate_instances( InstanceIds=[req.modifiers['instance']]) res = '' elif request.method == 'GET' and req.action == 'query': r = get_bec2().describe_instances( InstanceIds=[req.modifiers['instance']]) insts = r['Reservations'] if insts: res = insts[0]['Instances'][0]['State']['Name'] else: res = 'instance not found' else: raise Exception('unhandled request') except botocore.exceptions.ClientError as e: app.logger.debug('operation failed: %s' % ` e `) raise CommandFailure(req, ` e `) except Exception as e: app.logger.debug('generic failure: %s' % ` e `) app.logger.debug(traceback.format_exc()) raise CommandFailure(req, ` e `) resp = OpenC2Response(source=ec2target, status='OK', results=res, cmdref=req.modifiers['command_id']) return _seropenc2(resp)
def test_create(self, bec2): cmduuid = 'someuuid' instid = 'sdkj' ami = 'bogusimage' cmd = OpenC2Command(action=CREATE, target=ec2target, modifiers={ 'image': ami, 'command_id': cmduuid }) bec2().run_instances.return_value = { 'Instances': [{ 'InstanceId': instid, }] } # That a request to create a command response = self.test_client.post('/ec2', data=_seropenc2(cmd)) # 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, 'OK') # and has the instance id self.assertEqual(dcmd.results, instid) # and has the same command id self.assertEqual(dcmd.cmdref, cmduuid) # and that the image was run bec2().run_instances.assert_called_once_with(ImageId=ami, MinCount=1, MaxCount=1) # That when we get the same command as a get request response = self.test_client.get('/ec2', data=_seropenc2(cmd)) # that it fails self.assertEqual(response.status_code, 400)
def test_delete(self, bec2): #terminate_instances cmduuid = 'someuuid' instid = 'sdkj' cmd = OpenC2Command(action=DELETE, target=ec2target, modifiers={ 'instance': instid, 'command_id': cmduuid }) bec2().terminate_instances.return_value = { 'TerminatingInstances': [{ 'InstanceId': instid, }] } # That a request to create a command response = self.test_client.post('/ec2', data=_seropenc2(cmd)) # 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(dcmd.cmdref, cmduuid) # and that the image was terminated bec2().terminate_instances.assert_called_once_with( InstanceIds=[instid]) # That when we get the same command as a get request response = self.test_client.get('/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 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)
def test_stop(self, bec2): cmduuid = 'someuuid' instid = 'sdkj' cmd = OpenC2Command(action=STOP, target=ec2target, modifiers={ 'instance': instid, 'command_id': cmduuid }) bec2().stop_instances.return_value = { 'StoppingInstances': [{ 'InstanceId': instid, }] } # That a request to stop an instance response = self.test_client.post('/ec2', data=_seropenc2(cmd)) # 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(dcmd.cmdref, cmduuid) # and that the image was stopped bec2().stop_instances.assert_called_once_with(InstanceIds=[instid]) # That when we get the same command as a get request response = self.test_client.get('/ec2', data=_seropenc2(cmd)) # that it fails self.assertEqual(response.status_code, 400) # that when a stop command cmd = OpenC2Command(action=STOP, target=ec2target, modifiers={ 'instance': instid, 'command_id': cmduuid }) # and AWS returns an error bec2().stop_instances.side_effect = \ botocore.exceptions.ClientError({}, 'stop_instances') # That a request to stop an instance response = self.test_client.post('/ec2', data=_seropenc2(cmd)) # fails self.assertEqual(response.status_code, 400) # that it has a OpenC2Response body resp = _deseropenc2(response.data) # that it is an ERR self.assertEqual(resp.status, 'ERR') # that it references the correct command self.assertEqual(resp.cmdref, cmduuid)
def test_query(self, bec2): cmduuid = 'someuuid' instid = 'sdkj' cmd = OpenC2Command(action='query', target=ec2target, modifiers={ 'instance': instid, 'command_id': cmduuid }) inststate = 'pending' instdesc = { 'InstanceId': instid, 'some': 'other', 'data': 'included', 'State': { 'Code': 38732, 'Name': 'pending', } } bec2().describe_instances.return_value = { 'Reservations': [{ 'Instances': [instdesc], }] } # That a request to query a command response = self.test_client.get('/ec2', data=_seropenc2(cmd)) # Is successful self.assertEqual(response.status_code, 200) # and returns a valid OpenC2 response dcmd = _deseropenc2(response.data) # and has the instance id self.assertEqual(dcmd.results, inststate) # and has the same command id self.assertEqual(dcmd.cmdref, cmduuid) # and that the image was run bec2().describe_instances.assert_called_once_with(InstanceIds=[instid]) bec2().describe_instances.return_value = { 'Reservations': [], } # That a request to query a command the returns nothing response = self.test_client.get('/ec2', data=_seropenc2(cmd)) # and returns a valid OpenC2 response dcmd = _deseropenc2(response.data) # and has the instance id self.assertEqual(dcmd.results, '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)