Exemple #1
0
    def Run(self, args):
        """Create a domain mapping."""
        # domains.cloudrun.com api group only supports v1alpha1 on clusters.
        conn_context = connection_context.GetConnectionContext(
            args,
            flags.Product.RUN,
            self.ReleaseTrack(),
            version_override=('v1alpha1' if platforms.GetPlatform() !=
                              platforms.PLATFORM_MANAGED else None))
        domain_mapping_ref = args.CONCEPTS.domain.Parse()
        changes = [
            config_changes.SetLaunchStageAnnotationChange(self.ReleaseTrack())
        ]

        # Check if the provided domain has already been verified
        # if mapping to a non-CRoGKE service
        if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
            client = global_methods.GetServerlessClientInstance()
            all_domains = global_methods.ListVerifiedDomains(client)
            # If not already verified, explain and error out
            if all(d.id not in domain_mapping_ref.Name() for d in all_domains):
                if not all_domains:
                    domains_text = 'You currently have no verified domains.'
                else:
                    domains = ['* {}'.format(d.id) for d in all_domains]
                    domains_text = ('Currently verified domains:\n{}'.format(
                        '\n'.join(domains)))
                raise exceptions.DomainMappingCreationError(
                    'The provided domain does not appear to be verified '
                    'for the current account so a domain mapping '
                    'cannot be created. Visit [{help}] for more information.'
                    '\n{domains}'.format(help=DOMAIN_MAPPINGS_HELP_DOCS_URL,
                                         domains=domains_text))

        with serverless_operations.Connect(conn_context) as client:
            try:
                mapping = client.CreateDomainMapping(domain_mapping_ref,
                                                     args.service, changes,
                                                     args.force_override)
            except exceptions.DomainMappingAlreadyExistsError as e:
                if console_io.CanPrompt() and console_io.PromptContinue(
                    ('This domain is already being used as a mapping elsewhere. '
                     'The existing mapping can be overriden by passing '
                     '`--force-override` or by continuing at the prompt below.'
                     ),
                        prompt_string='Override the existing mapping'):
                    deletion.Delete(domain_mapping_ref,
                                    client.GetDomainMapping,
                                    client.DeleteDomainMapping,
                                    async_=False)
                    mapping = client.CreateDomainMapping(
                        domain_mapping_ref, args.service, changes, True)
                else:
                    raise e

            for record in mapping.records:
                record.name = record.name or mapping.route_name
            return mapping.records
 def _Call(self, parsed_args):
     if (platforms.GetPlatform() == platforms.PLATFORM_GKE
             or platforms.GetPlatform() == platforms.PLATFORM_KUBERNETES):
         return 'default'
     elif not (getattr(parsed_args, 'project', None)
               or properties.VALUES.core.project.Get()):
         # HACK: Compensate for how "namespace" is actually "project" in Cloud Run
         # by providing an error message explicitly early here.
         raise exceptions.ArgumentError(
             'The [project] resource is not properly specified. '
             'Please specify the argument [--project] on the command line or '
             'set the property [core/project].')
     return None
Exemple #3
0
def GetAllowUnauth(args, operations, service_ref, service_exists):
    """Returns allow_unauth value for a service change.

  Args:
    args: argparse.Namespace, Command line arguments
    operations: serverless_operations.ServerlessOperations, Serverless client.
    service_ref: protorpc.messages.Message, A resource reference object for the
      service See googlecloudsdk.core.resources.Registry.ParseResourceId for
      details.
    service_exists: True if the service being changed already exists.

  Returns:
    allow_unauth value where
     True means to enable unauthenticated acess for the service.
     False means to disable unauthenticated access for the service.
     None means to retain the current value for the service.
  """
    allow_unauth = None
    if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
        allow_unauth = flags.GetAllowUnauthenticated(args, operations,
                                                     service_ref,
                                                     not service_exists)
        # Avoid failure removing a policy binding for a service that
        # doesn't exist.
        if not service_exists and not allow_unauth:
            allow_unauth = None
    return allow_unauth
