def get_cloud_params(self, keyname): """ Searches through the locations.json file with key 'infrastructure_info' to build a dict containing the parameters necessary to interact with Google Compute Engine. Args: keyname: A str that uniquely identifies this AppScale deployment. Returns: A dict containing all of the credentials necessary to interact with Google Compute Engine. """ params = { self.PARAM_GROUP : LocalState.get_group(keyname), self.PARAM_KEYNAME : keyname, self.PARAM_PROJECT : LocalState.get_project(keyname), self.PARAM_VERBOSE : False, # TODO(cgb): Don't put False in here. self.PARAM_ZONE : LocalState.get_zone(keyname) } if os.path.exists(LocalState.get_client_secrets_location(keyname)): params[self.PARAM_SECRETS] = \ LocalState.get_client_secrets_location(keyname) else: params[self.PARAM_STORAGE] = \ LocalState.get_oauth2_storage_location(keyname) return params
def open_connection(self, parameters): """ Connects to Google Compute Engine with the given credentials. Args: parameters: A dict that contains all the parameters necessary to authenticate this user with Google Compute Engine. We assume that the user has already authorized this account for use with GCE. Returns: An apiclient.discovery.Resource that is a connection valid for requests to Google Compute Engine for the given user, and a Credentials object that can be used to sign requests performed with that connection. Raises: AppScaleException if the user wants to abort. """ is_autoscale_agent = parameters.get(self.PARAM_AUTOSCALE_AGENT, False) # Determine paths to credential files if is_autoscale_agent: client_secrets_path = self.CLIENT_SECRETS_LOCATION oauth2_storage_path = self.OAUTH2_STORAGE_LOCATION else: # Determine client secrets path client_secrets_path = LocalState.get_client_secrets_location( parameters[self.PARAM_KEYNAME]) if not os.path.exists(client_secrets_path): client_secrets_path = parameters.get(self.PARAM_SECRETS, '') # Determine oauth2 storage oauth2_storage_path = parameters.get(self.PARAM_STORAGE) if not oauth2_storage_path or not os.path.exists(oauth2_storage_path): oauth2_storage_path = LocalState.get_oauth2_storage_location( parameters[self.PARAM_KEYNAME]) if os.path.exists(client_secrets_path): # Attempt to perform authorization using Service account secrets_type = GCEAgent.get_secrets_type(client_secrets_path) if secrets_type == CredentialTypes.SERVICE: scopes = [GCPScopes.COMPUTE] credentials = ServiceAccountCredentials.from_json_keyfile_name( client_secrets_path, scopes=scopes) return discovery.build('compute', self.API_VERSION), credentials # Perform authorization using OAuth2 storage storage = oauth2client.file.Storage(oauth2_storage_path) credentials = storage.get() if not credentials or credentials.invalid: # If we couldn't get valid credentials from OAuth2 storage if not os.path.exists(client_secrets_path): raise AgentConfigurationException( 'Couldn\'t find client secrets file at {}'.format(client_secrets_path) ) # Run OAuth2 flow to get credentials flow = oauth2client.client.flow_from_clientsecrets( client_secrets_path, scope=self.GCE_SCOPE) flags = oauth2client.tools.argparser.parse_args(args=[]) credentials = oauth2client.tools.run_flow(flow, storage, flags) # Build the service return discovery.build('compute', self.API_VERSION), credentials
def open_connection(self, parameters): """ Connects to Google Compute Engine with the given credentials. Args: parameters: A dict that contains all the parameters necessary to authenticate this user with Google Compute Engine. We assume that the user has already authorized this account for use with GCE. Returns: An apiclient.discovery.Resource that is a connection valid for requests to Google Compute Engine for the given user, and a Credentials object that can be used to sign requests performed with that connection. Raises: AppScaleException if the user wants to abort. """ # Perform OAuth 2.0 authorization. flow = None if self.PARAM_SECRETS in parameters: secrets_location = os.path.expanduser(parameters[self.PARAM_SECRETS]) secrets_type = GCEAgent.get_secrets_type(secrets_location) if secrets_type == CredentialTypes.SERVICE: scopes = [GCPScopes.COMPUTE] credentials = ServiceAccountCredentials\ .from_json_keyfile_name(secrets_location, scopes=scopes) return discovery.build('compute', self.API_VERSION), credentials else: flow = oauth2client.client.flow_from_clientsecrets(secrets_location, scope=self.GCE_SCOPE) storage = oauth2client.file.Storage(LocalState.get_oauth2_storage_location( parameters[self.PARAM_KEYNAME])) credentials = storage.get() if credentials is None or credentials.invalid: flags = oauth2client.tools.argparser.parse_args(args=[]) credentials = oauth2client.tools.run_flow(flow, storage, flags) # Build the service return discovery.build('compute', self.API_VERSION), credentials
def get_params_from_args(self, args): """ Constructs a dict with only the parameters necessary to interact with Google Compute Engine (here, the client_secrets file and the image name). Args: args: A Namespace or dict that maps all of the arguments the user has invoked an AppScale command with their associated value. Returns: A dict containing the location of the client_secrets file and that name of the image to use in GCE. Raises: AgentConfigurationException: If the caller fails to specify a client_secrets file, or if it doesn't exist on the local filesystem. """ if not isinstance(args, dict): args = vars(args) if not args.get('client_secrets') and not args.get('oauth2_storage'): raise AgentConfigurationException("Please specify a client_secrets " + \ "file or a oauth2_storage file in your AppScalefile when running " + \ "over Google Compute Engine.") credentials_file = args.get('client_secrets') or args.get('oauth2_storage') full_credentials = os.path.expanduser(credentials_file) if not os.path.exists(full_credentials): raise AgentConfigurationException("Couldn't find your credentials " + \ "at {0}".format(full_credentials)) if args.get('client_secrets'): destination = LocalState.get_client_secrets_location(args['keyname']) # Make sure the destination's parent directory exists. destination_par = os.path.abspath(os.path.join(destination, os.pardir)) if not os.path.exists(destination_par): os.makedirs(destination_par) shutil.copy(full_credentials, destination) elif args.get('oauth2_storage'): destination = LocalState.get_oauth2_storage_location(args['keyname']) # Make sure the destination's parent directory exists. destination_par = os.path.abspath(os.path.join(destination, os.pardir)) if not os.path.exists(destination_par): os.makedirs(destination_par) shutil.copy(full_credentials, destination) params = { self.PARAM_GROUP : args['group'], self.PARAM_IMAGE_ID : args['machine'], self.PARAM_INSTANCE_TYPE : args[self.PARAM_INSTANCE_TYPE], self.PARAM_KEYNAME : args['keyname'], self.PARAM_PROJECT : args['project'], self.PARAM_STATIC_IP : args.get(self.PARAM_STATIC_IP), self.PARAM_ZONE : args['zone'], self.PARAM_TEST: args['test'], } # A zone in GCE looks like 'us-central2-a', which is in the region # 'us-central2'. Therefore, strip off the last two characters from the zone # to get the region name. if params[self.PARAM_ZONE]: params[self.PARAM_REGION] = params[self.PARAM_ZONE][:-2] else: params[self.PARAM_REGION] = self.DEFAULT_REGION if args.get(self.PARAM_SECRETS): params[self.PARAM_SECRETS] = args.get(self.PARAM_SECRETS) elif args.get(self.PARAM_STORAGE): params[self.PARAM_STORAGE] = args.get(self.PARAM_STORAGE) params[self.PARAM_VERBOSE] = args.get('verbose', False) self.assert_credentials_are_valid(params) return params