def get_params_from_yaml(self, keyname): """ Searches through the locations.yaml file 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. """ # Perform OAuth 2.0 authorization. flow = None if self.PARAM_SECRETS in parameters: flow = oauth2client.client.flow_from_clientsecrets( os.path.expanduser(parameters[self.PARAM_SECRETS]), 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: credentials = oauth2client.tools.run(flow, storage) # Build the service return apiclient.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. """ # Perform OAuth 2.0 authorization. flow = None if self.PARAM_SECRETS in parameters: flow = oauth2client.client.flow_from_clientsecrets( os.path.expanduser(parameters[self.PARAM_SECRETS]), 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: credentials = oauth2client.tools.run(flow, storage) # Build the service return apiclient.discovery.build('compute', self.API_VERSION), credentials
def get_params_from_yaml(self, keyname): """ Searches through the locations.yaml file 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 copy_deployment_credentials(cls, host, options): """Copies credentials needed to start the AppController and have it create other instances (in cloud deployments). Args: host: A str representing the machine (reachable from this computer) to copy our deployment credentials to. options: A Namespace that indicates which SSH keypair to use, and whether or not we are running in a cloud infrastructure. """ cls.scp(host, options.keyname, LocalState.get_secret_key_location(options.keyname), '/etc/appscale/secret.key', options.verbose) cls.scp(host, options.keyname, LocalState.get_key_path_from_name(options.keyname), '/etc/appscale/ssh.key', options.verbose) LocalState.generate_ssl_cert(options.keyname, options.verbose) cls.scp(host, options.keyname, LocalState.get_certificate_location(options.keyname), '/etc/appscale/certs/mycert.pem', options.verbose) cls.scp(host, options.keyname, LocalState.get_private_key_location(options.keyname), '/etc/appscale/certs/mykey.pem', options.verbose) hash_id = subprocess.Popen([ "openssl", "x509", "-hash", "-noout", "-in", LocalState.get_certificate_location(options.keyname) ], stdout=subprocess.PIPE).communicate()[0] cls.ssh(host, options.keyname, 'ln -fs /etc/appscale/certs/mycert.pem /etc/ssl/certs/{0}.0'.\ format(hash_id.rstrip()), options.verbose) AppScaleLogger.log("Copying over deployment credentials") cert = LocalState.get_certificate_location(options.keyname) private_key = LocalState.get_private_key_location(options.keyname) cls.ssh(host, options.keyname, 'mkdir -p /etc/appscale/keys/cloud1', options.verbose) cls.scp(host, options.keyname, cert, "/etc/appscale/keys/cloud1/mycert.pem", options.verbose) cls.scp(host, options.keyname, private_key, "/etc/appscale/keys/cloud1/mykey.pem", options.verbose) # In Google Compute Engine, we also need to copy over our client_secrets # file and the OAuth2 file that the user has approved for use with their # credentials, otherwise the AppScale VMs won't be able to interact with # GCE. if options.infrastructure and options.infrastructure == 'gce': if os.path.exists(LocalState.get_client_secrets_location( \ options.keyname)): cls.scp( host, options.keyname, LocalState.get_client_secrets_location(options.keyname), '/etc/appscale/client_secrets.json', options.verbose) cls.scp(host, options.keyname, LocalState.get_oauth2_storage_location(options.keyname), '/etc/appscale/oauth2.dat', options.verbose)
def copy_deployment_credentials(cls, host, options): """Copies credentials needed to start the AppController and have it create other instances (in cloud deployments). Args: host: A str representing the machine (reachable from this computer) to copy our deployment credentials to. options: A Namespace that indicates which SSH keypair to use, and whether or not we are running in a cloud infrastructure. """ local_secret_key = LocalState.get_secret_key_location(options.keyname) cls.scp(host, options.keyname, local_secret_key, '{}/secret.key'.format(cls.CONFIG_DIR), options.verbose) local_ssh_key = LocalState.get_key_path_from_name(options.keyname) cls.scp(host, options.keyname, local_ssh_key, '{}/ssh.key'.format(cls.CONFIG_DIR), options.verbose) LocalState.generate_ssl_cert(options.keyname, options.verbose) local_cert = LocalState.get_certificate_location(options.keyname) cls.scp(host, options.keyname, local_cert, '{}/certs/mycert.pem'.format(cls.CONFIG_DIR), options.verbose) local_private_key = LocalState.get_private_key_location( options.keyname) cls.scp(host, options.keyname, local_private_key, '{}/certs/mykey.pem'.format(cls.CONFIG_DIR), options.verbose) hash_id = subprocess.Popen([ "openssl", "x509", "-hash", "-noout", "-in", LocalState.get_certificate_location(options.keyname) ], stdout=subprocess.PIPE).communicate()[0] symlink_cert = 'ln -fs {}/certs/mycert.pem /etc/ssl/certs/{}.0'.\ format(cls.CONFIG_DIR, hash_id.rstrip()) cls.ssh(host, options.keyname, symlink_cert, options.verbose) # In Google Compute Engine, we also need to copy over our client_secrets # file and the OAuth2 file that the user has approved for use with their # credentials, otherwise the AppScale VMs won't be able to interact with # GCE. if options.infrastructure and options.infrastructure == 'gce': secrets_location = LocalState.get_client_secrets_location( options.keyname) if not os.path.exists(secrets_location): raise AppScaleException( '{} does not exist.'.format(secrets_location)) secrets_type = GCEAgent.get_secrets_type(secrets_location) cls.scp(host, options.keyname, secrets_location, '{}/client_secrets.json'.format(cls.CONFIG_DIR), options.verbose) if secrets_type == CredentialTypes.OAUTH: local_oauth = LocalState.get_oauth2_storage_location( options.keyname) cls.scp(host, options.keyname, local_oauth, '{}/oauth2.dat'.format(cls.CONFIG_DIR), options.verbose)
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']) elif args.get('oauth2_storage'): destination = LocalState.get_oauth2_storage_location( args['keyname']) shutil.copy(full_credentials, destination) params = { self.PARAM_GROUP: args['group'], self.PARAM_IMAGE_ID: args['machine'], self.PARAM_INSTANCE_TYPE: args['gce_instance_type'], self.PARAM_KEYNAME: args['keyname'], self.PARAM_PROJECT: args['project'], self.PARAM_ZONE: args['zone'] } 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) return params
def copy_deployment_credentials(cls, host, options): """Copies credentials needed to start the AppController and have it create other instances (in cloud deployments). Args: host: A str representing the machine (reachable from this computer) to copy our deployment credentials to. options: A Namespace that indicates which SSH keypair to use, and whether or not we are running in a cloud infrastructure. """ cls.scp(host, options.keyname, LocalState.get_secret_key_location( options.keyname), '/etc/appscale/secret.key', options.verbose) cls.scp(host, options.keyname, LocalState.get_key_path_from_name( options.keyname), '/etc/appscale/ssh.key', options.verbose) LocalState.generate_ssl_cert(options.keyname, options.verbose) cls.scp(host, options.keyname, LocalState.get_certificate_location( options.keyname), '/etc/appscale/certs/mycert.pem', options.verbose) cls.scp(host, options.keyname, LocalState.get_private_key_location( options.keyname), '/etc/appscale/certs/mykey.pem', options.verbose) hash_id = subprocess.Popen(["openssl", "x509", "-hash", "-noout", "-in", LocalState.get_certificate_location(options.keyname)], stdout=subprocess.PIPE).communicate()[0] cls.ssh(host, options.keyname, 'ln -fs /etc/appscale/certs/mycert.pem /etc/ssl/certs/{0}.0'.\ format(hash_id.rstrip()), options.verbose) AppScaleLogger.log("Copying over deployment credentials") cert = LocalState.get_certificate_location(options.keyname) private_key = LocalState.get_private_key_location(options.keyname) cls.ssh(host, options.keyname, 'mkdir -p /etc/appscale/keys/cloud1', options.verbose) cls.scp(host, options.keyname, cert, "/etc/appscale/keys/cloud1/mycert.pem", options.verbose) cls.scp(host, options.keyname, private_key, "/etc/appscale/keys/cloud1/mykey.pem", options.verbose) # In Google Compute Engine, we also need to copy over our client_secrets # file and the OAuth2 file that the user has approved for use with their # credentials, otherwise the AppScale VMs won't be able to interact with # GCE. if options.infrastructure and options.infrastructure == 'gce': if os.path.exists(LocalState.get_client_secrets_location( \ options.keyname)): cls.scp(host, options.keyname, LocalState.get_client_secrets_location( options.keyname), '/etc/appscale/client_secrets.json', options.verbose) cls.scp(host, options.keyname, LocalState.get_oauth2_storage_location( options.keyname), '/etc/appscale/oauth2.dat', options.verbose)
def copy_deployment_credentials(cls, host, options): """Copies credentials needed to start the AppController and have it create other instances (in cloud deployments). Args: host: A str representing the machine (reachable from this computer) to copy our deployment credentials to. options: A Namespace that indicates which SSH keypair to use, and whether or not we are running in a cloud infrastructure. """ local_secret_key = LocalState.get_secret_key_location(options.keyname) cls.scp(host, options.keyname, local_secret_key, '{}/secret.key'.format(cls.CONFIG_DIR), options.verbose) local_ssh_key = LocalState.get_key_path_from_name(options.keyname) cls.scp(host, options.keyname, local_ssh_key, '{}/ssh.key'.format(cls.CONFIG_DIR), options.verbose) LocalState.generate_ssl_cert(options.keyname, options.verbose) local_cert = LocalState.get_certificate_location(options.keyname) cls.scp(host, options.keyname, local_cert, '{}/certs/mycert.pem'.format(cls.CONFIG_DIR), options.verbose) local_private_key = LocalState.get_private_key_location(options.keyname) cls.scp(host, options.keyname, local_private_key, '{}/certs/mykey.pem'.format(cls.CONFIG_DIR), options.verbose) hash_id = subprocess.Popen(["openssl", "x509", "-hash", "-noout", "-in", LocalState.get_certificate_location(options.keyname)], stdout=subprocess.PIPE).communicate()[0] symlink_cert = 'ln -fs {}/certs/mycert.pem /etc/ssl/certs/{}.0'.\ format(cls.CONFIG_DIR, hash_id.rstrip()) cls.ssh(host, options.keyname, symlink_cert, options.verbose) # In Google Compute Engine, we also need to copy over our client_secrets # file and the OAuth2 file that the user has approved for use with their # credentials, otherwise the AppScale VMs won't be able to interact with # GCE. if options.infrastructure and options.infrastructure == 'gce': secrets_location = LocalState.get_client_secrets_location(options.keyname) if not os.path.exists(secrets_location): raise AppScaleException('{} does not exist.'.format(secrets_location)) secrets_type = GCEAgent.get_secrets_type(secrets_location) cls.scp(host, options.keyname, secrets_location, '{}/client_secrets.json'.format(cls.CONFIG_DIR), options.verbose) if secrets_type == CredentialTypes.OAUTH: local_oauth = LocalState.get_oauth2_storage_location(options.keyname) cls.scp(host, options.keyname, local_oauth, '{}/oauth2.dat'.format(cls.CONFIG_DIR), options.verbose)
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']) elif args.get('oauth2_storage'): destination = LocalState.get_oauth2_storage_location( args['keyname']) shutil.copy(full_credentials, destination) params = { self.PARAM_GROUP: args['group'], self.PARAM_IMAGE_ID: args['machine'], self.PARAM_INSTANCE_TYPE: args['gce_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'] } # 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