def startMachines(self, params, block=False): ''' This method instantiates ec2 instances ''' logging.info("startMachines : inside method with params : %s", str(params)) try: #make sure that any keynames we use are prefixed with stochss so that #we can do a terminate all based on keyname prefix key_name = params["keyname"] if not key_name.startswith(self.KEYPREFIX): params['keyname'] = self.KEYPREFIX + key_name # NOTE: We are forcing blocking mode within the InfrastructureManager class # for the launching of VMs because of how GAE joins on all threads before # returning a response from a request. i = InfrastructureManager(blocking=block) res = {} # NOTE: We need to make sure that the RabbitMQ server is running if any compute # nodes are running as we are using the AMQP broker option for Celery. compute_check_params = { "credentials": params["credentials"], "key_prefix": params["key_prefix"] } if self.isQueueHeadRunning(compute_check_params): res = i.run_instances(params,[]) else: # Need to start the queue head (RabbitMQ) params["queue_head"] = True vms_requested = int(params["num_vms"]) requested_key_name = params["keyname"] # Only want one queue head, and it must have its own key so # it can be differentiated if necessary params["num_vms"] = 1 params["keyname"] = requested_key_name+'-'+self.QUEUEHEAD_KEY_TAG res = i.run_instances(params,[]) #NOTE: This relies on the InfrastructureManager being run in blocking mode... queue_head_ip = res["vm_info"]["public_ips"][0] self.__update_celery_config_with_queue_head_ip(queue_head_ip) params["keyname"] = requested_key_name params["queue_head"] = False if vms_requested > 1: params["num_vms"] = vms_requested - 1 res = i.run_instances(params,[]) params["num_vms"] = vms_requested logging.info("startMachines : exiting method with result : %s", str(res)) return res except Exception, e: logging.error("startMachines : exiting method with error : {0}".format(str(e))) print "startMachines : exiting method with error :", str(e) return None
def test_ec2_run_instances(self): i = InfrastructureManager(blocking=True) # first, validate that the run_instances call goes through successfully # and gives the user a reservation id full_params = { 'credentials': {'a': 'b', 'EC2_URL': 'http://testing.appscale.com:8773/foo/bar', 'EC2_ACCESS_KEY': 'access_key', 'EC2_SECRET_KEY': 'secret_key'}, 'group': 'boogroup', 'image_id': 'booid', 'infrastructure': 'ec2', 'instance_type': 'booinstance_type', 'keyname': 'bookeyname', 'num_vms': '1', 'use_spot_instances': 'True', 'max_spot_price' : '1.23', 'zone' : 'my-zone-1b' } id = '0000000000' # no longer randomly generated full_result = { 'success': True, 'reservation_id': id, 'reason': 'none' } self.assertEquals(full_result, i.run_instances(full_params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its reservation info self.assertEquals(InfrastructureManager.STATE_RUNNING, i.reservations.get(id)['state']) vm_info = i.reservations.get(id)['vm_info'] self.assertEquals(['public-ip'], vm_info['public_ips']) self.assertEquals(['private-ip'], vm_info['private_ips']) self.assertEquals(['i-id'], vm_info['instance_ids'])
def run_instances(self, prefix, blocking, success=True): i = InfrastructureManager(blocking=blocking) reservation = Reservation() instance = flexmock(name='instance', private_dns_name='private-ip', public_dns_name='public-ip', id='i-id', state='running', key_name='bookeyname', ip_address='public-ip', private_ip_address='private-ip') new_instance = flexmock(name='new-instance', private_dns_name='new-private-ip', public_dns_name='new-public-ip', id='new-i-id', state='running', key_name='bookeyname', ip_address='new-public-ip', private_ip_address='new-private-ip') reservation.instances = [instance] new_reservation = Reservation() new_reservation.instances = [instance, new_instance] self.fake_ec2.should_receive('get_all_instances').and_return([]) \ .and_return([reservation]).and_return([new_reservation]) # first, validate that the run_instances call goes through successfully # and gives the user a reservation id full_params = { 'credentials': { 'a': 'b', 'EC2_URL': 'http://testing.appscale.com:8773/foo/bar', 'EC2_ACCESS_KEY': 'access_key', 'EC2_SECRET_KEY': 'secret_key'}, 'group': 'boogroup', 'image_id': 'booid', 'infrastructure': prefix, 'instance_type': 'booinstance_type', 'keyname': 'bookeyname', 'num_vms': '1', 'use_spot_instances': False, 'region' : 'my-zone-1', 'zone' : 'my-zone-1b', 'autoscale_agent': True } id = '0000000000' # no longer randomly generated full_result = { 'success': True, 'reservation_id': id, 'reason': 'none' } if success: self.assertEquals(full_result, i.run_instances(full_params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its reservation info if not blocking: time.sleep(.1) if success: self.assertEquals(InfrastructureManager.STATE_RUNNING, i.reservations.get(id)['state']) vm_info = i.reservations.get(id)['vm_info'] self.assertEquals(['new-public-ip'], vm_info['public_ips']) self.assertEquals(['new-private-ip'], vm_info['private_ips']) self.assertEquals(['new-i-id'], vm_info['instance_ids']) else: if blocking: self.assertRaises(AgentRuntimeException, i.run_instances, full_params, 'secret')
def test_euca_run_instances(self): i = InfrastructureManager(blocking=True) # first, validate that the run_instances call goes through successfully # and gives the user a reservation id full_params = { 'credentials': { 'a': 'b', 'EC2_URL': 'http://testing.appscale.com:8773/foo/bar', 'EC2_ACCESS_KEY': 'access_key', 'EC2_SECRET_KEY': 'secret_key' }, 'group': 'boogroup', 'image_id': 'booid', 'infrastructure': 'euca', 'instance_type': 'booinstance_type', 'keyname': 'bookeyname', 'num_vms': '2', 'use_spot_instances': False, } id = '0000000000' # no longer randomly generated full_result = {'success': True, 'reservation_id': id, 'reason': 'none'} self.assertEquals(full_result, i.run_instances(full_params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its reservation info self.assertEquals(InfrastructureManager.STATE_RUNNING, i.reservations.get(id)['state']) vm_info = i.reservations.get(id)['vm_info'] self.assertEquals(['ABC-public-ip1', 'DEF-public-ip2'], vm_info['public_ips']) self.assertEquals(['DEF-private-ip1', 'ABC-private-ip2'], vm_info['private_ips']) self.assertEquals(['i-id1', 'i-id2'], vm_info['instance_ids'])
def test_euca_run_instances(self): i = InfrastructureManager(blocking=True) reservation = Reservation() instance = flexmock(name='instance', private_dns_name='private-ip', public_dns_name='public-ip', id='i-id', state='running', key_name='bookeyname', ip_address='public-ip', private_ip_address='private-ip') new_instance = flexmock(name='new-instance', private_dns_name='new-private-ip', public_dns_name='new-public-ip', id='new-i-id', state='running', key_name='bookeyname', ip_address='new-public-ip', private_ip_address='new-private-ip') reservation.instances = [instance] new_reservation = Reservation() new_reservation.instances = [instance, new_instance] flexmock(EC2Connection).should_receive('get_all_instances').and_return([]) \ .and_return([reservation]).and_return([reservation]) \ .and_return([new_reservation]).and_return([new_reservation]) # first, validate that the run_instances call goes through successfully # and gives the user an operation id full_params = { 'credentials': { 'a': 'b', 'EC2_URL': 'http://testing.appscale.com:8773/foo/bar', 'EC2_ACCESS_KEY': 'access_key', 'EC2_SECRET_KEY': 'secret_key' }, 'group': 'boogroup', 'image_id': 'booid', 'infrastructure': 'euca', 'instance_type': 'booinstance_type', 'keyname': 'bookeyname', 'num_vms': '1', 'use_spot_instances': False, 'zone': 'my-zone-1b', 'autoscale_agent': True, 'IS_VERBOSE': True } id = '0000000000' # no longer randomly generated full_result = {'success': True, 'operation_id': id, 'reason': 'none'} self.assertEquals(full_result, i.run_instances(full_params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its operation info self.assertEquals(InfrastructureManager.STATE_SUCCESS, i.operation_ids.get(id)['state']) vm_info = i.operation_ids.get(id)['vm_info'] self.assertEquals(['new-public-ip'], vm_info['public_ips']) self.assertEquals(['new-private-ip'], vm_info['private_ips']) self.assertEquals(['new-i-id'], vm_info['instance_ids'])
def startMachines(self, params): ''' This method instantiates ec2 instances ''' #this will basically start an instance in ec2 # add call from the infrastructure manager here logging.info("startMachines : inside method with params : %s", str(params)) try: i = InfrastructureManager(blocking=True) res = i.run_instances(params,params) return res logging.info("startMachines : exiting method with result : %s", str(res)) except Exception, e: logging.error("startMachines : exiting method with error : %s", str(e)) return None
def run_instances(self, prefix, blocking, success=True): i = InfrastructureManager(blocking=blocking) # first, validate that the run_instances call goes through successfully # and gives the user a reservation id full_params = { 'credentials': { 'a': 'b', 'EC2_URL': 'http://testing.appscale.com:8773/foo/bar', 'EC2_ACCESS_KEY': 'access_key', 'EC2_SECRET_KEY': 'secret_key'}, 'group': 'boogroup', 'image_id': 'booid', 'infrastructure': prefix, 'instance_type': 'booinstance_type', 'keyname': 'bookeyname', 'num_vms': '1', 'use_spot_instances': False, 'region' : 'my-zone-1', 'zone' : 'my-zone-1b' } id = '0000000000' # no longer randomly generated full_result = { 'success': True, 'reservation_id': id, 'reason': 'none' } self.assertEquals(full_result, i.run_instances(full_params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its reservation info if not blocking: time.sleep(.1) if success: self.assertEquals(InfrastructureManager.STATE_RUNNING, i.reservations.get(id)['state']) vm_info = i.reservations.get(id)['vm_info'] self.assertEquals(['public-ip'], vm_info['public_ips']) self.assertEquals(['private-ip'], vm_info['private_ips']) self.assertEquals(['i-id'], vm_info['instance_ids']) else: self.assertEquals(InfrastructureManager.STATE_FAILED, i.reservations.get(id)['state'])
def startMachines(self, params, block=False): """ This method instantiates ec2 instances """ logging.info("startMachines : inside method with params : %s", str(params)) try: keyname = params["keyname"] # make sure that any keynames we use are prefixed with stochss so that # we can do a terminate all based on keyname prefix if not keyname.startswith(backendservices.KEYPREFIX): params["keyname"] = backendservices.KEYPREFIX + keyname # NOTE: We are forcing blocking mode within the InfrastructureManager class # for the launching of VMs because of how GAE joins on all threads before # returning a response from a request. i = InfrastructureManager(blocking=block) res = i.run_instances(params, []) logging.info("startMachines : exiting method with result : %s", str(res)) return res except Exception, e: logging.error("startMachines : exiting method with error : %s", str(e)) return None
def run_instances(self, prefix, blocking, success=True): i = InfrastructureManager(blocking=blocking) # first, validate that the run_instances call goes through successfully # and gives the user a reservation id full_params = { 'credentials': {'a': 'b', 'EC2_URL': 'http://testing.appscale.com:8773/foo/bar', 'EC2_ACCESS_KEY': 'access_key', 'EC2_SECRET_KEY': 'secret_key'}, 'group': 'boogroup', 'image_id': 'booid', 'infrastructure': prefix, 'instance_type': 'booinstance_type', 'keyname': 'bookeyname', 'num_vms': '1', 'spot': 'False', } id = '0000000000' # no longer randomly generated full_result = { 'success': True, 'reservation_id': id, 'reason': 'none' } self.assertEquals(full_result, i.run_instances(full_params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its reservation info if not blocking: time.sleep(2) if success: self.assertEquals(InfrastructureManager.STATE_RUNNING, i.reservations.get(id)['state']) vm_info = i.reservations.get(id)['vm_info'] self.assertEquals(['public-ip'], vm_info['public_ips']) self.assertEquals(['private-ip'], vm_info['private_ips']) self.assertEquals(['i-id'], vm_info['instance_ids']) else: self.assertEquals(InfrastructureManager.STATE_FAILED, i.reservations.get(id)['state'])
def test_ec2_run_instances(self): i = InfrastructureManager(blocking=True) # first, validate that the run_instances call goes through successfully # and gives the user an operation id full_params = { 'credentials': { 'a': 'b', 'EC2_URL': 'http://testing.appscale.com:8773/foo/bar', 'EC2_ACCESS_KEY': 'access_key', 'EC2_SECRET_KEY': 'secret_key' }, 'group': 'boogroup', 'image_id': 'booid', 'infrastructure': 'ec2', 'instance_type': 'booinstance_type', 'keyname': 'bookeyname', 'num_vms': '1', 'use_spot_instances': 'True', 'max_spot_price': '1.23', 'region': 'my-zone-1', 'zone': 'my-zone-1b', 'autoscale_agent': True } id = '0000000000' # no longer randomly generated full_result = {'success': True, 'operation_id': id, 'reason': 'none'} self.assertEquals(full_result, i.run_instances(full_params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its operation info self.assertEquals(InfrastructureManager.STATE_SUCCESS, i.operation_ids.get(id)['state']) vm_info = i.operation_ids.get(id)['vm_info'] self.assertEquals(['new-public-ip'], vm_info['public_ips']) self.assertEquals(['new-private-ip'], vm_info['private_ips']) self.assertEquals(['new-i-id'], vm_info['instance_ids'])
def test_gce_run_instances(self): # mock out interactions with GCE # first, mock out the oauth library calls fake_credentials = flexmock(name='fake_credentials') fake_credentials.should_receive('invalid').and_return(False) fake_storage = flexmock(name='fake_storage') fake_storage.should_receive('get').and_return(fake_credentials) flexmock(oauth2client.file) oauth2client.file.should_receive('Storage').with_args( GCEAgent.OAUTH2_STORAGE_LOCATION).and_return(fake_storage) # next, mock out http calls to GCE fake_http = flexmock(name='fake_http') fake_authorized_http = flexmock(name='fake_authorized_http') flexmock(httplib2) httplib2.should_receive('Http').and_return(fake_http) fake_credentials.should_receive('authorize').with_args(fake_http) \ .and_return(fake_authorized_http) # add some fake data in where no instances are initially running, then one # is (in response to our insert request) no_instance_info = { } instance_id = u'appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d' list_instance_info = { u'items': [{ u'status': u'RUNNING', u'kind': u'compute#instance', u'machineType': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/machineTypes/n1-standard-1', u'name': instance_id, u'zone': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b', u'tags': {u'fingerprint': u'42WmSpB8rSM='}, u'image': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/images/lucid64', u'disks': [{ u'index': 0, u'kind': u'compute#attachedDisk', u'type': u'EPHEMERAL', u'mode': u'READ_WRITE' }], u'canIpForward': False, u'serviceAccounts': [{ u'scopes': [GCEAgent.GCE_SCOPE], u'email': u'*****@*****.**' }], u'metadata': { u'kind': u'compute#metadata', u'fingerprint': u'42WmSpB8rSM=' }, u'creationTimestamp': u'2013-05-22T11:52:33.254-07:00', u'id': u'8684033495853907982', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/instances/appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d', u'networkInterfaces': [{ u'accessConfigs': [{ u'kind': u'compute#accessConfig', u'type': u'ONE_TO_ONE_NAT', u'name': u'External NAT', u'natIP': u'public-ip' }], u'networkIP': u'private-ip', u'network': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazgroup', u'name': u'nic0' }] }], u'kind': u'compute#instanceList', u'id': u'projects/appscale.com:appscale/zones/my-zone-1b/instances', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/961228229472/zones/my-zone-1b/instances' } fake_list_instance_request = flexmock(name='fake_list_instance_request') fake_list_instance_request.should_receive('execute').with_args( http=fake_authorized_http).and_return(no_instance_info).and_return(list_instance_info) fake_instances = flexmock(name='fake_instances') fake_gce = flexmock(name='fake_gce') fake_gce.should_receive('instances').and_return(fake_instances) fake_instances.should_receive('list').with_args(project=self.project, filter="name eq boogroup-.*", zone='my-zone-1b') \ .and_return(fake_list_instance_request) # we only need to create one node, so set up mocks for that add_instance = u'operation-1369248752891-4dd5311848461-afc55a20' add_instance_info = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': add_instance, u'azone': unicode(GCEAgent.GCE_URL) + u'appscale.com:appscale/zones/my-zone-1b', u'startTime': u'2013-05-22T11:52:32.939-07:00', u'insertTime': u'2013-05-22T11:52:32.891-07:00', u'targetLink': unicode(GCEAgent.GCE_URL) + u'appscale.com:appscale/zones/my-zone-1b/instances/appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d', u'operationType': u'insert', u'progress': 0, u'id': u'6663616273628949255', u'selfLink': unicode(GCEAgent.GCE_URL) + u'appscale.com:appscale/zones/my-zone-1b/operations/operation-1369248752891-4dd5311848461-afc55a20', u'user': u'*****@*****.**' } fake_add_instance_request = flexmock(name='fake_add_instance_request') fake_add_instance_request.should_receive('execute').with_args( http=fake_authorized_http).and_return(add_instance_info) fake_instances.should_receive('insert').with_args(project=self.project, body=dict, zone=str).and_return(fake_add_instance_request) created_instance_info = { u'status': u'DONE' } fake_instance_checker = flexmock(name='fake_network_checker') fake_instance_checker.should_receive('execute').and_return( created_instance_info) fake_blocker = flexmock(name='fake_blocker') fake_gce.should_receive('globalOperations').and_return(fake_blocker) fake_blocker.should_receive('get').with_args(project=self.project, operation=add_instance).and_return(fake_instance_checker) # finally, inject our fake GCE connection flexmock(discovery) discovery.should_receive('build').with_args('compute', GCEAgent.API_VERSION).and_return(fake_gce) # next, presume that the persistent disk we want to use exists disk_name = 'my-persistent-disk-1' disk_info = {'status':'DONE'} fake_disk_request = flexmock(name='fake_disk_request') fake_disk_request.should_receive('execute').with_args( http=fake_authorized_http).and_return(disk_info) fake_disks = flexmock(name='fake_disks') fake_disks.should_receive('get').with_args(project=self.project, disk=disk_name, zone=str).and_return(fake_disk_request) fake_disks.should_receive('insert').with_args(project=self.project, sourceImage=str, body=dict, zone=str).and_return(fake_disk_request) fake_gce.should_receive('disks').and_return(fake_disks) public_key = 'ssh-rsa long_key_string' flexmock(utils).should_receive('get_public_key').and_return(public_key) i = InfrastructureManager(blocking=True) # first, validate that the run_instances call goes through successfully # and gives the user a reservation id full_result = { 'success': True, 'reservation_id': self.reservation_id, 'reason': 'none' } self.assertEquals(full_result, i.run_instances(self.params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its reservation info self.assertEquals(InfrastructureManager.STATE_RUNNING, i.reservations.get( self.reservation_id)['state']) vm_info = i.reservations.get(self.reservation_id)['vm_info'] self.assertEquals(['public-ip'], vm_info['public_ips']) self.assertEquals(['private-ip'], vm_info['private_ips']) self.assertEquals([instance_id], vm_info['instance_ids'])
def test_gce_run_instances(self): # mock out interactions with GCE # first, mock out the oauth library calls fake_flow = flexmock(name='fake_flow') flexmock(oauth2client.client) oauth2client.client.should_receive('flow_from_clientsecrets').with_args( GCEAgent.CLIENT_SECRETS_LOCATION, scope=GCEAgent.GCE_SCOPE).and_return( fake_flow) fake_storage = flexmock(name='fake_storage') fake_storage.should_receive('get').and_return(None) flexmock(oauth2client.file) oauth2client.file.should_receive('Storage').with_args( GCEAgent.OAUTH2_STORAGE_LOCATION).and_return(fake_storage) fake_credentials = flexmock(name='fake_credentials') flexmock(oauth2client.tools) oauth2client.tools.should_receive('run').with_args(fake_flow, fake_storage).and_return(fake_credentials) # next, mock out http calls to GCE fake_http = flexmock(name='fake_http') fake_authorized_http = flexmock(name='fake_authorized_http') flexmock(httplib2) httplib2.should_receive('Http').and_return(fake_http) fake_credentials.should_receive('authorize').with_args(fake_http) \ .and_return(fake_authorized_http) # add some fake data in where no instances are initially running, then one # is (in response to our insert request) no_instance_info = { } instance_id = u'appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d' list_instance_info = { u'items': [{ u'status': u'RUNNING', u'kind': u'compute#instance', u'machineType': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/machineTypes/n1-standard-1', u'name': instance_id, u'zone': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/us-central1-a', u'tags': {u'fingerprint': u'42WmSpB8rSM='}, u'image': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/images/lucid64', u'disks': [{ u'index': 0, u'kind': u'compute#attachedDisk', u'type': u'EPHEMERAL', u'mode': u'READ_WRITE' }], u'canIpForward': False, u'serviceAccounts': [{ u'scopes': [GCEAgent.GCE_SCOPE], u'email': u'*****@*****.**' }], u'metadata': { u'kind': u'compute#metadata', u'fingerprint': u'42WmSpB8rSM=' }, u'creationTimestamp': u'2013-05-22T11:52:33.254-07:00', u'id': u'8684033495853907982', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/us-central1-a/instances/appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d', u'networkInterfaces': [{ u'accessConfigs': [{ u'kind': u'compute#accessConfig', u'type': u'ONE_TO_ONE_NAT', u'name': u'External NAT', u'natIP': u'public-ip' }], u'networkIP': u'private-ip', u'network': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazgroup', u'name': u'nic0' }] }], u'kind': u'compute#instanceList', u'id': u'projects/appscale.com:appscale/zones/us-central1-a/instances', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/961228229472/zones/us-central1-a/instances' } fake_list_instance_request = flexmock(name='fake_list_instance_request') fake_list_instance_request.should_receive('execute').with_args( fake_authorized_http).and_return(no_instance_info).and_return( list_instance_info) fake_instances = flexmock(name='fake_instances') fake_gce = flexmock(name='fake_gce') fake_gce.should_receive('instances').and_return(fake_instances) fake_instances.should_receive('list').with_args(project=self.project, filter="name eq appscale-boogroup-.*", zone=GCEAgent.DEFAULT_ZONE) \ .and_return(fake_list_instance_request) # we only need to create one node, so set up mocks for that add_instance = u'operation-1369248752891-4dd5311848461-afc55a20' add_instance_info = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': add_instance, u'azone': unicode(GCEAgent.GCE_URL) + u'appscale.com:appscale/zones/us-central1-a', u'startTime': u'2013-05-22T11:52:32.939-07:00', u'insertTime': u'2013-05-22T11:52:32.891-07:00', u'targetLink': unicode(GCEAgent.GCE_URL) + u'appscale.com:appscale/zones/us-central1-a/instances/appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d', u'operationType': u'insert', u'progress': 0, u'id': u'6663616273628949255', u'selfLink': unicode(GCEAgent.GCE_URL) + u'appscale.com:appscale/zones/us-central1-a/operations/operation-1369248752891-4dd5311848461-afc55a20', u'user': u'*****@*****.**' } fake_add_instance_request = flexmock(name='fake_add_instance_request') fake_add_instance_request.should_receive('execute').with_args( fake_authorized_http).and_return(add_instance_info) fake_instances.should_receive('insert').with_args(project=self.project, body=dict, zone=str).and_return(fake_add_instance_request) created_instance_info = { u'status': u'DONE' } fake_instance_checker = flexmock(name='fake_network_checker') fake_instance_checker.should_receive('execute').and_return( created_instance_info) fake_blocker = flexmock(name='fake_blocker') fake_gce.should_receive('globalOperations').and_return(fake_blocker) fake_blocker.should_receive('get').with_args(project=self.project, operation=add_instance).and_return(fake_instance_checker) # finally, inject our fake GCE connection flexmock(apiclient.discovery) apiclient.discovery.should_receive('build').with_args('compute', GCEAgent.API_VERSION).and_return(fake_gce) i = InfrastructureManager(blocking=True) # first, validate that the run_instances call goes through successfully # and gives the user a reservation id full_params = { 'credentials' : { 'EC2_URL': None, 'EC2_ACCESS_KEY': None, 'EC2_SECRET_KEY': None, }, 'project': self.project, 'group': 'boogroup', 'image_id': 'booid', 'infrastructure': 'gce', 'instance_type': 'booinstance_type', 'keyname': 'bookeyname', 'num_vms': '1', 'use_spot_instances': False, } full_result = { 'success': True, 'reservation_id': self.reservation_id, 'reason': 'none' } self.assertEquals(full_result, i.run_instances(full_params, 'secret')) # next, look at run_instances internally to make sure it actually is # updating its reservation info self.assertEquals(InfrastructureManager.STATE_RUNNING, i.reservations.get( self.reservation_id)['state']) vm_info = i.reservations.get(self.reservation_id)['vm_info'] self.assertEquals(['public-ip'], vm_info['public_ips']) self.assertEquals(['private-ip'], vm_info['private_ips']) self.assertEquals([instance_id], vm_info['instance_ids'])
def test_gce_run_instances(self): # mock out interactions with GCE # first, mock out the oauth library calls fake_credentials = flexmock(name="fake_credentials") fake_storage = flexmock(name="fake_storage") fake_storage.should_receive("get").and_return(fake_credentials) flexmock(oauth2client.file) oauth2client.file.should_receive("Storage").with_args(GCEAgent.OAUTH2_STORAGE_LOCATION).and_return(fake_storage) # next, mock out http calls to GCE fake_http = flexmock(name="fake_http") fake_authorized_http = flexmock(name="fake_authorized_http") flexmock(httplib2) httplib2.should_receive("Http").and_return(fake_http) fake_credentials.should_receive("authorize").with_args(fake_http).and_return(fake_authorized_http) # add some fake data in where no instances are initially running, then one # is (in response to our insert request) no_instance_info = {} instance_id = u"appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d" list_instance_info = { u"items": [ { u"status": u"RUNNING", u"kind": u"compute#instance", u"machineType": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/machineTypes/n1-standard-1", u"name": instance_id, u"zone": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b", u"tags": {u"fingerprint": u"42WmSpB8rSM="}, u"image": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/images/lucid64", u"disks": [ {u"index": 0, u"kind": u"compute#attachedDisk", u"type": u"EPHEMERAL", u"mode": u"READ_WRITE"} ], u"canIpForward": False, u"serviceAccounts": [ {u"scopes": [GCEAgent.GCE_SCOPE], u"email": u"*****@*****.**"} ], u"metadata": {u"kind": u"compute#metadata", u"fingerprint": u"42WmSpB8rSM="}, u"creationTimestamp": u"2013-05-22T11:52:33.254-07:00", u"id": u"8684033495853907982", u"selfLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/instances/appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d", u"networkInterfaces": [ { u"accessConfigs": [ { u"kind": u"compute#accessConfig", u"type": u"ONE_TO_ONE_NAT", u"name": u"External NAT", u"natIP": u"public-ip", } ], u"networkIP": u"private-ip", u"network": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazgroup", u"name": u"nic0", } ], } ], u"kind": u"compute#instanceList", u"id": u"projects/appscale.com:appscale/zones/my-zone-1b/instances", u"selfLink": u"https://www.googleapis.com/compute/v1beta14/projects/961228229472/zones/my-zone-1b/instances", } fake_list_instance_request = flexmock(name="fake_list_instance_request") fake_list_instance_request.should_receive("execute").with_args(fake_authorized_http).and_return( no_instance_info ).and_return(list_instance_info) fake_instances = flexmock(name="fake_instances") fake_gce = flexmock(name="fake_gce") fake_gce.should_receive("instances").and_return(fake_instances) fake_instances.should_receive("list").with_args( project=self.project, filter="name eq appscale-boogroup-.*", zone="my-zone-1b" ).and_return(fake_list_instance_request) # we only need to create one node, so set up mocks for that add_instance = u"operation-1369248752891-4dd5311848461-afc55a20" add_instance_info = { u"status": u"PENDING", u"kind": u"compute#operation", u"name": add_instance, u"azone": unicode(GCEAgent.GCE_URL) + u"appscale.com:appscale/zones/my-zone-1b", u"startTime": u"2013-05-22T11:52:32.939-07:00", u"insertTime": u"2013-05-22T11:52:32.891-07:00", u"targetLink": unicode(GCEAgent.GCE_URL) + u"appscale.com:appscale/zones/my-zone-1b/instances/appscale-bazgroup-feb10b11-62bc-4536-ac25-9734f2267d6d", u"operationType": u"insert", u"progress": 0, u"id": u"6663616273628949255", u"selfLink": unicode(GCEAgent.GCE_URL) + u"appscale.com:appscale/zones/my-zone-1b/operations/operation-1369248752891-4dd5311848461-afc55a20", u"user": u"*****@*****.**", } fake_add_instance_request = flexmock(name="fake_add_instance_request") fake_add_instance_request.should_receive("execute").with_args(fake_authorized_http).and_return( add_instance_info ) fake_instances.should_receive("insert").with_args(project=self.project, body=dict, zone=str).and_return( fake_add_instance_request ) created_instance_info = {u"status": u"DONE"} fake_instance_checker = flexmock(name="fake_network_checker") fake_instance_checker.should_receive("execute").and_return(created_instance_info) fake_blocker = flexmock(name="fake_blocker") fake_gce.should_receive("globalOperations").and_return(fake_blocker) fake_blocker.should_receive("get").with_args(project=self.project, operation=add_instance).and_return( fake_instance_checker ) # finally, inject our fake GCE connection flexmock(apiclient.discovery) apiclient.discovery.should_receive("build").with_args("compute", GCEAgent.API_VERSION).and_return(fake_gce) i = InfrastructureManager(blocking=True) # first, validate that the run_instances call goes through successfully # and gives the user a reservation id full_result = {"success": True, "reservation_id": self.reservation_id, "reason": "none"} self.assertEquals(full_result, i.run_instances(self.params, "secret")) # next, look at run_instances internally to make sure it actually is # updating its reservation info self.assertEquals(InfrastructureManager.STATE_RUNNING, i.reservations.get(self.reservation_id)["state"]) vm_info = i.reservations.get(self.reservation_id)["vm_info"] self.assertEquals(["public-ip"], vm_info["public_ips"]) self.assertEquals(["private-ip"], vm_info["private_ips"]) self.assertEquals([instance_id], vm_info["instance_ids"])