Exemple #4
0
    def Run(self, args):
        """Executes when user runs the init command."""
        if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
            raise exceptions.UnsupportedArgumentError(
                'This command is only available with Cloud Run for Anthos.')

        kuberun_events_flags.ValidateAuthenticationFlags(args)

        conn_context = connection_context.GetConnectionContext(
            args, serverless_flags.Product.EVENTS, self.ReleaseTrack())

        namespace_ref = args.CONCEPTS.namespace.Parse()

        with eventflow_operations.Connect(conn_context) as client:
            product_type = init_shared.determine_product_type(
                client, args.authentication)

            if not client.GetNamespace(namespace_ref):
                client.CreateNamespace(namespace_ref)

            if args.authentication == events_constants.AUTH_SECRETS:
                client.CreateOrReplaceSourcesSecret(namespace_ref,
                                                    product_type)

        log.status.Print(
            'Initialized namespace [{}] for Cloud Run eventing with '
            'secret {}'.format(namespace_ref.Name(),
                               anthosevents_operations.SOURCES_KEY))
Exemple #5
0
  def Run(self, args):
    """Update the traffic split for the service.

    Args:
      args: Args!

    Returns:
      List of traffic.TrafficTargetStatus instances reflecting the change.
    """
    conn_context = connection_context.GetConnectionContext(
        args, flags.Product.RUN, self.ReleaseTrack())
    service_ref = args.CONCEPTS.service.Parse()
    flags.ValidateResource(service_ref)

    changes = flags.GetServiceConfigurationChanges(args)
    if not changes:
      raise exceptions.NoConfigurationChangeError(
          'No traffic configuration change requested.')
    changes.insert(
        0,
        config_changes.DeleteAnnotationChange(
            k8s_object.BINAUTHZ_BREAKGLASS_ANNOTATION))
    changes.append(
        config_changes.SetLaunchStageAnnotationChange(self.ReleaseTrack()))

    is_managed = platforms.GetPlatform() == platforms.PLATFORM_MANAGED
    with serverless_operations.Connect(conn_context) as client:
      deployment_stages = stages.UpdateTrafficStages()
      try:
        with progress_tracker.StagedProgressTracker(
            'Updating traffic...',
            deployment_stages,
            failure_message='Updating traffic failed',
            suppress_output=args.async_) as tracker:
          client.UpdateTraffic(service_ref, changes, tracker, args.async_)
      except:
        serv = client.GetService(service_ref)
        if serv:
          resources = traffic_pair.GetTrafficTargetPairs(
              serv.spec_traffic,
              serv.status_traffic,
              is_managed,
              serv.status.latestReadyRevisionName,
              serv.status.url)
          display.Displayer(
              self, args, resources,
              display_info=args.GetDisplayInfo()).Display()
        raise

      if args.async_:
        pretty_print.Success('Updating traffic asynchronously.')
      else:
        serv = client.GetService(service_ref)
        resources = traffic_pair.GetTrafficTargetPairs(
            serv.spec_traffic,
            serv.status_traffic,
            is_managed,
            serv.status.latestReadyRevisionName,
            serv.status.url)
        return resources
