Esempio n. 1
0
def SetHubMembershipPath(ref, args, request):
    """Sets the cluster.hub.membership field with a relative resource path.

  Args:
    ref: reference to the membership object.
    args: command line arguments.
    request: API request to be issued

  Returns:
    modified request
  """
    release_track = args.calliope_command.ReleaseTrack()
    msgs = util.GetMessagesModule(release_track)
    if flags.FlagIsExplicitlySet(args, 'hub_membership'):
        # Populate hub membership with a relative resource path using the same
        # project as the cluster, and --hub-membership as the membership id.
        hub_membership = resources.REGISTRY.Create(
            'gkehub.projects.locations.memberships',
            projectsId=ref.projectsId,
            locationsId='global',  # All Hub memberships are global.
            membershipsId=args.hub_membership)
        request.cluster.hub.membership = hub_membership.RelativeName()
    elif flags.FlagIsExplicitlySet(args, 'fleet_project'):
        request.cluster.fleet = msgs.Fleet()
        request.cluster.fleet.project = 'projects/' + args.fleet_project
    else:
        request.cluster.fleet = msgs.Fleet()
        request.cluster.fleet.project = 'projects/' + ref.projectsId
    return request
def ClearMaintenanceWindow(ref, args, request):
    """Clears cluster.maintenance_policy in the request if --clear-maintenance-window flag is specified.

  Args:
    ref: reference to the cluster object.
    args: command line arguments.
    request: API request to be issued

  Returns:
    modified request
  """

    del ref  # unused argument

    if not flags.FlagIsExplicitlySet(args, "clear_maintenance_window"):
        return request

    if not args.clear_maintenance_window:
        raise exceptions.BadArgumentException("--no-clear-maintenance-window",
                                              "The flag is not supported")
    if request.cluster is None:
        release_track = args.calliope_command.ReleaseTrack()
        request.cluster = util.GetMessagesModule(release_track).Cluster()
    request.cluster.maintenancePolicy = None

    _AddFieldToUpdateMask("maintenancePolicy", request)
    return request
Esempio n. 3
0
  def Run(self, args):
    """Deploy a container to Cloud Run."""
    service_ref = flags.GetService(args)
    image = args.image
    # Build an image from source if source specified.
    if flags.FlagIsExplicitlySet(args, 'source'):
      # Create a tag for the image creation
      if image is None and not args.IsSpecified('config'):
        image = 'gcr.io/{projectID}/cloud-run-source-deploy/{service}:{tag}'.format(
            projectID=properties.VALUES.core.project.Get(required=True),
            service=service_ref.servicesId,
            tag=uuid.uuid4().hex)
      messages = cloudbuild_util.GetMessagesModule()
      build_config = submit_util.CreateBuildConfig(
          image, args.no_cache, messages, args.substitutions, args.config,
          args.IsSpecified('source'), False, args.source,
          args.gcs_source_staging_dir, args.ignore_file, args.gcs_log_dir,
          args.machine_type, args.disk_size)
      submit_util.Build(messages, args.async_, build_config)

    # Deploy a container with an image
    conn_context = connection_context.GetConnectionContext(
        args, flags.Product.RUN, self.ReleaseTrack())
    config_changes = flags.GetConfigurationChanges(args)

    with serverless_operations.Connect(conn_context) as operations:
      image_change = config_changes_mod.ImageChange(image)
      changes = [image_change]
      if config_changes:
        changes.extend(config_changes)
      service = operations.GetService(service_ref)
      allow_unauth = GetAllowUnauth(args, operations, service_ref, service)

      pretty_print.Info(GetStartDeployMessage(conn_context, service_ref))
      has_latest = (service is None or
                    traffic.LATEST_REVISION_KEY in service.spec_traffic)
      deployment_stages = stages.ServiceStages(
          include_iam_policy_set=allow_unauth is not None,
          include_route=has_latest)
      header = 'Deploying...' if service else 'Deploying new service...'
      with progress_tracker.StagedProgressTracker(
          header,
          deployment_stages,
          failure_message='Deployment failed',
          suppress_output=args.async_) as tracker:
        operations.ReleaseService(
            service_ref,
            changes,
            tracker,
            asyn=args.async_,
            allow_unauthenticated=allow_unauth,
            prefetch=service)
      if args.async_:
        pretty_print.Success(
            'Service [{{bold}}{serv}{{reset}}] is deploying '
            'asynchronously.'.format(serv=service_ref.servicesId))
      else:
        pretty_print.Success(GetSuccessMessageForSynchronousDeploy(
            operations, service_ref))
