예제 #1
0
    def Run(self, args):
        """Roll back to the previous server CA cert for a Cloud SQL instance.

    Args:
      args: argparse.Namespace, The arguments that this command was invoked
          with.

    Returns:
      The Server CA Cert that was rolled back to, if the operation was
      successful.
    """

        client = api_util.SqlClient(api_util.API_VERSION_DEFAULT)
        sql_client = client.sql_client
        sql_messages = client.sql_messages

        validate.ValidateInstanceName(args.instance)
        instance_ref = client.resource_parser.Parse(
            args.instance,
            params={'project': properties.VALUES.core.project.GetOrFail},
            collection='sql.instances')

        previous_server_ca = server_ca_certs.GetPreviousServerCa(
            sql_client, sql_messages, instance_ref)

        if not previous_server_ca:
            raise exceptions.ResourceNotFoundError(
                'No previous Server CA Certificate exists.')

        result_operation = sql_client.instances.RotateServerCa(
            sql_messages.SqlInstancesRotateServerCaRequest(
                project=instance_ref.project,
                instance=instance_ref.instance,
                instancesRotateServerCaRequest=sql_messages.
                InstancesRotateServerCaRequest(
                    rotateServerCaContext=sql_messages.RotateServerCaContext(
                        nextVersion=previous_server_ca.sha1Fingerprint))))

        operation_ref = client.resource_parser.Create(
            'sql.operations',
            operation=result_operation.name,
            project=instance_ref.project)

        operations.OperationsV1Beta4.WaitForOperation(
            sql_client, operation_ref,
            'Rolling back to previous Server CA Certificate')

        return previous_server_ca
예제 #2
0
    def Run(self, args):
        """Displays configuration and metadata about a Cloud SQL instance.

    Information such as instance name, IP address, region, the CA certificate
    and configuration settings will be displayed.

    Args:
      args: argparse.Namespace, The arguments that this command was invoked
          with.

    Returns:
      A dict object representing the instance resource if fetching the instance
      was successful.
    Raises:
      HttpException: A http error response was received while executing api
          request.
    ResourceNotFoundError: The SQL instance was not found.
    """
        client = api_util.SqlClient(api_util.API_VERSION_DEFAULT)
        sql_client = client.sql_client
        sql_messages = client.sql_messages

        validate.ValidateInstanceName(args.instance)
        instance_ref = client.resource_parser.Parse(
            args.instance,
            params={'project': properties.VALUES.core.project.GetOrFail},
            collection='sql.instances')

        try:
            instance = sql_client.instances.Get(
                sql_messages.SqlInstancesGetRequest(
                    project=instance_ref.project,
                    instance=instance_ref.instance))
            instance.state = instance_api_util.GetInstanceState(instance)
            # TODO(b/122660263): Remove when V1 instances are no longer supported.
            if instance_api_util.IsInstanceV1(instance):
                instance_command_util.ShowV1DeprecationWarning()
            return instance
        except apitools_exceptions.HttpError as error:
            if error.status_code == six.moves.http_client.FORBIDDEN:
                raise exceptions.ResourceNotFoundError(
                    'There was no instance found at {} or you are not authorized to '
                    'access it.'.format(instance_ref.RelativeName()))
            raise calliope_exceptions.HttpException(error)