Exemple #6
0
def GetConnectionContext(args,
                         product=flags.Product.RUN,
                         release_track=base.ReleaseTrack.GA,
                         version_override=None,
                         platform=None):
  """Gets the regional, kubeconfig, or GKE connection context.

  Args:
    args: Namespace, the args namespace.
    product: Which product is requesting connection context.
    release_track: Release track of the command being run.
    version_override: If specified, the given api version will be used no matter
      the other parameters.
    platform: 'gke', 'kubernetes', or 'managed'. If not specified, the value of
      the --platform flag will be used instead.

  Raises:
    ArgumentError if region or cluster is not specified.

  Returns:
    A GKE or regional ConnectionInfo object.
  """
  if platform is None:
    platform = platforms.GetPlatform()
  if platform == platforms.PLATFORM_KUBERNETES:
    kubeconfig = flags.GetKubeconfig(getattr(args, 'kubeconfig', None))
    api_name = _GetApiName(product, release_track, is_cluster=True)
    api_version = _GetApiVersion(
        product,
        release_track,
        is_cluster=True,
        version_override=version_override)
    return KubeconfigConnectionContext(kubeconfig, api_name, api_version,
                                       args.context)

  if platform == platforms.PLATFORM_GKE:
    cluster_ref = args.CONCEPTS.cluster.Parse()
    if not cluster_ref:
      raise serverless_exceptions.ArgumentError(
          'You must specify a cluster in a given location. '
          'Either use the `--cluster` and `--cluster-location` flags '
          'or set the run/cluster and run/cluster_location properties.')
    api_name = _GetApiName(product, release_track, is_cluster=True)
    api_version = _GetApiVersion(
        product,
        release_track,
        is_cluster=True,
        version_override=version_override)
    return GKEConnectionContext(cluster_ref, api_name, api_version)

  if platform == platforms.PLATFORM_MANAGED:
    region = flags.GetRegion(args, prompt=True)
    if not region:
      raise serverless_exceptions.ArgumentError(
          'You must specify a region. Either use the `--region` flag '
          'or set the run/region property.')
    api_name = _GetApiName(product, release_track)
    api_version = _GetApiVersion(
        product, release_track, version_override=version_override)
    return _RegionalConnectionContext(region, api_name, api_version)
    def _Prompt(self, parsed_args):
        """Fallthrough to reading the cluster location from an interactive prompt.

    Only prompt for cluster location if the user-specified platform is GKE
    and if cluster name is already defined.

    Args:
      parsed_args: Namespace, the args namespace.

    Returns:
      A cluster location string
    """
        cluster_name = (getattr(parsed_args, 'cluster', None)
                        or properties.VALUES.run.cluster.Get())
        if platforms.GetPlatform() == platforms.PLATFORM_GKE and cluster_name:
            clusters = [
                c for c in global_methods.ListClusters()
                if c.name == cluster_name
            ]
            if not clusters:
                raise exceptions.ConfigurationError(
                    'No cluster locations found for cluster [{}]. '
                    'Ensure your clusters have Cloud Run enabled.'.format(
                        cluster_name))
            cluster_locations = [c.zone for c in clusters]
            idx = console_io.PromptChoice(
                cluster_locations,
                message='GKE cluster location for [{}]:'.format(cluster_name),
                cancel_option=True)
            location = cluster_locations[idx]
            log.status.Print(
                'To make this the default cluster location, run '
                '`gcloud config set run/cluster_location {}`.\n'.format(
                    location))
            return location
Exemple #8
0
 def Run(self, args):
     """List available services."""
     is_managed = platforms.GetPlatform() == platforms.PLATFORM_MANAGED
     if is_managed and not args.IsSpecified('region'):
         self._SetFormat(args, show_region=True)
         client = global_methods.GetServerlessClientInstance()
         self.SetPartialApiEndpoint(client.url)
         args.CONCEPTS.namespace.Parse()  # Error if no proj.
         # Don't consider region property here, we'll default to all regions
         return commands.SortByName(global_methods.ListServices(client))
     else:
         conn_context = connection_context.GetConnectionContext(
             args, flags.Product.RUN, self.ReleaseTrack())
         self._SetFormat(args,
                         show_region=is_managed,
                         show_namespace=(not is_managed))
         namespace_ref = args.CONCEPTS.namespace.Parse()
         with serverless_operations.Connect(conn_context) as client:
             self.SetCompleteApiEndpoint(conn_context.endpoint)
             if not is_managed:
                 location_msg = ' in [{}]'.format(
                     conn_context.cluster_location)
                 project_msg = ' in project [{}]'.format(
                     conn_context.cluster_project)
                 is_multi_tenant = conn_context.cluster_project != properties.VALUES.core.project.Get(
                     required=False)
                 log.status.Print(
                     'For cluster [{cluster}]{zone}{project}:'.format(
                         cluster=conn_context.cluster_name,
                         zone=location_msg
                         if conn_context.cluster_location else '',
                         project=project_msg if is_multi_tenant else ''))
             return commands.SortByName(client.ListServices(namespace_ref))