Esempio n. 4
0
def ValidateClearVpcConnector(service, args):
    """Validates that the VPC connector can be safely removed.

  Does nothing if 'clear_vpc_connector' is not present in args with value True.

  Args:
    service: A Cloud Run service object.
    args: Namespace object containing the specified command line arguments.

  Raises:
    exceptions.ConfigurationError: If the command cannot prompt and
      VPC egress is set to 'all' or 'all-traffic'.
    console_io.OperationCancelledError: If the user answers no to the
      confirmation prompt.
  """
    if (service is None
            or not flags.FlagIsExplicitlySet(args, 'clear_vpc_connector')
            or not args.clear_vpc_connector):
        return

    if flags.FlagIsExplicitlySet(args, 'vpc_egress'):
        egress = args.vpc_egress
    elif container_resource.EGRESS_SETTINGS_ANNOTATION in service.template_annotations:
        egress = service.template_annotations[
            container_resource.EGRESS_SETTINGS_ANNOTATION]
    else:
        # --vpc-egress flag not specified and egress settings not set on service.
        return

    if (egress != container_resource.EGRESS_SETTINGS_ALL
            and egress != container_resource.EGRESS_SETTINGS_ALL_TRAFFIC):
        return

    if console_io.CanPrompt():
        console_io.PromptContinue(
            message=
            'Removing the VPC connector from this service will clear the '
            'VPC egress setting and route outbound traffic to the public internet.',
            default=False,
            cancel_on_no=True)
    else:
        raise exceptions.ConfigurationError(
            'Cannot remove VPC connector with VPC egress set to "{}". Set'
            ' `--vpc-egress=private-ranges-only` or run this command '
            'interactively and provide confirmation to continue.'.format(
                egress))
Esempio n. 5
0
def SetAdminUsers(ref, args, request):
    """Sets the cluster.authorization.admin_users to the user if unspecified.

  Args:
    ref: reference to the membership object.
    args: command line arguments.
    request: API request to be issued

  Returns:
    modified request
  """

    del ref  # unused argument

    # If the argument is set, don't change it.
    if flags.FlagIsExplicitlySet(args, 'admin_users'):
        return request

    if properties.VALUES.auth.credential_file_override.Get() is not None:
        raise gcloud_exceptions.RequiredArgumentException(
            '--admin-users',
            'Required if auth/credential_file_override is defined.')

    release_track = args.calliope_command.ReleaseTrack()
    msgs = util.GetMessagesModule(release_track)
    service_account_override = properties.VALUES.auth.impersonate_service_account.Get(
    )
    request.cluster.authorization = msgs.Authorization()
    request.cluster.authorization.adminUsers = msgs.ClusterUser()
    if service_account_override is not None:
        request.cluster.authorization.adminUsers.username = service_account_override
    else:
        default_account = properties.VALUES.core.account.Get()
        if default_account is None:
            raise gcloud_exceptions.RequiredArgumentException(
                '--admin-users',
                'Required if no account is active and --impersonate-service-account is undefined.'
            )
        request.cluster.authorization.adminUsers.username = default_account
    return request