예제 #3
0
def _AllowlistClientIP(instance_ref,
                       sql_client,
                       sql_messages,
                       resources,
                       minutes=5):
    """Add CLIENT_IP to the authorized networks list.

  Makes an API call to add CLIENT_IP to the authorized networks list.
  The server knows to interpret the string CLIENT_IP as the address with which
  the client reaches the server. This IP will be allowlisted for 1 minute.

  Args:
    instance_ref: resources.Resource, The instance we're connecting to.
    sql_client: apitools.BaseApiClient, A working client for the sql version to
      be used.
    sql_messages: module, The module that defines the messages for the sql
      version to be used.
    resources: resources.Registry, The registry that can create resource refs
      for the sql version to be used.
    minutes: How long the client IP will be allowlisted for, in minutes.

  Returns:
    string, The name of the authorized network rule. Callers can use this name
    to find out the IP the client reached the server with.
  Raises:
    HttpException: An http error response was received while executing api
        request.
    ResourceNotFoundError: The SQL instance was not found.
  """
    time_of_connection = network.GetCurrentTime()

    acl_name = 'sql connect at time {0}'.format(time_of_connection)
    user_acl = sql_messages.AclEntry(
        kind='sql#aclEntry',
        name=acl_name,
        expirationTime=iso_duration.Duration(
            minutes=minutes).GetRelativeDateTime(time_of_connection)
        # TODO(b/122989827): Remove this once the datetime parsing is fixed.
        # Setting the microseconds component to 10 milliseconds. This complies
        # with backend formatting restrictions, since backend requires a microsecs
        # component and anything less than 1 milli will get truncated.
        .replace(microsecond=10000).isoformat(),
        value='CLIENT_IP')

    try:
        original = sql_client.instances.Get(
            sql_messages.SqlInstancesGetRequest(
                project=instance_ref.project, instance=instance_ref.instance))
    except apitools_exceptions.HttpError as error:
        if error.status_code == six.moves.http_client.FORBIDDEN:
            raise exceptions.ResourceNotFoundError(
                'There was no instance found at {} or you are not authorized to '
                'connect to it.'.format(instance_ref.RelativeName()))
        raise calliope_exceptions.HttpException(error)

    # TODO(b/122989827): Remove this once the datetime parsing is fixed.
    original.serverCaCert = None

    original.settings.ipConfiguration.authorizedNetworks.append(user_acl)
    try:
        patch_request = sql_messages.SqlInstancesPatchRequest(
            databaseInstance=original,
            project=instance_ref.project,
            instance=instance_ref.instance)
        result = sql_client.instances.Patch(patch_request)
    except apitools_exceptions.HttpError as error:
        raise calliope_exceptions.HttpException(error)

    operation_ref = resources.Create('sql.operations',
                                     operation=result.name,
                                     project=instance_ref.project)
    message = ('Allowlisting your IP for incoming connection for '
               '{0} {1}'.format(minutes, text.Pluralize(minutes, 'minute')))

    operations.OperationsV1Beta4.WaitForOperation(sql_client, operation_ref,
                                                  message)

    return acl_name
예제 #4
0
    def Run(self, args):
        """Delete a client 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:
      ResourceNotFoundError: The ssl cert could not be found for the instance.
    """
        client = api_util.SqlClient(api_util.API_VERSION_DEFAULT)
        sql_client = client.sql_client
        sql_messages = client.sql_messages

        validate.ValidateInstanceName(args.instance)
        instance_ref = client.resource_parser.Parse(
            args.instance,
            params={'project': properties.VALUES.core.project.GetOrFail},
            collection='sql.instances')

        # TODO(b/36050482): figure out how to rectify the common_name and the
        # sha1fingerprint, so that things can work with the resource parser.

        console_io.PromptContinue(
            message='{0} will be deleted. New connections can no longer be made '
            'using this certificate. Existing connections are not affected.'.
            format(args.common_name),
            default=True,
            cancel_on_no=True)

        cert_ref = cert.GetCertRefFromName(sql_client, sql_messages,
                                           client.resource_parser,
                                           instance_ref, args.common_name)
        if not cert_ref:
            raise exceptions.ResourceNotFoundError(
                '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 = client.resource_parser.Create('sql.operations',
                                                      operation=result.name,
                                                      project=cert_ref.project)

        if args. async:
            return sql_client.operations.Get(
                sql_messages.SqlOperationsGetRequest(
                    project=operation_ref.project,
                    instance=operation_ref.instance,
                    operation=operation_ref.operation))

        operations.OperationsV1Beta4.WaitForOperation(sql_client,
                                                      operation_ref,
                                                      'Deleting sslCert')

        log.DeletedResource(cert_ref)