def terminate_instances(cls, options): """Stops all services running in an AppScale deployment, and in cloud deployments, also powers off the instances previously spawned. Raises: AppScaleException: If AppScale is not running, and thus can't be terminated. """ if not os.path.exists(LocalState.get_locations_yaml_location( options.keyname)): raise AppScaleException("AppScale is not running with the keyname {0}". format(options.keyname)) infrastructure = LocalState.get_infrastructure(options.keyname) # If the user is on a cloud deployment, and not backing their data to # persistent disks, warn them before shutting down AppScale. # Also, if we're in developer mode, skip the warning. if infrastructure != "xen" and not LocalState.are_disks_used( options.keyname) and not options.test: LocalState.ensure_user_wants_to_terminate() if infrastructure in InfrastructureAgentFactory.VALID_AGENTS: RemoteHelper.terminate_cloud_infrastructure(options.keyname, options.verbose) else: RemoteHelper.terminate_virtualized_cluster(options.keyname, options.verbose) LocalState.cleanup_appscale_files(options.keyname) AppScaleLogger.success("Successfully shut down your AppScale deployment.")
def copy_local_metadata(cls, host, keyname, is_verbose): """Copies the locations.yaml and locations.json files found locally (which contain metadata about this AppScale deployment) to the specified host. Args: host: The machine that we should copy the metadata files to. keyname: The name of the SSH keypair that we can use to log into the given host. is_verbose: A bool that indicates if we should print the SCP commands we exec to stdout. """ # copy the metadata files for AppScale itself to use cls.scp(host, keyname, LocalState.get_locations_yaml_location(keyname), '/etc/appscale/locations-{0}.yaml'.format(keyname), is_verbose) cls.scp(host, keyname, LocalState.get_locations_json_location(keyname), '/etc/appscale/locations-{0}.json'.format(keyname), is_verbose) # and copy the json file if the tools on that box wants to use it cls.scp(host, keyname, LocalState.get_locations_json_location(keyname), '/root/.appscale/locations-{0}.json'.format(keyname), is_verbose) # and copy the secret file if the tools on that box wants to use it cls.scp(host, keyname, LocalState.get_secret_key_location(keyname), '/root/.appscale/', is_verbose)
def terminate_instances(cls, options): """Stops all services running in an AppScale deployment, and in cloud deployments, also powers off the instances previously spawned. Raises: AppScaleException: If AppScale is not running, and thus can't be terminated. """ if not os.path.exists( LocalState.get_locations_yaml_location(options.keyname)): raise AppScaleException( "AppScale is not running with the keyname {0}".format( options.keyname)) if LocalState.get_infrastructure(options.keyname) in \ InfrastructureAgentFactory.VALID_AGENTS: RemoteHelper.terminate_cloud_infrastructure( options.keyname, options.verbose) else: RemoteHelper.terminate_virtualized_cluster(options.keyname, options.verbose) LocalState.cleanup_appscale_files(options.keyname) AppScaleLogger.success( "Successfully shut down your AppScale deployment.")
def test_update_local_metadata(self): # mock out getting all the ips in the deployment from the head node fake_soap = flexmock(name='fake_soap') fake_soap.should_receive('get_all_public_ips').with_args('the secret') \ .and_return(json.dumps(['public1'])) role_info = [{ 'public_ip' : 'public1', 'private_ip' : 'private1', 'jobs' : ['shadow', 'db_master'] }] fake_soap.should_receive('get_role_info').with_args('the secret') \ .and_return(json.dumps(role_info)) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://public1:17443') \ .and_return(fake_soap) # mock out reading the secret key fake_secret = flexmock(name='fake_secret') fake_secret.should_receive('read').and_return('the secret') builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') builtins.should_receive('open').with_args( LocalState.get_secret_key_location('booscale'), 'r') \ .and_return(fake_secret) # mock out writing the yaml file fake_locations_yaml = flexmock(name='fake_locations_yaml') fake_locations_yaml.should_receive('write').with_args(yaml.dump({ 'load_balancer': 'public1', 'instance_id': 'i-ABCDEFG', 'secret': 'the secret', 'infrastructure': 'ec2', 'group': 'boogroup', 'ips': 'public1', 'table': 'cassandra', 'db_master': 'node-0', 'zone' : 'my-zone-1b' })).and_return() builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location('booscale'), 'w') \ .and_return(fake_locations_yaml) # and mock out writing the json file fake_locations_json = flexmock(name='fake_locations_json') fake_locations_json.should_receive('write').with_args(json.dumps( role_info)).and_return() builtins.should_receive('open').with_args( LocalState.get_locations_json_location('booscale'), 'w') \ .and_return(fake_locations_json) options = flexmock(name='options', table='cassandra', infrastructure='ec2', keyname='booscale', group='boogroup', zone='my-zone-1b') node_layout = NodeLayout(options={ 'min' : 1, 'max' : 1, 'infrastructure' : 'ec2', 'table' : 'cassandra' }) host = 'public1' instance_id = 'i-ABCDEFG' LocalState.update_local_metadata(options, node_layout, host, instance_id)
def test_terminate_when_not_running(self): # let's say that there's no locations.yaml file, which means appscale isn't # running, so we should throw up and die flexmock(os.path) os.path.should_call("exists") # set up the fall-through os.path.should_receive("exists").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return( False ) argv = ["--keyname", self.keyname] options = ParseArgs(argv, self.function).args self.assertRaises(AppScaleException, AppScaleTools.terminate_instances, options)
def test_terminate_when_not_running(self): # let's say that there's no locations.yaml file, which means appscale isn't # running, so we should throw up and die flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location( self.keyname)).and_return(False) argv = ["--keyname", self.keyname] options = ParseArgs(argv, self.function).args self.assertRaises(AppScaleException, AppScaleTools.terminate_instances, options)
def copy_local_metadata(cls, host, keyname, is_verbose): """Copies the locations.yaml and locations.json files found locally (which contain metadata about this AppScale deployment) to the specified host. Args: host: The machine that we should copy the metadata files to. keyname: The name of the SSH keypair that we can use to log into the given host. is_verbose: A bool that indicates if we should print the SCP commands we exec to stdout. """ # copy the metadata files for AppScale itself to use cls.scp( host, keyname, LocalState.get_locations_yaml_location(keyname), "/etc/appscale/locations-{0}.yaml".format(keyname), is_verbose, ) cls.scp( host, keyname, LocalState.get_locations_json_location(keyname), "/etc/appscale/locations-{0}.json".format(keyname), is_verbose, ) # and copy the json file if the tools on that box wants to use it cls.scp( host, keyname, LocalState.get_locations_json_location(keyname), "/root/.appscale/locations-{0}.json".format(keyname), is_verbose, ) # and copy the secret file if the tools on that box wants to use it cls.scp(host, keyname, LocalState.get_secret_key_location(keyname), "/root/.appscale/", is_verbose)
def terminate_instances(cls, options): """Stops all services running in an AppScale deployment, and in cloud deployments, also powers off the instances previously spawned. Raises: AppScaleException: If AppScale is not running, and thus can't be terminated. """ if not os.path.exists(LocalState.get_locations_yaml_location( options.keyname)): raise AppScaleException("AppScale is not running with the keyname {0}". format(options.keyname)) if LocalState.get_infrastructure(options.keyname) in \ InfrastructureAgentFactory.VALID_AGENTS: RemoteHelper.terminate_cloud_infrastructure(options.keyname, options.verbose) else: RemoteHelper.terminate_virtualized_cluster(options.keyname, options.verbose) LocalState.cleanup_appscale_files(options.keyname) AppScaleLogger.success("Successfully shut down your AppScale deployment.")
def test_terminate_in_cloud_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_secret_key_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') fake_yaml_file = flexmock(name='fake_file') fake_yaml_file.should_receive('read').and_return( yaml.dump({ 'infrastructure': 'ec2', 'group': self.group, })) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_yaml_file) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name='fake_file') fake_json_file.should_receive('read').and_return( json.dumps([{ 'public_ip': 'public1', 'jobs': ['shadow'] }, { 'public_ip': 'public2', 'jobs': ['appengine'] }])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_json_file) # and slip in a fake secret file fake_secret_file = flexmock(name='fake_file') fake_secret_file.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args( LocalState.get_secret_key_location(self.keyname), 'r') \ .and_return(fake_secret_file) # mock out talking to EC2 fake_ec2 = flexmock(name='fake_ec2') # let's say that three instances are running, and that two of them are in # our deployment fake_one_running = flexmock(name='fake_one', key_name=self.keyname, state='running', id='i-ONE', public_dns_name='public1', private_dns_name='private1') fake_two_running = flexmock(name='fake_two', key_name=self.keyname, state='running', id='i-TWO', public_dns_name='public2', private_dns_name='private2') fake_three_running = flexmock(name='fake_three', key_name='abcdefg', state='running', id='i-THREE', public_dns_name='public3', private_dns_name='private3') fake_reservation_running = flexmock( name='fake_reservation', instances=[fake_one_running, fake_two_running, fake_three_running]) fake_one_terminated = flexmock(name='fake_one', key_name=self.keyname, state='terminated', id='i-ONE', public_dns_name='public1', private_dns_name='private1') fake_two_terminated = flexmock(name='fake_two', key_name=self.keyname, state='terminated', id='i-TWO', public_dns_name='public2', private_dns_name='private2') fake_three_terminated = flexmock(name='fake_three', key_name='abcdefg', state='terminated', id='i-THREE', public_dns_name='public3', private_dns_name='private3') fake_reservation_terminated = flexmock(name='fake_reservation', instances=[ fake_one_terminated, fake_two_terminated, fake_three_terminated ]) fake_ec2.should_receive('get_all_instances').and_return(fake_reservation_running) \ .and_return(fake_reservation_terminated) flexmock(boto.ec2) boto.ec2.should_receive('connect_to_region').and_return(fake_ec2) # and mock out the call to kill the instances fake_ec2.should_receive('terminate_instances').with_args( ['i-ONE', 'i-TWO']).and_return([fake_one_terminated, fake_two_terminated]) # mock out the call to delete the keypair fake_ec2.should_receive('delete_key_pair').and_return() # and the call to delete the security group - let's say that we can't # delete the group the first time, and can the second fake_ec2.should_receive('delete_security_group').and_return(False) \ .and_return(True) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive('remove').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_secret_key_location(self.keyname)).and_return() # also mock out asking the user for confirmation on shutting down # their cloud builtins.should_receive('raw_input').and_return('yes') argv = ["--keyname", self.keyname] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_terminate_in_virtual_cluster_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') fake_yaml_file = flexmock(name='fake_file') fake_yaml_file.should_receive('read').and_return(yaml.dump({ 'infrastructure' : 'xen' })) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_yaml_file) # mock out reading the json file, and pretend that we're running in a # two node deployment os.path.should_receive('exists').with_args( LocalState.get_locations_json_location(self.keyname)).and_return(True) fake_json_file = flexmock(name='fake_file') fake_json_file.should_receive('read').and_return(json.dumps([ { 'public_ip' : 'public1', 'jobs' : ['shadow'] }, { 'public_ip' : 'public2', 'jobs' : ['appengine'] } ])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_json_file) # and slip in a fake secret file fake_secret_file = flexmock(name='fake_file') fake_secret_file.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args( LocalState.get_secret_key_location(self.keyname), 'r') \ .and_return(fake_secret_file) # mock out talking to the appcontroller, and assume that it tells us there # there are still two machines in this deployment fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('get_all_public_ips').with_args('the secret') \ .and_return(json.dumps(['public1', 'public2'])) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://public1:17443') \ .and_return(fake_appcontroller) # and mock out the ssh call to kill the remote appcontroller, assuming that # it fails the first time and passes the second flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('controller stop'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.failed).and_return(self.success) # next, mock out our checks to see how the stopping process is going and # assume that it has stopped flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ps x'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive('remove').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_secret_key_location(self.keyname)).and_return() argv = [ "--keyname", self.keyname ] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_terminate_in_cloud_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') fake_yaml_file = flexmock(name='fake_file') fake_yaml_file.should_receive('read').and_return(yaml.dump({ 'infrastructure' : 'ec2', 'group' : 'bazboogroup' })) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_yaml_file) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name='fake_file') fake_json_file.should_receive('read').and_return(json.dumps([ { 'public_ip' : 'public1', 'jobs' : ['shadow'] }, { 'public_ip' : 'public2', 'jobs' : ['appengine'] } ])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_json_file) # and slip in a fake secret file fake_secret_file = flexmock(name='fake_file') fake_secret_file.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args( LocalState.get_secret_key_location(self.keyname), 'r') \ .and_return(fake_secret_file) # mock out talking to EC2 fake_ec2 = flexmock(name='fake_ec2') # let's say that three instances are running, and that two of them are in # our deployment fake_one = flexmock(name='fake_one', key_name=self.keyname, state='running', id='i-ONE', public_dns_name='public1', private_dns_name='private1') fake_two = flexmock(name='fake_two', key_name=self.keyname, state='running', id='i-TWO', public_dns_name='public2', private_dns_name='private2') fake_three = flexmock(name='fake_three', key_name='abcdefg', state='running', id='i-THREE', public_dns_name='public3', private_dns_name='private3') fake_reservation = flexmock(name='fake_reservation', instances=[fake_one, fake_two, fake_three]) fake_ec2.should_receive('get_all_instances').and_return(fake_reservation) flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz') \ .and_return(fake_ec2) # and mock out the call to kill the instances fake_ec2.should_receive('terminate_instances').with_args(['i-ONE', 'i-TWO']).and_return([fake_one, fake_two]) # mock out the call to delete the keypair fake_ec2.should_receive('delete_key_pair').and_return() # and the call to delete the security group - let's say that we can't # delete the group the first time, and can the second fake_ec2.should_receive('delete_security_group').and_return(False) \ .and_return(True) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive('remove').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_secret_key_location(self.keyname)).and_return() argv = [ "--keyname", self.keyname ] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_terminate_in_gce_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return(True) os.path.should_receive('exists').with_args( LocalState.get_client_secrets_location(self.keyname)).and_return(True) os.path.should_receive('exists').with_args( LocalState.get_secret_key_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # GCE project_id = "1234567890" zone = 'my-zone-1b' builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') fake_yaml_file = flexmock(name='fake_file') fake_yaml_file.should_receive('read').and_return(yaml.dump({ 'infrastructure' : 'gce', 'group' : self.group, 'project' : project_id, 'zone' : zone })) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_yaml_file) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name='fake_file') fake_json_file.should_receive('read').and_return(json.dumps([ { 'public_ip' : 'public1', 'jobs' : ['shadow'] }, { 'public_ip' : 'public2', 'jobs' : ['appengine'] } ])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_json_file) # and slip in a fake secret file fake_secret_file = flexmock(name='fake_file') fake_secret_file.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args( LocalState.get_secret_key_location(self.keyname), 'r') \ .and_return(fake_secret_file) # also add in a fake client-secrets file for GCE client_secrets = LocalState.get_client_secrets_location(self.keyname) # mock out talking to 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( client_secrets, scope=str).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(str).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) fake_gce = flexmock(name='fake_gce') # let's say that two instances are running instance_one_info = { 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': u'appscale-bazboogroup-one', 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-bazboogroup-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'public1' }], u'networkIP': u'private1', u'network': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazboogroup', u'name': u'nic0' }] } instance_two_info = { 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': u'appscale-bazboogroup-two', 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-bazboogroup-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'public1' }], u'networkIP': u'private1', u'network': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazboogroup', u'name': u'nic0' }] } list_instance_info = { u'items': [instance_one_info, instance_two_info], 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(list_instance_info) fake_instances = flexmock(name='fake_instances') fake_instances.should_receive('list').with_args(project=project_id, filter="name eq appscale-bazboogroup-.*", zone=zone) \ .and_return(fake_list_instance_request) fake_gce.should_receive('instances').and_return(fake_instances) # And assume that we can kill both of our instances fine delete_instance = u'operation-1369676691806-4ddb6b4ab6f39-a095d3de' delete_instance_info_one = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': delete_instance, u'zone': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b', u'startTime': u'2013-05-27T10:44:51.849-07:00', u'insertTime': u'2013-05-27T10:44:51.806-07:00', u'targetId': u'12912855597472179535', u'targetLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/instances/appscale-appscalecgb20-0cf89267-5887-4048-b774-ca20de47a07f', u'operationType': u'delete', u'progress': 0, u'id': u'11114355109942058217', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/operations/operation-1369676691806-4ddb6b4ab6f39-a095d3de', u'user': u'*****@*****.**' } delete_instance_info_two = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': delete_instance, u'zone': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b', u'startTime': u'2013-05-27T10:44:51.849-07:00', u'insertTime': u'2013-05-27T10:44:51.806-07:00', u'targetId': u'12912855597472179535', u'targetLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/instances/appscale-appscalecgb20-0cf89267-5887-4048-b774-ca20de47a07f', u'operationType': u'delete', u'progress': 0, u'id': u'11114355109942058217', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/operations/operation-1369676691806-4ddb6b4ab6f39-a095d3de', u'user': u'*****@*****.**' } fake_delete_instance_request_one = flexmock(name='fake_delete_instance_request_one') fake_delete_instance_request_one.should_receive('execute').with_args( http=fake_authorized_http).and_return(delete_instance_info_one) fake_instances.should_receive('delete').with_args(project=project_id, zone=zone, instance='appscale-bazboogroup-one').and_return( fake_delete_instance_request_one) fake_delete_instance_request_two = flexmock(name='fake_delete_instance_request_two') fake_delete_instance_request_two.should_receive('execute').with_args( http=fake_authorized_http).and_return(delete_instance_info_two) fake_instances.should_receive('delete').with_args(project=project_id, zone=zone, instance='appscale-bazboogroup-two').and_return( fake_delete_instance_request_two) # mock out our waiting for the instances to be deleted all_done = { u'status' : u'DONE' } fake_instance_checker = flexmock(name='fake_instance_checker') fake_instance_checker.should_receive('execute').and_return(all_done) fake_blocker = flexmock(name='fake_blocker') fake_blocker.should_receive('get').with_args(project=project_id, operation=delete_instance, zone=zone).and_return( fake_instance_checker) fake_gce.should_receive('zoneOperations').and_return(fake_blocker) # mock out the call to delete the firewall delete_firewall = u'operation-1369677695390-4ddb6f07cc611-5a8f1654' fake_delete_firewall_info = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': delete_firewall, u'startTime': u'2013-05-27T11:01:35.482-07:00', u'insertTime': u'2013-05-27T11:01:35.390-07:00', u'targetId': u'11748720697396371259', u'targetLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/firewalls/appscalecgb20', u'operationType': u'delete', u'progress': 0, u'id': u'15574488986772298961', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/operations/operation-1369677695390-4ddb6f07cc611-5a8f1654', u'user': u'*****@*****.**' } fake_delete_firewall_request = flexmock(name='fake_delete_firewall_request') fake_delete_firewall_request.should_receive('execute').and_return(fake_delete_firewall_info) fake_firewalls = flexmock(name='fake_firewalls') fake_firewalls.should_receive('delete').with_args(project=project_id, firewall=self.group).and_return(fake_delete_firewall_request) fake_gce.should_receive('firewalls').and_return(fake_firewalls) # mock out the call to make sure the firewall was deleted fake_firewall_checker = flexmock(name='fake_firewall_checker') fake_firewall_checker.should_receive('execute').and_return(all_done) fake_blocker.should_receive('get').with_args(project=project_id, operation=delete_firewall).and_return(fake_firewall_checker) fake_gce.should_receive('globalOperations').and_return(fake_blocker) # and the call to delete the network delete_network = u'operation-1369677749954-4ddb6f3bd1849-056cf8ca' fake_delete_network_info = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': delete_network, u'startTime': u'2013-05-27T11:02:30.012-07:00', u'insertTime': u'2013-05-27T11:02:29.954-07:00', u'targetId': u'17688075350400527692', u'targetLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/appscalecgb20', u'operationType': u'delete', u'progress': 0, u'id': u'12623697331874594836', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/operations/operation-1369677749954-4ddb6f3bd1849-056cf8ca', u'user': u'*****@*****.**' } fake_delete_network_request = flexmock(name='fake_delete_network_request') fake_delete_network_request.should_receive('execute').and_return(fake_delete_network_info) fake_networks = flexmock(name='fake_networks') fake_networks.should_receive('delete').with_args(project=project_id, network=self.group).and_return(fake_delete_network_request) fake_gce.should_receive('networks').and_return(fake_networks) # mock out the call to make sure the network was deleted fake_network_checker = flexmock(name='fake_network_checker') fake_network_checker.should_receive('execute').and_return(all_done) fake_blocker.should_receive('get').with_args(project=project_id, operation=delete_network).and_return(fake_network_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) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive('remove').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_secret_key_location(self.keyname)).and_return() argv = [ "--keyname", self.keyname, "--test" ] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_terminate_in_cloud_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call("exists") # set up the fall-through os.path.should_receive("exists").with_args(LocalState.get_secret_key_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules["__builtin__"]) builtins.should_call("open") fake_yaml_file = flexmock(name="fake_file") fake_yaml_file.should_receive("read").and_return(yaml.dump({"infrastructure": "ec2", "group": self.group})) builtins.should_receive("open").with_args(LocalState.get_locations_yaml_location(self.keyname), "r").and_return( fake_yaml_file ) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name="fake_file") fake_json_file.should_receive("read").and_return( json.dumps([{"public_ip": "public1", "jobs": ["shadow"]}, {"public_ip": "public2", "jobs": ["appengine"]}]) ) builtins.should_receive("open").with_args(LocalState.get_locations_json_location(self.keyname), "r").and_return( fake_json_file ) # and slip in a fake secret file fake_secret_file = flexmock(name="fake_file") fake_secret_file.should_receive("read").and_return("the secret") builtins.should_receive("open").with_args(LocalState.get_secret_key_location(self.keyname), "r").and_return( fake_secret_file ) # mock out talking to EC2 fake_ec2 = flexmock(name="fake_ec2") # let's say that three instances are running, and that two of them are in # our deployment fake_one_running = flexmock( name="fake_one", key_name=self.keyname, state="running", id="i-ONE", public_dns_name="public1", private_dns_name="private1", ) fake_two_running = flexmock( name="fake_two", key_name=self.keyname, state="running", id="i-TWO", public_dns_name="public2", private_dns_name="private2", ) fake_three_running = flexmock( name="fake_three", key_name="abcdefg", state="running", id="i-THREE", public_dns_name="public3", private_dns_name="private3", ) fake_reservation_running = flexmock( name="fake_reservation", instances=[fake_one_running, fake_two_running, fake_three_running] ) fake_one_terminated = flexmock( name="fake_one", key_name=self.keyname, state="terminated", id="i-ONE", public_dns_name="public1", private_dns_name="private1", ) fake_two_terminated = flexmock( name="fake_two", key_name=self.keyname, state="terminated", id="i-TWO", public_dns_name="public2", private_dns_name="private2", ) fake_three_terminated = flexmock( name="fake_three", key_name="abcdefg", state="terminated", id="i-THREE", public_dns_name="public3", private_dns_name="private3", ) fake_reservation_terminated = flexmock( name="fake_reservation", instances=[fake_one_terminated, fake_two_terminated, fake_three_terminated] ) fake_ec2.should_receive("get_all_instances").and_return(fake_reservation_running).and_return( fake_reservation_terminated ) flexmock(boto.ec2) boto.ec2.should_receive("connect_to_region").and_return(fake_ec2) # and mock out the call to kill the instances fake_ec2.should_receive("terminate_instances").with_args(["i-ONE", "i-TWO"]).and_return( [fake_one_terminated, fake_two_terminated] ) # mock out the call to delete the keypair fake_ec2.should_receive("delete_key_pair").and_return() # and the call to delete the security group - let's say that we can't # delete the group the first time, and can the second fake_ec2.should_receive("delete_security_group").and_return(False).and_return(True) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive("remove").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive("remove").with_args(LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive("remove").with_args(LocalState.get_secret_key_location(self.keyname)).and_return() # also mock out asking the user for confirmation on shutting down # their cloud builtins.should_receive("raw_input").and_return("yes") argv = ["--keyname", self.keyname] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_add_nodes_in_virt_deployment(self): # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_yaml = """ database: 1.2.3.4 zookeeper: 1.2.3.4 appengine: 1.2.3.4 """ # mock out reading the yaml file, and slip in our own fake_yaml_file = flexmock(name='fake_yaml') fake_yaml_file.should_receive('read').and_return(ips_yaml) builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through builtins.should_receive('open').with_args('/tmp/boo.yaml', 'r') \ .and_return(fake_yaml_file) # and pretend we're on a virtualized cluster locations_yaml = yaml.dump({ "infrastructure" : "xen" }) fake_locations_yaml_file = flexmock(name='fake_yaml') fake_locations_yaml_file.should_receive('read').and_return(locations_yaml) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_locations_yaml_file) # say that the ssh key works flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT, stdin=self.fake_input_file) \ .and_return(self.success) # mock out reading the locations.json file, and slip in our own json flexmock(os.path) os.path.should_call('exists') # set the fall-through os.path.should_receive('exists').with_args( LocalState.get_locations_json_location(self.keyname)).and_return(True) fake_nodes_json = flexmock(name="fake_nodes_json") fake_nodes_json.should_receive('read').and_return(json.dumps([{ "public_ip" : "public1", "private_ip" : "private1", "jobs" : ["shadow", "login"] }])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_nodes_json) # mock out writing the secret key to ~/.appscale, as well as reading it # later secret_key_location = LocalState.get_secret_key_location(self.keyname) fake_secret = flexmock(name="fake_secret") fake_secret.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args(secret_key_location, 'r') \ .and_return(fake_secret) # mock out the SOAP call to the AppController and assume it succeeded json_node_info = json.dumps(yaml.safe_load(ips_yaml)) fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('start_roles_on_nodes') \ .with_args(json_node_info, 'the secret').and_return('OK') flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://public1:17443') \ .and_return(fake_appcontroller) argv = [ "--ips", "/tmp/boo.yaml", "--keyname", self.keyname ] options = ParseArgs(argv, self.function).args AppScaleTools.add_instances(options)
def test_terminate_in_gce_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location( self.keyname)).and_return(True) os.path.should_receive('exists').with_args( LocalState.get_client_secrets_location( self.keyname)).and_return(True) os.path.should_receive('exists').with_args( LocalState.get_secret_key_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # GCE project_id = "1234567890" zone = 'my-zone-1b' builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') fake_yaml_file = flexmock(name='fake_file') fake_yaml_file.should_receive('read').and_return( yaml.dump({ 'infrastructure': 'gce', 'group': self.group, 'project': project_id, 'zone': zone })) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_yaml_file) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name='fake_file') fake_json_file.should_receive('read').and_return( json.dumps([{ 'public_ip': 'public1', 'jobs': ['shadow'] }, { 'public_ip': 'public2', 'jobs': ['appengine'] }])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_json_file) # and slip in a fake secret file fake_secret_file = flexmock(name='fake_file') fake_secret_file.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args( LocalState.get_secret_key_location(self.keyname), 'r') \ .and_return(fake_secret_file) # also add in a fake client-secrets file for GCE client_secrets = LocalState.get_client_secrets_location(self.keyname) # mock out talking to 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( client_secrets, scope=str).and_return(fake_flow) fake_storage = flexmock(name='fake_storage') fake_storage.should_receive('get').and_return(None) fake_flags = oauth2client.tools.argparser.parse_args(args=[]) flexmock(oauth2client.file) oauth2client.file.should_receive('Storage').with_args(str).and_return( fake_storage) fake_credentials = flexmock(name='fake_credentials') flexmock(oauth2client.tools) oauth2client.tools.should_receive('run_flow').with_args( fake_flow, fake_storage, fake_flags).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) fake_gce = flexmock(name='fake_gce') # let's say that two instances are running instance_one_info = { 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': u'appscale-bazboogroup-one', 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-bazboogroup-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'public1' }], u'networkIP': u'private1', u'network': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazboogroup', u'name': u'nic0' }] } instance_two_info = { 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': u'appscale-bazboogroup-two', 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-bazboogroup-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'public1' }], u'networkIP': u'private1', u'network': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazboogroup', u'name': u'nic0' }] } list_instance_info = { u'items': [instance_one_info, instance_two_info], 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(list_instance_info) fake_instances = flexmock(name='fake_instances') fake_instances.should_receive('list').with_args(project=project_id, filter="name eq appscale-bazboogroup-.*", zone=zone) \ .and_return(fake_list_instance_request) fake_gce.should_receive('instances').and_return(fake_instances) # And assume that we can kill both of our instances fine delete_instance = u'operation-1369676691806-4ddb6b4ab6f39-a095d3de' delete_instance_info_one = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': delete_instance, u'zone': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b', u'startTime': u'2013-05-27T10:44:51.849-07:00', u'insertTime': u'2013-05-27T10:44:51.806-07:00', u'targetId': u'12912855597472179535', u'targetLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/instances/appscale-appscalecgb20-0cf89267-5887-4048-b774-ca20de47a07f', u'operationType': u'delete', u'progress': 0, u'id': u'11114355109942058217', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/operations/operation-1369676691806-4ddb6b4ab6f39-a095d3de', u'user': u'*****@*****.**' } delete_instance_info_two = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': delete_instance, u'zone': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b', u'startTime': u'2013-05-27T10:44:51.849-07:00', u'insertTime': u'2013-05-27T10:44:51.806-07:00', u'targetId': u'12912855597472179535', u'targetLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/instances/appscale-appscalecgb20-0cf89267-5887-4048-b774-ca20de47a07f', u'operationType': u'delete', u'progress': 0, u'id': u'11114355109942058217', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/operations/operation-1369676691806-4ddb6b4ab6f39-a095d3de', u'user': u'*****@*****.**' } fake_delete_instance_request_one = flexmock( name='fake_delete_instance_request_one') fake_delete_instance_request_one.should_receive('execute').with_args( http=fake_authorized_http).and_return(delete_instance_info_one) fake_instances.should_receive('delete').with_args( project=project_id, zone=zone, instance='appscale-bazboogroup-one').and_return( fake_delete_instance_request_one) fake_delete_instance_request_two = flexmock( name='fake_delete_instance_request_two') fake_delete_instance_request_two.should_receive('execute').with_args( http=fake_authorized_http).and_return(delete_instance_info_two) fake_instances.should_receive('delete').with_args( project=project_id, zone=zone, instance='appscale-bazboogroup-two').and_return( fake_delete_instance_request_two) # mock out our waiting for the instances to be deleted all_done = {u'status': u'DONE'} fake_instance_checker = flexmock(name='fake_instance_checker') fake_instance_checker.should_receive('execute').and_return(all_done) fake_blocker = flexmock(name='fake_blocker') fake_blocker.should_receive('get').with_args( project=project_id, operation=delete_instance, zone=zone).and_return(fake_instance_checker) fake_gce.should_receive('zoneOperations').and_return(fake_blocker) # mock out the call to delete the firewall delete_firewall = u'operation-1369677695390-4ddb6f07cc611-5a8f1654' fake_delete_firewall_info = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': delete_firewall, u'startTime': u'2013-05-27T11:01:35.482-07:00', u'insertTime': u'2013-05-27T11:01:35.390-07:00', u'targetId': u'11748720697396371259', u'targetLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/firewalls/appscalecgb20', u'operationType': u'delete', u'progress': 0, u'id': u'15574488986772298961', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/operations/operation-1369677695390-4ddb6f07cc611-5a8f1654', u'user': u'*****@*****.**' } fake_delete_firewall_request = flexmock( name='fake_delete_firewall_request') fake_delete_firewall_request.should_receive('execute').and_return( fake_delete_firewall_info) fake_firewalls = flexmock(name='fake_firewalls') fake_firewalls.should_receive('delete').with_args( project=project_id, firewall=self.group).and_return(fake_delete_firewall_request) fake_gce.should_receive('firewalls').and_return(fake_firewalls) # mock out the call to make sure the firewall was deleted fake_firewall_checker = flexmock(name='fake_firewall_checker') fake_firewall_checker.should_receive('execute').and_return(all_done) fake_blocker.should_receive('get').with_args( project=project_id, operation=delete_firewall).and_return(fake_firewall_checker) fake_gce.should_receive('globalOperations').and_return(fake_blocker) # and the call to delete the network delete_network = u'operation-1369677749954-4ddb6f3bd1849-056cf8ca' fake_delete_network_info = { u'status': u'PENDING', u'kind': u'compute#operation', u'name': delete_network, u'startTime': u'2013-05-27T11:02:30.012-07:00', u'insertTime': u'2013-05-27T11:02:29.954-07:00', u'targetId': u'17688075350400527692', u'targetLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/appscalecgb20', u'operationType': u'delete', u'progress': 0, u'id': u'12623697331874594836', u'selfLink': u'https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/operations/operation-1369677749954-4ddb6f3bd1849-056cf8ca', u'user': u'*****@*****.**' } fake_delete_network_request = flexmock( name='fake_delete_network_request') fake_delete_network_request.should_receive('execute').and_return( fake_delete_network_info) fake_networks = flexmock(name='fake_networks') fake_networks.should_receive('delete').with_args( project=project_id, network=self.group).and_return(fake_delete_network_request) fake_gce.should_receive('networks').and_return(fake_networks) # mock out the call to make sure the network was deleted fake_network_checker = flexmock(name='fake_network_checker') fake_network_checker.should_receive('execute').and_return(all_done) fake_blocker.should_receive('get').with_args( project=project_id, operation=delete_network).and_return(fake_network_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) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive('remove').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_secret_key_location(self.keyname)).and_return() argv = ["--keyname", self.keyname, "--test"] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_terminate_in_virtual_cluster_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_secret_key_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') fake_yaml_file = flexmock(name='fake_file') fake_yaml_file.should_receive('read').and_return( yaml.dump({'infrastructure': 'xen'})) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_yaml_file) # mock out reading the json file, and pretend that we're running in a # two node deployment os.path.should_receive('exists').with_args( LocalState.get_locations_json_location( self.keyname)).and_return(True) fake_json_file = flexmock(name='fake_file') fake_json_file.should_receive('read').and_return( json.dumps([{ 'public_ip': 'public1', 'jobs': ['shadow'] }, { 'public_ip': 'public2', 'jobs': ['appengine'] }])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_json_file) # and slip in a fake secret file fake_secret_file = flexmock(name='fake_file') fake_secret_file.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args( LocalState.get_secret_key_location(self.keyname), 'r') \ .and_return(fake_secret_file) # mock out talking to the appcontroller, and assume that it tells us there # there are still two machines in this deployment fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('get_all_public_ips').with_args('the secret') \ .and_return(json.dumps(['public1', 'public2'])) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://public1:17443') \ .and_return(fake_appcontroller) # and mock out the ssh call to kill the remote appcontroller, assuming that # it fails the first time and passes the second flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('controller stop'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.failed).and_return(self.success) # next, mock out our checks to see how the stopping process is going and # assume that it has stopped flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ps x'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive('remove').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_secret_key_location(self.keyname)).and_return() # also mock out asking the user for confirmation on shutting down # their cloud builtins.should_receive('raw_input').and_return('yes') argv = ["--keyname", self.keyname] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_terminate_in_gce_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call("exists") # set up the fall-through os.path.should_receive("exists").with_args(LocalState.get_secret_key_location(self.keyname)).and_return(True) os.path.should_receive("exists").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return( True ) os.path.should_receive("exists").with_args(LocalState.get_client_secrets_location(self.keyname)).and_return( True ) # mock out reading the locations.yaml file, and pretend that we're on # GCE project_id = "1234567890" zone = "my-zone-1b" builtins = flexmock(sys.modules["__builtin__"]) builtins.should_call("open") fake_yaml_file = flexmock(name="fake_file") fake_yaml_file.should_receive("read").and_return( yaml.dump({"infrastructure": "gce", "group": self.group, "project": project_id, "zone": zone}) ) builtins.should_receive("open").with_args(LocalState.get_locations_yaml_location(self.keyname), "r").and_return( fake_yaml_file ) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name="fake_file") fake_json_file.should_receive("read").and_return( json.dumps([{"public_ip": "public1", "jobs": ["shadow"]}, {"public_ip": "public2", "jobs": ["appengine"]}]) ) builtins.should_receive("open").with_args(LocalState.get_locations_json_location(self.keyname), "r").and_return( fake_json_file ) # and slip in a fake secret file fake_secret_file = flexmock(name="fake_file") fake_secret_file.should_receive("read").and_return("the secret") builtins.should_receive("open").with_args(LocalState.get_secret_key_location(self.keyname), "r").and_return( fake_secret_file ) # also add in a fake client-secrets file for GCE client_secrets = LocalState.get_client_secrets_location(self.keyname) # mock out talking to 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(client_secrets, scope=str).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(str).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) fake_gce = flexmock(name="fake_gce") # let's say that two instances are running instance_one_info = { 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": u"appscale-bazboogroup-one", 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-bazboogroup-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"public1", } ], u"networkIP": u"private1", u"network": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazboogroup", u"name": u"nic0", } ], } instance_two_info = { 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": u"appscale-bazboogroup-two", 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-bazboogroup-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"public1", } ], u"networkIP": u"private1", u"network": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/bazboogroup", u"name": u"nic0", } ], } list_instance_info = { u"items": [instance_one_info, instance_two_info], 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( list_instance_info ) fake_instances = flexmock(name="fake_instances") fake_instances.should_receive("list").with_args( project=project_id, filter="name eq appscale-bazboogroup-.*", zone=zone ).and_return(fake_list_instance_request) fake_gce.should_receive("instances").and_return(fake_instances) # And assume that we can kill both of our instances fine delete_instance = u"operation-1369676691806-4ddb6b4ab6f39-a095d3de" delete_instance_info_one = { u"status": u"PENDING", u"kind": u"compute#operation", u"name": delete_instance, u"zone": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b", u"startTime": u"2013-05-27T10:44:51.849-07:00", u"insertTime": u"2013-05-27T10:44:51.806-07:00", u"targetId": u"12912855597472179535", u"targetLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/instances/appscale-appscalecgb20-0cf89267-5887-4048-b774-ca20de47a07f", u"operationType": u"delete", u"progress": 0, u"id": u"11114355109942058217", u"selfLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/operations/operation-1369676691806-4ddb6b4ab6f39-a095d3de", u"user": u"*****@*****.**", } delete_instance_info_two = { u"status": u"PENDING", u"kind": u"compute#operation", u"name": delete_instance, u"zone": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b", u"startTime": u"2013-05-27T10:44:51.849-07:00", u"insertTime": u"2013-05-27T10:44:51.806-07:00", u"targetId": u"12912855597472179535", u"targetLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/instances/appscale-appscalecgb20-0cf89267-5887-4048-b774-ca20de47a07f", u"operationType": u"delete", u"progress": 0, u"id": u"11114355109942058217", u"selfLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/zones/my-zone-1b/operations/operation-1369676691806-4ddb6b4ab6f39-a095d3de", u"user": u"*****@*****.**", } fake_delete_instance_request_one = flexmock(name="fake_delete_instance_request_one") fake_delete_instance_request_one.should_receive("execute").with_args(http=fake_authorized_http).and_return( delete_instance_info_one ) fake_instances.should_receive("delete").with_args( project=project_id, zone=zone, instance="appscale-bazboogroup-one" ).and_return(fake_delete_instance_request_one) fake_delete_instance_request_two = flexmock(name="fake_delete_instance_request_two") fake_delete_instance_request_two.should_receive("execute").with_args(http=fake_authorized_http).and_return( delete_instance_info_two ) fake_instances.should_receive("delete").with_args( project=project_id, zone=zone, instance="appscale-bazboogroup-two" ).and_return(fake_delete_instance_request_two) # mock out our waiting for the instances to be deleted all_done = {u"status": u"DONE"} fake_instance_checker = flexmock(name="fake_instance_checker") fake_instance_checker.should_receive("execute").and_return(all_done) fake_blocker = flexmock(name="fake_blocker") fake_blocker.should_receive("get").with_args( project=project_id, operation=delete_instance, zone=zone ).and_return(fake_instance_checker) fake_gce.should_receive("zoneOperations").and_return(fake_blocker) # mock out the call to delete the firewall delete_firewall = u"operation-1369677695390-4ddb6f07cc611-5a8f1654" fake_delete_firewall_info = { u"status": u"PENDING", u"kind": u"compute#operation", u"name": delete_firewall, u"startTime": u"2013-05-27T11:01:35.482-07:00", u"insertTime": u"2013-05-27T11:01:35.390-07:00", u"targetId": u"11748720697396371259", u"targetLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/firewalls/appscalecgb20", u"operationType": u"delete", u"progress": 0, u"id": u"15574488986772298961", u"selfLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/operations/operation-1369677695390-4ddb6f07cc611-5a8f1654", u"user": u"*****@*****.**", } fake_delete_firewall_request = flexmock(name="fake_delete_firewall_request") fake_delete_firewall_request.should_receive("execute").and_return(fake_delete_firewall_info) fake_firewalls = flexmock(name="fake_firewalls") fake_firewalls.should_receive("delete").with_args(project=project_id, firewall=self.group).and_return( fake_delete_firewall_request ) fake_gce.should_receive("firewalls").and_return(fake_firewalls) # mock out the call to make sure the firewall was deleted fake_firewall_checker = flexmock(name="fake_firewall_checker") fake_firewall_checker.should_receive("execute").and_return(all_done) fake_blocker.should_receive("get").with_args(project=project_id, operation=delete_firewall).and_return( fake_firewall_checker ) fake_gce.should_receive("globalOperations").and_return(fake_blocker) # and the call to delete the network delete_network = u"operation-1369677749954-4ddb6f3bd1849-056cf8ca" fake_delete_network_info = { u"status": u"PENDING", u"kind": u"compute#operation", u"name": delete_network, u"startTime": u"2013-05-27T11:02:30.012-07:00", u"insertTime": u"2013-05-27T11:02:29.954-07:00", u"targetId": u"17688075350400527692", u"targetLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/networks/appscalecgb20", u"operationType": u"delete", u"progress": 0, u"id": u"12623697331874594836", u"selfLink": u"https://www.googleapis.com/compute/v1beta14/projects/appscale.com:appscale/global/operations/operation-1369677749954-4ddb6f3bd1849-056cf8ca", u"user": u"*****@*****.**", } fake_delete_network_request = flexmock(name="fake_delete_network_request") fake_delete_network_request.should_receive("execute").and_return(fake_delete_network_info) fake_networks = flexmock(name="fake_networks") fake_networks.should_receive("delete").with_args(project=project_id, network=self.group).and_return( fake_delete_network_request ) fake_gce.should_receive("networks").and_return(fake_networks) # mock out the call to make sure the network was deleted fake_network_checker = flexmock(name="fake_network_checker") fake_network_checker.should_receive("execute").and_return(all_done) fake_blocker.should_receive("get").with_args(project=project_id, operation=delete_network).and_return( fake_network_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) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive("remove").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive("remove").with_args(LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive("remove").with_args(LocalState.get_secret_key_location(self.keyname)).and_return() argv = ["--keyname", self.keyname, "--test"] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_terminate_in_virtual_cluster_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call("exists") # set up the fall-through os.path.should_receive("exists").with_args(LocalState.get_secret_key_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules["__builtin__"]) builtins.should_call("open") fake_yaml_file = flexmock(name="fake_file") fake_yaml_file.should_receive("read").and_return(yaml.dump({"infrastructure": "xen"})) builtins.should_receive("open").with_args(LocalState.get_locations_yaml_location(self.keyname), "r").and_return( fake_yaml_file ) # mock out reading the json file, and pretend that we're running in a # two node deployment os.path.should_receive("exists").with_args(LocalState.get_locations_json_location(self.keyname)).and_return( True ) fake_json_file = flexmock(name="fake_file") fake_json_file.should_receive("read").and_return( json.dumps([{"public_ip": "public1", "jobs": ["shadow"]}, {"public_ip": "public2", "jobs": ["appengine"]}]) ) builtins.should_receive("open").with_args(LocalState.get_locations_json_location(self.keyname), "r").and_return( fake_json_file ) # and slip in a fake secret file fake_secret_file = flexmock(name="fake_file") fake_secret_file.should_receive("read").and_return("the secret") builtins.should_receive("open").with_args(LocalState.get_secret_key_location(self.keyname), "r").and_return( fake_secret_file ) # mock out talking to the appcontroller, and assume that it tells us there # there are still two machines in this deployment fake_appcontroller = flexmock(name="fake_appcontroller") fake_appcontroller.should_receive("get_all_public_ips").with_args("the secret").and_return( json.dumps(["public1", "public2"]) ) flexmock(SOAPpy) SOAPpy.should_receive("SOAPProxy").with_args("https://public1:17443").and_return(fake_appcontroller) # and mock out the ssh call to kill the remote appcontroller, assuming that # it fails the first time and passes the second flexmock(subprocess) subprocess.should_receive("Popen").with_args( re.compile("controller stop"), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT ).and_return(self.failed).and_return(self.success) # next, mock out our checks to see how the stopping process is going and # assume that it has stopped flexmock(subprocess) subprocess.should_receive("Popen").with_args( re.compile("ps x"), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT ).and_return(self.success) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive("remove").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive("remove").with_args(LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive("remove").with_args(LocalState.get_secret_key_location(self.keyname)).and_return() # also mock out asking the user for confirmation on shutting down # their cloud builtins.should_receive("raw_input").and_return("yes") argv = ["--keyname", self.keyname] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_appscale_in_one_node_virt_deployment(self): # let's say that appscale isn't already running flexmock(os.path) os.path.should_call('exists') os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return(False) # mock out talking to logs.appscale.com fake_connection = flexmock(name='fake_connection') fake_connection.should_receive('request').with_args('POST', '/upload', str, AppScaleLogger.HEADERS).and_return() flexmock(httplib) httplib.should_receive('HTTPSConnection').with_args('logs.appscale.com') \ .and_return(fake_connection) # mock out generating the secret key flexmock(uuid) uuid.should_receive('uuid4').and_return('the secret') # mock out writing the secret key to ~/.appscale, as well as reading it # later builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through secret_key_location = LocalState.get_secret_key_location(self.keyname) fake_secret = flexmock(name="fake_secret") fake_secret.should_receive('read').and_return('the secret') fake_secret.should_receive('write').and_return() builtins.should_receive('open').with_args(secret_key_location, 'r') \ .and_return(fake_secret) builtins.should_receive('open').with_args(secret_key_location, 'w') \ .and_return(fake_secret) # mock out seeing if the image is appscale-compatible, and assume it is # mock out our attempts to find /etc/appscale and presume it does exist flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('/etc/appscale'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # mock out our attempts to find /etc/appscale/version and presume it does # exist subprocess.should_receive('Popen').with_args(re.compile( '/etc/appscale/{0}'.format(APPSCALE_VERSION)), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # put in a mock indicating that the database the user wants is supported subprocess.should_receive('Popen').with_args(re.compile( '/etc/appscale/{0}/{1}'.format(APPSCALE_VERSION, 'cassandra')), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # mock out generating the private key flexmock(M2Crypto.RSA) fake_rsa_key = flexmock(name='fake_rsa_key') fake_rsa_key.should_receive('save_key').with_args( LocalState.get_private_key_location(self.keyname), None) M2Crypto.RSA.should_receive('gen_key').and_return(fake_rsa_key) flexmock(M2Crypto.EVP) fake_pkey = flexmock(name='fake_pkey') fake_pkey.should_receive('assign_rsa').with_args(fake_rsa_key).and_return() M2Crypto.EVP.should_receive('PKey').and_return(fake_pkey) # and mock out generating the certificate flexmock(M2Crypto.X509) fake_cert = flexmock(name='fake_x509') fake_cert.should_receive('set_pubkey').with_args(fake_pkey).and_return() fake_cert.should_receive('set_subject') fake_cert.should_receive('set_issuer_name') fake_cert.should_receive('set_not_before') fake_cert.should_receive('set_not_after') fake_cert.should_receive('sign').with_args(fake_pkey, md="sha256") fake_cert.should_receive('save_pem').with_args( LocalState.get_certificate_location(self.keyname)) M2Crypto.X509.should_receive('X509').and_return(fake_cert) # assume that we started god fine subprocess.should_receive('Popen').with_args(re.compile('god &'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # and that we copied over the AppController's god file subprocess.should_receive('Popen').with_args(re.compile( 'appcontroller.god'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # also, that we started the AppController itself subprocess.should_receive('Popen').with_args(re.compile('god load'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that the AppController comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('1.2.3.4', AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # same for the UserAppServer fake_socket.should_receive('connect').with_args(('1.2.3.4', UserAppClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # as well as for the AppLoadBalancer fake_socket.should_receive('connect').with_args(('1.2.3.4', RemoteHelper.APP_LOAD_BALANCER_PORT)).and_raise(Exception) \ .and_raise(Exception).and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('set_parameters').with_args(list, list, ['none'], 'the secret').and_return('OK') fake_appcontroller.should_receive('get_all_public_ips').with_args('the secret') \ .and_return(json.dumps(['1.2.3.4'])) role_info = [{ 'public_ip' : '1.2.3.4', 'private_ip' : '1.2.3.4', 'jobs' : ['shadow', 'login'] }] fake_appcontroller.should_receive('get_role_info').with_args('the secret') \ .and_return(json.dumps(role_info)) fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('nothing interesting here') \ .and_return('Database is at not-up-yet') \ .and_return('Database is at 1.2.3.4') fake_appcontroller.should_receive('is_done_initializing') \ .and_raise(Exception) \ .and_return(False) \ .and_return(True) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://1.2.3.4:17443') \ .and_return(fake_appcontroller) # mock out reading the locations.json file, and slip in our own json os.path.should_receive('exists').with_args( LocalState.get_locations_json_location(self.keyname)).and_return(True) fake_nodes_json = flexmock(name="fake_nodes_json") fake_nodes_json.should_receive('read').and_return(json.dumps([{ "public_ip" : "1.2.3.4", "private_ip" : "1.2.3.4", "jobs" : ["shadow", "login"] }])) fake_nodes_json.should_receive('write').and_return() builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_nodes_json) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'w') \ .and_return(fake_nodes_json) # copying over the locations yaml and json files should be fine subprocess.should_receive('Popen').with_args(re.compile( 'locations-{0}.[yaml|json]'.format(self.keyname)), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # same for the secret key subprocess.should_receive('Popen').with_args(re.compile( '{0}.secret'.format(self.keyname)), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # mock out calls to the UserAppServer and presume that calls to create new # users succeed fake_userappserver = flexmock(name='fake_appcontroller') fake_userappserver.should_receive('commit_new_user').with_args( '*****@*****.**', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('commit_new_user').with_args( '[email protected]', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('set_cloud_admin_status').with_args( '*****@*****.**', 'true', 'the secret').and_return() fake_userappserver.should_receive('set_capabilities').with_args( '*****@*****.**', UserAppClient.ADMIN_CAPABILITIES, 'the secret').and_return() SOAPpy.should_receive('SOAPProxy').with_args('https://1.2.3.4:4343') \ .and_return(fake_userappserver) # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_layout = yaml.safe_load(""" master : 1.2.3.4 database: 1.2.3.4 zookeeper: 1.2.3.4 appengine: 1.2.3.4 """) argv = [ "--ips_layout", base64.b64encode(yaml.dump(ips_layout)), "--keyname", self.keyname, "--test" ] options = ParseArgs(argv, self.function).args AppScaleTools.run_instances(options)