Esempio n. 6
0
    def Run(self, args):
        """Deploy a container to Cloud Run."""
        platform = flags.GetAndValidatePlatform(args, self.ReleaseTrack(),
                                                flags.Product.RUN)

        include_build = flags.FlagIsExplicitlySet(args, 'source')
        if not include_build and not args.IsSpecified('image'):
            if console_io.CanPrompt():
                args.source = flags.PromptForDefaultSource()
                include_build = True
            else:
                raise c_exceptions.RequiredArgumentException(
                    '--image', 'Requires a container image to deploy (e.g. '
                    '`gcr.io/cloudrun/hello:latest`) if no build source is provided.'
                )

        service_ref = args.CONCEPTS.service.Parse()
        flags.ValidateResource(service_ref)

        # Obtaining the connection context prompts the user to select a region if
        # one hasn't been provided. We want to do this prior to preparing a source
        # deploy so that we can use that region for the Artifact Registry repo.
        conn_context = connection_context.GetConnectionContext(
            args, flags.Product.RUN, self.ReleaseTrack())

        build_type = None
        image = None
        pack = None
        source = None
        operation_message = 'Deploying container to'
        repo_to_create = None
        # Build an image from source if source specified
        if include_build:
            source = args.source

            ar_repo = docker_util.DockerRepo(
                project_id=properties.VALUES.core.project.Get(required=True),
                location_id=artifact_registry.RepoRegion(
                    args,
                    cluster_location=(conn_context.cluster_location if platform
                                      == platforms.PLATFORM_GKE else None)),
                repo_id='cloud-run-source-deploy')
            if artifact_registry.ShouldCreateRepository(ar_repo):
                repo_to_create = ar_repo
            # The image is built with latest tag. After build, the image digest
            # from the build result will be added to the image of the service spec.
            args.image = '{repo}/{service}'.format(
                repo=ar_repo.GetDockerString(), service=service_ref.servicesId)
            # Use GCP Buildpacks if Dockerfile doesn't exist
            docker_file = source + '/Dockerfile'
            if os.path.exists(docker_file):
                build_type = BuildType.DOCKERFILE
            else:
                pack = [{'image': args.image}]
                build_type = BuildType.BUILDPACKS
            image = None if pack else args.image
            operation_message = (
                'Building using {build_type} and deploying container'
                ' to').format(build_type=build_type.value)
            pretty_print.Info(
                messages_util.GetBuildEquivalentForSourceRunMessage(
                    service_ref.servicesId, pack, source))

        # Deploy a container with an image
        changes = flags.GetServiceConfigurationChanges(args)
        changes.insert(
            0,
            config_changes.DeleteAnnotationChange(
                k8s_object.BINAUTHZ_BREAKGLASS_ANNOTATION))
        changes.append(
            config_changes.SetLaunchStageAnnotationChange(self.ReleaseTrack()))

        with serverless_operations.Connect(conn_context) as operations:
            service = operations.GetService(service_ref)
            allow_unauth = GetAllowUnauth(args, operations, service_ref,
                                          service)
            resource_change_validators.ValidateClearVpcConnector(service, args)

            pretty_print.Info(
                messages_util.GetStartDeployMessage(conn_context, service_ref,
                                                    operation_message))
            has_latest = (service is None or traffic.LATEST_REVISION_KEY
                          in service.spec_traffic)
            deployment_stages = stages.ServiceStages(
                include_iam_policy_set=allow_unauth is not None,
                include_route=has_latest,
                include_build=include_build,
                include_create_repo=repo_to_create is not None,
            )
            header = None
            if include_build:
                header = 'Building and deploying'
            else:
                header = 'Deploying'
            if service is None:
                header += ' new service'
            header += '...'
            with progress_tracker.StagedProgressTracker(
                    header,
                    deployment_stages,
                    failure_message='Deployment failed',
                    suppress_output=args.async_) as tracker:
                service = operations.ReleaseService(
                    service_ref,
                    changes,
                    tracker,
                    asyn=args.async_,
                    allow_unauthenticated=allow_unauth,
                    prefetch=service,
                    build_image=image,
                    build_pack=pack,
                    build_source=source,
                    repo_to_create=repo_to_create)

            if args.async_:
                pretty_print.Success(
                    'Service [{{bold}}{serv}{{reset}}] is deploying '
                    'asynchronously.'.format(serv=service.name))
            else:
                service = operations.GetService(service_ref)
                pretty_print.Success(
                    messages_util.GetSuccessMessageForSynchronousDeploy(
                        service))
            return service