Exemple #9
0
  def _Prompt(self, parsed_args):
    """Fallthrough to reading the cluster name from an interactive prompt.

    Only prompt for cluster name if the user-specified platform is GKE.

    Args:
      parsed_args: Namespace, the args namespace.

    Returns:
      A cluster name string
    """
    if platforms.GetPlatform() != platforms.PLATFORM_GKE:
      return

    project = properties.VALUES.core.project.Get(required=True)
    cluster_location = (
        getattr(parsed_args, 'cluster_location', None) or
        properties.VALUES.run.cluster_location.Get())
    cluster_location_msg = ' in [{}]'.format(
        cluster_location) if cluster_location else ''

    cluster_refs = global_methods.MultiTenantClustersForProject(
        project, cluster_location)
    if not cluster_refs:
      raise exceptions.ConfigurationError(
          'No compatible clusters found{}. '
          'Ensure your cluster has Cloud Run enabled.'.format(
              cluster_location_msg))

    cluster_refs_descs = [
        self._GetClusterDescription(c, cluster_location, project)
        for c in cluster_refs
    ]

    idx = console_io.PromptChoice(
        cluster_refs_descs,
        message='GKE cluster{}:'.format(cluster_location_msg),
        cancel_option=True)

    cluster_ref = cluster_refs[idx]

    if cluster_location:
      location_help_text = ''
    else:
      location_help_text = (
          ' && gcloud config set run/cluster_location {}'.format(
              cluster_ref.zone))

    cluster_name = cluster_ref.Name()

    if cluster_ref.projectId != project:
      cluster_name = cluster_ref.RelativeName()
      location_help_text = ''

    log.status.Print('To make this the default cluster, run '
                     '`gcloud config set run/cluster {cluster}'
                     '{location}`.\n'.format(
                         cluster=cluster_name, location=location_help_text))
    return cluster_ref.SelfLink()
Exemple #10
0
  def Run(self, args):
    if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
      raise exceptions.UnsupportedArgumentError(
          'This command is only available with Cloud Run for Anthos.')
    conn_context = connection_context.GetConnectionContext(
        args, serverless_flags.Product.EVENTS, self.ReleaseTrack())
    namespace_ref = args.CONCEPTS.namespace.Parse()

    with eventflow_operations.Connect(conn_context) as client:
      brokers = client.ListBrokers(namespace_ref.RelativeName())
      return brokers
Exemple #11
0
 def Run(self, args):
     """List available domain mappings."""
     # domains.cloudrun.com api group only supports v1alpha1 on clusters.
     conn_context = connection_context.GetConnectionContext(
         args,
         flags.Product.RUN,
         self.ReleaseTrack(),
         version_override=('v1alpha1' if platforms.GetPlatform() !=
                           platforms.PLATFORM_MANAGED else None))
     namespace_ref = args.CONCEPTS.namespace.Parse()
     with serverless_operations.Connect(conn_context) as client:
         self.SetCompleteApiEndpoint(conn_context.endpoint)
         return commands.SortByName(
             client.ListDomainMappings(namespace_ref))
Exemple #12
0
def _GetIngress(record):
  """Gets the ingress traffic allowed to call the service."""
  if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
    spec_ingress = record.annotations.get(service.INGRESS_ANNOTATION)
    status_ingress = record.annotations.get(service.INGRESS_STATUS_ANNOTATION)
    if spec_ingress == status_ingress:
      return spec_ingress
    else:
      spec_ingress = spec_ingress or _INGRESS_UNSPECIFIED
      status_ingress = status_ingress or _INGRESS_UNSPECIFIED
      return '{} (currently {})'.format(spec_ingress, status_ingress)
  elif (record.labels.get(
      service.ENDPOINT_VISIBILITY) == service.CLUSTER_LOCAL):
    return service.INGRESS_INTERNAL
  else:
    return service.INGRESS_ALL
Exemple #13
0
 def Run(self, args):
     """Describe a domain mapping."""
     # domains.cloudrun.com api group only supports v1alpha1 on clusters.
     conn_context = connection_context.GetConnectionContext(
         args,
         flags.Product.RUN,
         self.ReleaseTrack(),
         version_override=('v1alpha1' if platforms.GetPlatform() !=
                           platforms.PLATFORM_MANAGED else None))
     domain_mapping_ref = args.CONCEPTS.domain.Parse()
     with serverless_operations.Connect(conn_context) as client:
         domain_mapping = client.GetDomainMapping(domain_mapping_ref)
         if not domain_mapping:
             raise exceptions.ArgumentError(
                 'Cannot find domain mapping for domain name [{}]'.format(
                     domain_mapping_ref.domainmappingsId))
         return domain_mapping
Exemple #14
0
 def Run(self, args):
   """Delete domain mappings."""
   # domains.cloudrun.com api group only supports v1alpha1 on clusters.
   conn_context = connection_context.GetConnectionContext(
       args,
       flags.Product.RUN,
       self.ReleaseTrack(),
       version_override=('v1alpha1' if
                         platforms.GetPlatform() != platforms.PLATFORM_MANAGED
                         else None))
   domain_mapping_ref = args.CONCEPTS.domain.Parse()
   with serverless_operations.Connect(conn_context) as client:
     deletion.Delete(domain_mapping_ref, client.GetDomainMapping,
                     client.DeleteDomainMapping, args.async_)
     msg = """Mappings to [{domain}] now have been deleted.""".format(
         domain=domain_mapping_ref.domainmappingsId)
     pretty_print.Success(msg)
