def _GetInstanceRefsFromArgs(self, args): """Get validated refs to source and destination instances from args.""" resources = self.context['registry'] validate.ValidateInstanceName(args.source) validate.ValidateInstanceName(args.destination) source_instance_ref = resources.Parse( args.source, collection='sql.instances') destination_instance_ref = resources.Parse( args.destination, collection='sql.instances') self._CheckSourceAndDestination(source_instance_ref, destination_instance_ref) return source_instance_ref, destination_instance_ref
def Run(self, args): """Retrieves information about a Cloud SQL instance operation. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource if the api request was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') operation_ref = resources.Parse(args.operation, collection='sql.operations', params={ 'project': instance_ref.project, 'instance': instance_ref.instance }) result = sql_client.operations.Get(operation_ref.Request()) return result
def Run(self, args): """Lists all SSL certs for a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object that has the list of sslCerts resources if the api request was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') result = sql_client.sslCerts.List( sql_messages.SqlSslCertsListRequest( project=instance_ref.project, instance=instance_ref.instance)) return iter(result.items)
def Run(self, args): """Retrieves information about an SSL cert for a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the sslCerts resource if the api request was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') # sha1fingerprint, so that things can work with the resource parser. return cert.GetCertFromName(sql_client, sql_messages, instance_ref, args.common_name)
def Run(self, args): """Retrieves information about a backup. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object that has the backup run resource if the command ran successfully. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') instance = sql_client.instances.Get(instance_ref.Request()) # At this point we support only one backup-config. So, just use that id. backup_config = instance.settings.backupConfiguration[0].id request = sql_messages.SqlBackupRunsGetRequest( project=instance_ref.project, instance=instance_ref.instance, backupConfiguration=backup_config, dueTime=args.due_time) return sql_client.backupRuns.Get(request)
def Run(self, args): """Retrieves information about a backup. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object that has the backup run resource if the command ran successfully. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') request = sql_messages.SqlBackupRunsGetRequest( project=instance_ref.project, instance=instance_ref.instance, id=args.id) return sql_client.backupRuns.Get(request)
def Run(self, args): """Lists all backups associated with a given instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object that has the list of backup run resources if the command ran successfully. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') return apitools_base.YieldFromList( sql_client.backupRuns, sql_messages.SqlBackupRunsListRequest( project=instance_ref.project, instance=instance_ref.instance), args.limit)
def Run(self, args): """Exports data from a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the export operation if the export was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') # TODO(user): add support for CSV exporting. export_request = sql_messages.SqlInstancesExportRequest( instance=instance_ref.instance, project=instance_ref.project, instancesExportRequest=sql_messages.InstancesExportRequest( exportContext=sql_messages.ExportContext( uri=args.uri, databases=args.database or [], fileType='SQL', sqlExportOptions=( sql_messages.ExportContext.SqlExportOptionsValue( tables=args.table or [], )), ), ), ) result_operation = sql_client.instances.Export(export_request) operation_ref = resources.Create( 'sql.operations', operation=result_operation.name, project=instance_ref.project, instance=instance_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta4.WaitForOperation( sql_client, operation_ref, 'Exporting Cloud SQL instance') log.status.write('Exported [{instance}] to [{bucket}].\n'.format( instance=instance_ref, bucket=args.uri)) return None
def Run(self, args): """Sets the password of the MySQL root user. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the setRootPassword operation if the setRootPassword was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') if args.password_file: with open(args.password_file) as f: password = f.readline() else: password = args.password result = sql_client.instances.SetRootPassword( sql_messages.SqlInstancesSetRootPasswordRequest( project=instance_ref.project, instance=instance_ref.instance, instanceSetRootPasswordRequest=( sql_messages.InstanceSetRootPasswordRequest( setRootPasswordContext=( sql_messages.SetRootPasswordContext( password=password)))))) operation_ref = resources.Create( 'sql.operations', operation=result.operation, project=instance_ref.project, instance=instance_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta3.WaitForOperation( sql_client, operation_ref, 'Setting Cloud SQL instance password') log.status.write( 'Set password for [{instance}].\n'.format(instance=instance_ref)) return None
def Run(self, args): """Restores a backup of a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the restoreBackup operation if the restoreBackup was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') if not args.backup_instance: args.backup_instance = args.instance result_operation = sql_client.instances.RestoreBackup( sql_messages.SqlInstancesRestoreBackupRequest( project=instance_ref.project, instance=instance_ref.instance, instancesRestoreBackupRequest=( sql_messages.InstancesRestoreBackupRequest( restoreBackupContext=sql_messages.RestoreBackupContext( backupRunId=args.backup_id, instanceId=args.backup_instance, ))))) operation_ref = resources.Create( 'sql.operations', operation=result_operation.name, project=instance_ref.project, instance=instance_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta4.WaitForOperation( sql_client, operation_ref, 'Restoring Cloud SQL instance') log.status.write( 'Restored [{instance}].\n'.format(instance=instance_ref)) return None
def Run(self, args): """Deletes a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the delete operation if the delete was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] operation_ref = None validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') if not console_io.PromptContinue( 'All of the instance data will be lost when the instance is deleted.' ): return None try: result = sql_client.instances.Delete( sql_messages.SqlInstancesDeleteRequest( instance=instance_ref.instance, project=instance_ref.project)) operation_ref = resources.Create( 'sql.operations', operation=result.name, project=instance_ref.project, instance=instance_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta4.WaitForOperation( sql_client, operation_ref, 'Deleting Cloud SQL instance') log.DeletedResource(instance_ref) cache = remote_completion.RemoteCompletion() cache.DeleteFromCache(instance_ref.SelfLink()) except apitools_base.HttpError: log.debug('operation : %s', str(operation_ref)) raise
def Run(self, args): """Deletes an SSL certificate for a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the delete operation if the api request was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') # TODO(user): figure out how to rectify the common_name and the # sha1fingerprint, so that things can work with the resource parser. cert_ref = cert.GetCertRefFromName(sql_client, sql_messages, resources, instance_ref, args.common_name) if not cert_ref: raise exceptions.ToolException( 'no ssl cert named [{name}] for instance [{instance}]'.format( name=args.common_name, instance=instance_ref)) result = sql_client.sslCerts.Delete( sql_messages.SqlSslCertsDeleteRequest( project=cert_ref.project, instance=cert_ref.instance, sha1Fingerprint=cert_ref.sha1Fingerprint)) operation_ref = resources.Create( 'sql.operations', operation=result.operation, project=cert_ref.project, instance=cert_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta3.WaitForOperation(sql_client, operation_ref, 'Deleting sslCert') log.DeletedResource(cert_ref)
def Run(self, args): """Imports data into a Cloud SQL instance from Google Cloud Storage. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the import operation if the import was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') import_request = sql_messages.SqlInstancesImportRequest( instance=instance_ref.instance, project=instance_ref.project, instancesImportRequest=sql_messages.InstancesImportRequest( importContext=sql_messages.ImportContext( uri=args.uri, database=args.database, ), ), ) result = sql_client.instances.Import(import_request) operation_ref = resources.Create( 'sql.operations', operation=result.operation, project=instance_ref.project, instance=instance_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta3.WaitForOperation( sql_client, operation_ref, 'Importing Cloud SQL instance') log.status.write('Imported [{instance}] from [{buckets}].\n'.format( instance=instance_ref, buckets=','.join(args.uri))) return None
def Run(self, args): """Restores a backup of a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the restoreBackup operation if the restoreBackup was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') instance_resource = sql_client.instances.Get(instance_ref.Request()) # At this point we support only one backup-config. So, just use that id. backup_config = instance_resource.settings.backupConfiguration[0].id result = sql_client.instances.RestoreBackup( sql_messages.SqlInstancesRestoreBackupRequest( project=instance_ref.project, instance=instance_ref.instance, backupConfiguration=backup_config, dueTime=args.due_time)) operation_ref = resources.Create( 'sql.operations', operation=result.operation, project=instance_ref.project, instance=instance_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta3.WaitForOperation( sql_client, operation_ref, 'Restoring Cloud SQL instance') log.status.write( 'Restored [{instance}].\n'.format(instance=instance_ref)) return None
def Run(self, args): """Deletes all certificates and generates a new server SSL certificate. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the resetSslConfig operation if the reset was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') result_operation = sql_client.instances.ResetSslConfig( sql_messages.SqlInstancesResetSslConfigRequest( project=instance_ref.project, instance=instance_ref.instance)) operation_ref = resources.Create( 'sql.operations', operation=result_operation.name, project=instance_ref.project, instance=instance_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta4.WaitForOperation(sql_client, operation_ref, 'Resetting SSL config') log.status.write('Reset SSL config for [{resource}].\n'.format( resource=instance_ref))
def Run(self, args): """Promotes Cloud SQL read replica to a stand-alone instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the promote-replica operation if the promote-replica was successful. Raises: HttpException: An HTTP error response was received while executing api request. ToolException: An error other than an HTTP error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.replica) instance_ref = resources.Parse(args.replica, collection='sql.instances') result = sql_client.instances.PromoteReplica( sql_messages.SqlInstancesPromoteReplicaRequest( project=instance_ref.project, instance=instance_ref.instance)) operation_ref = resources.Create( 'sql.operations', operation=result.name, project=instance_ref.project, instance=instance_ref.instance, ) if args.async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta4.WaitForOperation( sql_client, operation_ref, 'Promoting Cloud SQL replica') log.status.write( 'Promoted [{instance}].\n'.format(instance=instance_ref))
def Run(self, args): """Wait for a Cloud SQL instance operation. Args: args: argparse.Namespace, The arguments that this command was invoked with. Yields: Operations that were waited for. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') for op in args.operation: operation_ref = resources.Parse(op, collection='sql.operations', params={ 'project': instance_ref.project, 'instance': instance_ref.instance }) operations.OperationsV1Beta3.WaitForOperation( sql_client, operation_ref, 'Waiting for [{operation}]'.format(operation=operation_ref)) yield sql_client.operations.Get(operation_ref.Request())
def Run(self, args): """Creates an SSL certificate for a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the create operation if the create was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ if os.path.exists(args.cert_file): raise exceptions.ToolException( 'file [{path}] already exists'.format(path=args.cert_file)) # First check if args.out_file is writeable. If not, abort and don't create # the useless cert. try: with files.OpenForWritingPrivate(args.cert_file) as cf: cf.write('placeholder\n') except (files.Error, OSError) as e: raise exceptions.ToolException( 'unable to write [{path}]: {error}'.format(path=args.cert_file, error=str(e))) sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') # TODO(user): figure out how to rectify the common_name and the # sha1fingerprint, so that things can work with the resource parser. result = sql_client.sslCerts.Insert( sql_messages.SqlSslCertsInsertRequest( project=instance_ref.project, instance=instance_ref.instance, sslCertsInsertRequest=sql_messages.SslCertsInsertRequest( commonName=args.common_name))) private_key = result.clientCert.certPrivateKey with files.OpenForWritingPrivate(args.cert_file) as cf: cf.write(private_key) cf.write('\n') cert_ref = resources.Create( collection='sql.sslCerts', project=instance_ref.project, instance=instance_ref.instance, sha1Fingerprint=result.clientCert.certInfo.sha1Fingerprint) log.CreatedResource(cert_ref) return result
def Run(self, args): """Connects to a Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: If no exception is raised this method does not return. A new process is started and the original one is killed. Raises: HttpException: An http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] # Do the mysql executable check first. This way we can return an error # faster and not wait for whitelisting IP and other operations. mysql_executable = files.FindExecutableOnPath('mysql') if not mysql_executable: raise exceptions.ToolException( 'Mysql client not found. Please install a mysql client and make sure ' 'it is in PATH to be able to connect to the database instance.' ) validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') acl_name = _WhitelistClientIP(instance_ref, sql_client, sql_messages, resources) # Get the client IP that the server sees. Sadly we can only do this by # checking the name of the authorized network rule. retryer = retry.Retryer(max_retrials=2, exponential_sleep_multiplier=2) try: instance_info, client_ip = retryer.RetryOnResult( _GetClientIP, [instance_ref, sql_client, acl_name], should_retry_if=lambda x, s: x[1] is None, # client_ip is None sleep_ms=500) except retry.RetryException: raise exceptions.ToolException( 'Could not whitelist client IP. Server ' 'did not reply with the whitelisted IP.') # Check the version of IP and decide if we need to add ipv4 support. ip_type = network.GetIpVersion(client_ip) if ip_type == network.IP_VERSION_4: if instance_info.settings.ipConfiguration.ipv4Enabled: ip_address = instance_info.ipAddresses[0].ipAddress else: # TODO(user): ask user if we should enable ipv4 addressing message = ( 'It seems your client does not have ipv6 connectivity and ' 'the database instance does not have an ipv4 address. ' 'Please request an ipv4 address for this database instance.' ) raise exceptions.ToolException(message) elif ip_type == network.IP_VERSION_6: ip_address = instance_info.ipv6Address else: raise exceptions.ToolException('Could not connect to SQL server.') # We have everything we need, time to party! mysql_args = [mysql_executable, '-h', ip_address] if args.user: mysql_args.extend(['-u', args.user]) mysql_args.append('-p') execution_utils.Exec(mysql_args)
def Run(self, args): """Creates a new Cloud SQL instance. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: A dict object representing the operations resource describing the create operation if the create was successful. Raises: HttpException: A http error response was received while executing api request. ToolException: An error other than http error occured while executing the command. """ # Added this temporarily for debugging SQL instance creation failures. # See b/18936263 for details. log.SetVerbosity(logging.DEBUG) sql_client = self.context['sql_client'] sql_messages = self.context['sql_messages'] resources = self.context['registry'] validate.ValidateInstanceName(args.instance) instance_ref = resources.Parse(args.instance, collection='sql.instances') instance_resource = instances.InstancesV1Beta4.ConstructInstanceFromArgs( sql_messages, args, instance_ref=instance_ref) if args.pricing_plan == 'PACKAGE': if not console_io.PromptContinue( 'Charges will begin accruing immediately. Really create Cloud ' 'SQL instance?'): raise exceptions.ToolException('canceled by the user.') operation_ref = None try: result_operation = sql_client.instances.Insert(instance_resource) operation_ref = resources.Create( 'sql.operations', operation=result_operation.name, project=instance_ref.project, instance=instance_ref.instance, ) if args. async: return sql_client.operations.Get(operation_ref.Request()) operations.OperationsV1Beta4.WaitForOperation( sql_client, operation_ref, 'Creating Cloud SQL instance') log.CreatedResource(instance_ref) new_resource = sql_client.instances.Get(instance_ref.Request()) cache = remote_completion.RemoteCompletion() cache.AddToCache(instance_ref.SelfLink()) return new_resource except apitools_base.HttpError: log.debug('operation : %s', str(operation_ref)) raise