Esempio n. 7
0
    def Run(self, args):
        """Deploy a container to Cloud Run."""
        flags.GetAndValidatePlatform(args, self.ReleaseTrack(),
                                     flags.Product.RUN)
        service_ref = args.CONCEPTS.service.Parse()
        flags.ValidateResource(service_ref)
        build_type = None
        image = None
        pack = None
        source = None
        include_build = flags.FlagIsExplicitlySet(args, 'source')
        operation_message = 'Deploying container'
        # Build an image from source if source specified
        if include_build:
            # Create a tag for the image creation
            source = args.source
            if not args.IsSpecified('image'):
                args.image = 'gcr.io/{projectID}/cloud-run-source-deploy/{service}:{tag}'.format(
                    projectID=properties.VALUES.core.project.Get(
                        required=True),
                    service=service_ref.servicesId,
                    tag=uuid.uuid4().hex)
            # Use GCP Buildpacks if Dockerfile doesn't exist
            docker_file = args.source + '/Dockerfile'
            if os.path.exists(docker_file):
                build_type = BuildType.DOCKERFILE
            else:
                pack = [{'image': args.image}]
                build_type = BuildType.BUILDPACKS
            image = None if pack else args.image
            operation_message = 'Building using {build_type} and deploying container'.format(
                build_type=build_type.value)
        elif not args.IsSpecified('image'):
            raise c_exceptions.RequiredArgumentException(
                '--image', 'Requires a container image to deploy (e.g. '
                '`gcr.io/cloudrun/hello:latest`) if no build source is provided.'
            )
        # Deploy a container with an image
        conn_context = connection_context.GetConnectionContext(
            args, flags.Product.RUN, self.ReleaseTrack())
        changes = flags.GetConfigurationChanges(args)
        changes.insert(
            0,
            config_changes.DeleteAnnotationChange(
                k8s_object.BINAUTHZ_BREAKGLASS_ANNOTATION))
        changes.append(
            config_changes.SetLaunchStageAnnotationChange(self.ReleaseTrack()))

        with serverless_operations.Connect(conn_context) as operations:
            service = operations.GetService(service_ref)
            allow_unauth = GetAllowUnauth(args, operations, service_ref,
                                          service)
            resource_change_validators.ValidateClearVpcConnector(service, args)

            pretty_print.Info(
                messages_util.GetStartDeployMessage(conn_context, service_ref,
                                                    operation_message))
            has_latest = (service is None or traffic.LATEST_REVISION_KEY
                          in service.spec_traffic)
            deployment_stages = stages.ServiceStages(
                include_iam_policy_set=allow_unauth is not None,
                include_route=has_latest,
                include_build=include_build)
            header = None
            if include_build:
                header = 'Building and deploying'
            else:
                header = 'Deploying'
            if service is None:
                header += ' new service'
            header += '...'
            with progress_tracker.StagedProgressTracker(
                    header,
                    deployment_stages,
                    failure_message='Deployment failed',
                    suppress_output=args.async_) as tracker:
                service = operations.ReleaseService(
                    service_ref,
                    changes,
                    tracker,
                    asyn=args.async_,
                    allow_unauthenticated=allow_unauth,
                    prefetch=service,
                    build_image=image,
                    build_pack=pack,
                    build_source=source)

            if args.async_:
                pretty_print.Success(
                    'Service [{{bold}}{serv}{{reset}}] is deploying '
                    'asynchronously.'.format(serv=service.name))
            else:
                service = operations.GetService(service_ref)
                pretty_print.Success(
                    messages_util.GetSuccessMessageForSynchronousDeploy(
                        service))
            return service