Exemple #15
0
 def Run(self, args):
     """List available configurations."""
     is_managed = platforms.GetPlatform() == platforms.PLATFORM_MANAGED
     conn_context = connection_context.GetConnectionContext(
         args, flags.Product.RUN, self.ReleaseTrack())
     self._SetFormat(args,
                     show_region=is_managed,
                     show_namespace=(not is_managed))
     namespace_ref = args.CONCEPTS.namespace.Parse()
     with serverless_operations.Connect(conn_context) as client:
         self.SetCompleteApiEndpoint(conn_context.endpoint)
         if not is_managed:
             zone_label = ' in zone [{}]'.format(
                 conn_context.cluster_location)
             log.status.Print('For cluster [{cluster}]{zone}:'.format(
                 cluster=conn_context.cluster_name,
                 zone=zone_label if conn_context.cluster_location else ''))
         return commands.SortByName(
             client.ListConfigurations(namespace_ref))
Exemple #16
0
    def Run(self, args):
        """Executes when the user runs the init command."""
        if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
            raise exceptions.UnsupportedArgumentError(
                'This command is only available with Cloud Run for Anthos.')
        project = properties.VALUES.core.project.Get(required=True)
        conn_context = connection_context.GetConnectionContext(
            args, serverless_flags.Product.EVENTS, self.ReleaseTrack())

        with eventflow_operations.Connect(conn_context) as client:
            operator.install_eventing_via_operator(client, self.ReleaseTrack())

            # Eventing has been installed and enabled, but not initialized yet.
            product_type = init_shared.determine_product_type(
                client, args.authentication)

            if client.IsClusterInitialized(product_type):
                console_io.PromptContinue(
                    message='This cluster has already been initialized.',
                    prompt_string='Would you like to re-run initialization?',
                    cancel_on_no=True)

            _EnableMissingServices(project)

            if args.authentication == events_constants.AUTH_SECRETS:
                # Create secrets for each Google service account and adds to cluster.
                gsa_emails = init_shared.construct_service_accounts(
                    args, product_type)
                init_shared.initialize_eventing_secrets(
                    client, gsa_emails, product_type)

            elif args.authentication == events_constants.AUTH_WI_GSA:
                # Bind controller and broker GSA to KSA via workload identity.
                gsa_emails = init_shared.construct_service_accounts(
                    args, product_type)
                init_shared.initialize_workload_identity_gsa(
                    client, gsa_emails)
            else:
                log.status.Print('Skipped initializing cluster.')

        log.status.Print(
            _InitializedMessage(self.ReleaseTrack(), conn_context.cluster_name,
                                args.authentication))
Exemple #17
0
  def Run(self, args):
    """Executes when the user runs the describe command."""
    if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
      raise exceptions.UnsupportedArgumentError(
          'This command is only available with Cloud Run for Anthos.')

    conn_context = connection_context.GetConnectionContext(
        args, serverless_flags.Product.EVENTS, self.ReleaseTrack())

    namespace_ref = args.CONCEPTS.namespace.Parse()
    broker_name = args.BROKER
    broker_full_name = namespace_ref.RelativeName() + '/brokers/' + broker_name

    with eventflow_operations.Connect(conn_context) as client:
      broker_obj = client.GetBroker(broker_full_name)

    if not broker_obj:
      raise exceptions.BrokerNotFound(
          'Broker [{}] not found.'.format(broker_name))
    return broker_obj
Exemple #18
0
def Delete(ref, getter, deleter, async_):
    """Deletes a resource for a surface, including a pretty progress tracker."""
    if async_ is None:
        async_ = platforms.GetPlatform() != platforms.PLATFORM_MANAGED
    if async_:
        deleter(ref)
        return
    poller = DeletionPoller(getter)
    with progress_tracker.ProgressTracker(
            message='Deleting [{}]'.format(ref.Name()),
            detail_message_callback=poller.GetMessage):
        deleter(ref)
        res = waiter.PollUntilDone(poller, ref)
        if res:
            if poller.GetMessage():
                raise serverless_exceptions.DeletionFailedError(
                    'Failed to delete [{}]: {}.'.format(
                        ref.Name(), poller.GetMessage()))
            else:
                raise serverless_exceptions.DeletionFailedError(
                    'Failed to delete [{}].'.format(ref.Name()))
Exemple #19
0
  def Run(self, args):
    """Executes when the user runs the delete command."""
    conn_context = connection_context.GetConnectionContext(
        args, serverless_flags.Product.EVENTS, self.ReleaseTrack())

    trigger_ref = args.CONCEPTS.trigger.Parse()
    console_io.PromptContinue(
        message='Trigger [{}] will be deleted.'.format(trigger_ref.Name()),
        throw_if_unattended=True,
        cancel_on_no=True)

    with eventflow_operations.Connect(conn_context) as client:
      # TODO(b/147308604): Don't delete source when Odin supports ownerRefs
      if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
        trigger_obj = client.GetTrigger(trigger_ref)
        if trigger_obj is not None:
          source_crds = client.ListSourceCustomResourceDefinitions()
          source_ref, source_crd = util.GetSourceRefAndCrdForTrigger(
              trigger_obj, source_crds, client.IsCluster())
          if source_ref and source_crd:
            # Delete the source before the trigger because we need the trigger
            # to exist to be able to find the source. Otherwise, we could end up
            # losing a reference to the source if trigger deletion succeeds but
            # source deletion fails.
            try:
              client.DeleteSource(source_ref, source_crd)
            except exceptions.SourceNotFound:
              # Source could have been deleted but trigger deletion failed
              # and this command was re-run, which is fine.
              pass
      if client.IsCluster():
        trigger_ref = resources.REGISTRY.Parse(
            trigger_ref.RelativeName(),
            collection=util.ANTHOS_TRIGGER_COLLECTION_NAME,
            api_version=client.api_version)
      client.DeleteTrigger(trigger_ref)

    log.DeletedResource(trigger_ref.Name(), 'trigger')
Exemple #20
0
    def Run(self, args):
        """Executes when the user runs the delete command."""
        if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
            raise exceptions.UnsupportedArgumentError(
                'This command is only available with Cloud Run for Anthos.')

        conn_context = connection_context.GetConnectionContext(
            args, serverless_flags.Product.EVENTS, self.ReleaseTrack())

        namespace_ref = args.CONCEPTS.namespace.Parse()
        broker_name = args.BROKER

        console_io.PromptContinue(
            message='Broker [{}] will be deleted.'.format(broker_name),
            throw_if_unattended=True,
            cancel_on_no=True)

        conn_context = connection_context.GetConnectionContext(
            args, serverless_flags.Product.EVENTS, self.ReleaseTrack())

        with eventflow_operations.Connect(conn_context) as client:
            client.DeleteBroker(namespace_ref.Name(), broker_name)

        log.DeletedResource(broker_name, 'broker')
Exemple #21
0
    def Run(self, args):
        """Executes when the user runs the create command."""
        if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
            raise exceptions.UnsupportedArgumentError(
                'This command is only available with Cloud Run for Anthos.')

        conn_context = connection_context.GetConnectionContext(
            args, serverless_flags.Product.EVENTS, self.ReleaseTrack())

        namespace_ref = args.CONCEPTS.namespace.Parse()

        with eventflow_operations.Connect(conn_context) as client:
            client.CreateBroker(namespace_ref.Name(), args.BROKER)

            broker_full_name = 'namespaces/{}/brokers/{}'.format(
                namespace_ref.Name(), args.BROKER)

            with progress_tracker.StagedProgressTracker(
                    'Creating Broker...',
                [progress_tracker.Stage('Creating Broker...')]) as tracker:
                client.PollBroker(broker_full_name, tracker)

        log.status.Print('Created broker [{}] in namespace [{}].'.format(
            args.BROKER, namespace_ref.Name()))
Exemple #22
0
 def _MakeEnvVarSource(self, messages, name, key):
     _AssertValidSecretKey(key, platforms.GetPlatform())
     return messages.EnvVarSource(
         secretKeyRef=messages.SecretKeySelector(name=name, key=key))
Exemple #23
0
  def Run(self, args):
    """Create or Update service from YAML."""
    conn_context = connection_context.GetConnectionContext(
        args, flags.Product.RUN, self.ReleaseTrack())

    with serverless_operations.Connect(conn_context) as client:
      try:
        new_service = service.Service(
            messages_util.DictToMessageWithErrorCheck(
                args.FILE, client.messages_module.Service),
            client.messages_module)
      except messages_util.ScalarTypeMismatchError as e:
        exceptions.MaybeRaiseCustomFieldMismatch(
            e,
            help_text='Please make sure that the YAML file matches the Knative '
                      'service definition spec in https://kubernetes.io/docs/'
                      'reference/kubernetes-api/services-resources/service-v1/'
                      '#Service.')

      # If managed, namespace must match project (or will default to project if
      # not specified).
      # If not managed, namespace simply must not conflict if specified in
      # multiple places (or will default to "default" if not specified).
      namespace = args.CONCEPTS.namespace.Parse().Name()  # From flag or default
      if new_service.metadata.namespace is not None:
        if (args.IsSpecified('namespace') and
            namespace != new_service.metadata.namespace):
          raise exceptions.ConfigurationError(
              'Namespace specified in file does not match passed flag.')
        namespace = new_service.metadata.namespace
        if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
          project = properties.VALUES.core.project.Get()
          project_number = projects_util.GetProjectNumber(project)
          if namespace != project and namespace != str(project_number):
            raise exceptions.ConfigurationError(
                'Namespace must be project ID [{}] or quoted number [{}] for '
                'Cloud Run (fully managed).'.format(project, project_number))
      new_service.metadata.namespace = namespace

      changes = [
          config_changes.ReplaceServiceChange(new_service),
          config_changes.SetLaunchStageAnnotationChange(self.ReleaseTrack())
      ]
      service_ref = resources.REGISTRY.Parse(
          new_service.metadata.name,
          params={'namespacesId': new_service.metadata.namespace},
          collection='run.namespaces.services')
      service_obj = client.GetService(service_ref)

      pretty_print.Info(
          run_messages_util.GetStartDeployMessage(
              conn_context, service_ref,
              operation='Applying new configuration'))

      deployment_stages = stages.ServiceStages()
      header = (
          'Deploying...' if service_obj else 'Deploying new service...')
      with progress_tracker.StagedProgressTracker(
          header,
          deployment_stages,
          failure_message='Deployment failed',
          suppress_output=args.async_) as tracker:
        service_obj = client.ReleaseService(
            service_ref,
            changes,
            tracker,
            asyn=args.async_,
            allow_unauthenticated=None,
            for_replace=True)
      if args.async_:
        pretty_print.Success(
            'New configuration for [{{bold}}{serv}{{reset}}] is being applied '
            'asynchronously.'.format(serv=service_obj.name))
      else:
        service_obj = client.GetService(service_ref)
        pretty_print.Success('New configuration has been applied to service '
                             '[{{bold}}{serv}{{reset}}].\n'
                             'URL: {{bold}}{url}{{reset}}'.format(
                                 serv=service_obj.name, url=service_obj.domain))
      return service_obj
    def Run(self, args):
        """Create or Update service from YAML."""
        run_messages = apis.GetMessagesModule(
            global_methods.SERVERLESS_API_NAME,
            global_methods.SERVERLESS_API_VERSION)
        service_dict = dict(args.FILE)
        # Clear the status to make migration from k8s deployments easier.
        # Since a Deployment status will have several fields that Cloud Run doesn't
        # support, trying to convert it to a message as-is will fail even though
        # status is ignored by the server.
        if 'status' in service_dict:
            del service_dict['status']

        # For cases where YAML contains the project number as metadata.namespace,
        # preemptively convert them to a string to avoid validation failures.
        namespace = service_dict.get('metadata', {}).get('namespace', None)
        if namespace is not None and not isinstance(namespace, str):
            service_dict['metadata']['namespace'] = str(namespace)

        try:
            raw_service = messages_util.DictToMessageWithErrorCheck(
                service_dict, run_messages.Service)
            new_service = service.Service(raw_service, run_messages)
        except messages_util.ScalarTypeMismatchError as e:
            exceptions.MaybeRaiseCustomFieldMismatch(
                e,
                help_text=
                'Please make sure that the YAML file matches the Knative '
                'service definition spec in https://kubernetes.io/docs/'
                'reference/kubernetes-api/services-resources/service-v1/'
                '#Service.')

        # If managed, namespace must match project (or will default to project if
        # not specified).
        # If not managed, namespace simply must not conflict if specified in
        # multiple places (or will default to "default" if not specified).
        namespace = args.CONCEPTS.namespace.Parse().Name(
        )  # From flag or default
        if new_service.metadata.namespace is not None:
            if (args.IsSpecified('namespace')
                    and namespace != new_service.metadata.namespace):
                raise exceptions.ConfigurationError(
                    'Namespace specified in file does not match passed flag.')
            namespace = new_service.metadata.namespace
            if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
                project = properties.VALUES.core.project.Get()
                project_number = projects_util.GetProjectNumber(project)
                if namespace != project and namespace != str(project_number):
                    raise exceptions.ConfigurationError(
                        'Namespace must be project ID [{}] or quoted number [{}] for '
                        'Cloud Run (fully managed).'.format(
                            project, project_number))
        new_service.metadata.namespace = namespace

        changes = [
            config_changes.ReplaceServiceChange(new_service),
            config_changes.SetLaunchStageAnnotationChange(self.ReleaseTrack())
        ]
        service_ref = resources.REGISTRY.Parse(
            new_service.metadata.name,
            params={'namespacesId': new_service.metadata.namespace},
            collection='run.namespaces.services')

        region_label = new_service.region if new_service.is_managed else None

        conn_context = connection_context.GetConnectionContext(
            args,
            flags.Product.RUN,
            self.ReleaseTrack(),
            region_label=region_label)

        with serverless_operations.Connect(conn_context) as client:
            service_obj = client.GetService(service_ref)

            pretty_print.Info(
                run_messages_util.GetStartDeployMessage(
                    conn_context,
                    service_ref,
                    operation='Applying new configuration to'))

            deployment_stages = stages.ServiceStages()
            header = ('Deploying...'
                      if service_obj else 'Deploying new service...')
            with progress_tracker.StagedProgressTracker(
                    header,
                    deployment_stages,
                    failure_message='Deployment failed',
                    suppress_output=args.async_) as tracker:
                service_obj = client.ReleaseService(service_ref,
                                                    changes,
                                                    tracker,
                                                    asyn=args.async_,
                                                    allow_unauthenticated=None,
                                                    for_replace=True)
            if args.async_:
                pretty_print.Success(
                    'New configuration for [{{bold}}{serv}{{reset}}] is being applied '
                    'asynchronously.'.format(serv=service_obj.name))
            else:
                service_obj = client.GetService(service_ref)
                pretty_print.Success(
                    'New configuration has been applied to service '
                    '[{{bold}}{serv}{{reset}}].\n'
                    'URL: {{bold}}{url}{{reset}}'.format(
                        serv=service_obj.name, url=service_obj.domain))
            return service_obj
Exemple #25
0
 def _CheckPlatform(self):
     if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
         raise exceptions.PlatformError(
             'This command group is in beta for fully managed Cloud Run; '
             'use `gcloud beta run domain-mappings`.')
Exemple #26
0
 def _CheckPlatform(self):
     if platforms.GetPlatform() != platforms.PLATFORM_MANAGED:
         raise exceptions.PlatformError(
             'This command group only supports reading logs for '
             'Cloud Run (fully managed).')
 def _CheckPlatform(self):
     if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
         raise run_exceptions.PlatformError(
             'The flag --platform={0} is not supported. '
             'Instead of using the flag --platform={0} in "gcloud events", '
             'run "gcloud eventarc".'.format(platforms.PLATFORM_MANAGED))
Exemple #28
0
 def _OmittedSecretKeyDefault(self, name):
     if platforms.GetPlatform() == platforms.PLATFORM_MANAGED:
         return 'latest'
     raise exceptions.ConfigurationError(
         'Missing required item key for environment variable [{}].'.format(
             name))
Exemple #29
0
 def _MakeVolumeSource(self, messages, name, key=None):
     source = messages.SecretVolumeSource(secretName=name)
     if key is not None:
         _AssertValidSecretKey(key, platforms.GetPlatform())
         source.items.append(messages.KeyToPath(key=key, path=key))
     return source
Exemple #30
0
 def _CheckPlatform(self):
   platform = platforms.GetPlatform()
   if platform is not None and platform != platforms.PLATFORM_MANAGED:
     raise exceptions.PlatformError(
         'This command group only supports listing regions for '
         'Cloud Run (fully managed).')