feat: Add new gcloud commands, API clients, and third-party libraries across various services.

This commit is contained in:
2026-01-01 20:26:35 +01:00
parent 5e23cbece0
commit a19e592eb7
25221 changed files with 8324611 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The main command group for Cloud Pub/Sub."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA,
base.ReleaseTrack.BETA,
base.ReleaseTrack.GA,
)
class Pubsub(base.Group):
"""Manage Cloud Pub/Sub topics, subscriptions, and snapshots."""
category = base.DATA_ANALYTICS_CATEGORY
def Filter(self, context, args):
# TODO(b/190538812): Determine if command group works with project number
base.RequireProjectID(args)
del context, args
base.DisableUserProjectQuota()

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Manage Pub/Sub Lite operations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class LiteOperations(base.Group):
"""Manage Pub/Sub Lite operations."""

View File

@@ -0,0 +1,23 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Describe a Pub/Sub Lite operation.
description: Describe a Pub/Sub Lite operation.
examples: |
To describe a Pub/Sub Lite operation, run:
$ {command} operation-id --location=us-central1-a
Alternatively, specify the full operation name:
$ {command} projects/my-project/locations/us-central1-a/operations/operation-id
request:
collection: pubsublite.admin.projects.locations.operations
method: get
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: The Pub/Sub Lite operation to describe.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_operation

View File

@@ -0,0 +1,55 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: List Pub/Sub Lite operations.
description: |
List Pub/Sub Lite operations.
The optional `--subscription` flag can be used to filter operations for a Pub/Sub Lite
subscription. The optional `--done` flag can be used to filter by operation completion status.
These flags are ignored if `--filter` is set.
To describe a listed operation, run:
$ {command} operation-id --location=us-central1-a
examples: |
To list Pub/Sub Lite operations, run:
$ {command} --location=us-central1-a --limit=50
To list incomplete Pub/Sub Lite operations, run:
$ {command} --location=us-central1-a --done=false
To list Pub/Sub Lite operations for a subscription, run:
$ {command} --location=us-central1-a --subscription=my-subscription --limit=50
To list incomplete Pub/Sub Lite operations for a subscription, run:
$ {command} --location=us-central1-a --subscription=my-subscription --done=false
request:
collection: pubsublite.admin.projects.locations.operations
method: list
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateListOperationsFilter
arguments:
resource:
help_text: Location to list operations for.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:location
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:operation-done
- _REF_: googlecloudsdk.command_lib.pubsub.flags:operation-subscription
output:
format: |
table(
name.scope("operations"):label=OPERATION_ID,
metadata.target:label=TARGET,
metadata.createTime:label=CREATE_TIME,
done:label=DONE,
error.code:label=ERROR_CODE,
error.message:label=MESSAGE
)

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Manage Pub/Sub Lite reservations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class LiteReservations(base.Group):
"""Manage Pub/Sub Lite reservations."""

View File

@@ -0,0 +1,28 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Create a Pub/Sub Lite reservation.
description: Create a Pub/Sub Lite reservation.
examples: |
To create a Pub/Sub lite-reservation, run:
$ {command} myreservation \
--location=us-central1 \
--throughput-capacity=2
request:
collection: pubsublite.admin.projects.locations.reservations
method: create
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Identifies the Cloud location this command will be executed on.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:location
is_parent_resource: true
is_positional: false
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:reservation-name
- _REF_: googlecloudsdk.command_lib.pubsub.flags:throughput-capacity
required: true

View File

@@ -0,0 +1,20 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Delete a Pub/Sub Lite reservation.
description: Delete a Pub/Sub Lite reservation.
examples: |
To delete a Pub/Sub Lite reservation, run:
$ {command} myreservation \
--location=us-central1
request:
collection: pubsublite.admin.projects.locations.reservations
method: delete
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Reservation to delete.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_reservation

View File

@@ -0,0 +1,20 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Describe a Pub/Sub Lite reservation.
description: Describe a Pub/Sub Lite reservation.
examples: |
To describe a Pub/Sub Lite reservation, run:
$ {command} myreservation \
--location=us-central1
request:
collection: pubsublite.admin.projects.locations.reservations
method: get
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Reservation to describe.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_reservation

View File

@@ -0,0 +1,20 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: List Pub/Sub Lite reservations.
description: List Pub/Sub Lite reservations.
examples: |
To list Pub/Sub Lite reservations, run:
$ {command} --location=us-central1 \
--limit=5
request:
collection: pubsublite.admin.projects.locations.reservations
method: list
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Location to list reservations for.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:location

View File

@@ -0,0 +1,26 @@
release_tracks: [ALPHA, BETA, GA]
command_type: LIST
help_text:
brief: List Pub/Sub Lite topics for a given Lite reservation.
description: List Pub/Sub Lite topics for a given Lite reservation.
examples: |
To list Pub/Sub Lite topics for a given Lite reservation, run:
$ {command} myreservation \
--location=us-central1
request:
collection: pubsublite.admin.projects.locations.reservations.topics
method: list
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Reservation to list topics for.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_reservation
is_parent_resource: true
is_positional: true
response:
result_attribute: topics

View File

@@ -0,0 +1,27 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Update a Pub/Sub Lite reservation.
description: Update a Pub/Sub Lite reservation.
examples: |
To update a Pub/Sub Lite reservation, run:
$ {command} myreservation \
--location=us-central1 \
--throughput-capacity=2
request:
collection: pubsublite.admin.projects.locations.reservations
method: patch
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Reservation to update.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_reservation
params:
- group:
required: true
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:throughput-capacity

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Manage Pub/Sub Lite subscriptions."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class LiteSubscriptions(base.Group):
"""Manage Pub/Sub Lite subscriptions."""

View File

@@ -0,0 +1,35 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Acknowledge messages on a Pub/Sub Lite subscription.
description: |
Acknowledge all messages on a Pub/Sub Lite subscription up to the provided offset. The message
corresponding to the provided offset will be included in the list of messages that are
acknowledged.
examples: |
To acknowledge messages on a Pub/Sub Lite subscription, run:
$ {command} mysubscription \
--location=us-central1-a \
--partition=0 \
--offset=10
request:
collection: pubsublite.cursor.projects.locations.subscriptions
method: commitCursor
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateCommitCursorRequest
arguments:
resource:
help_text: Subscription on which to acknowledge messages.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_cursor_subscription
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone
- _REF_: googlecloudsdk.command_lib.pubsub.flags:partition
required: true
- _REF_: googlecloudsdk.command_lib.pubsub.flags:offset
required: true

View File

@@ -0,0 +1,63 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Create a Pub/Sub Lite subscription.
description: Create a Pub/Sub Lite subscription.
examples: |
To create a Pub/Sub Lite subscription, run:
$ {command} mysubscription \
--location=us-central1-a \
--topic=mytopic
To create a Pub/Sub Lite subscription at the offset of the oldest retained message, run:
$ {command} mysubscription \
--location=us-central1-a \
--topic=mytopic \
--starting-offset=beginning
To create a Pub/Sub Lite subscription that exports messages from a Pub/Sub Lite topic to a
Pub/Sub topic, run:
$ {command} mysubscription \
--location=us-central1-a \
--topic=mytopic
--export-pubsub-topic=pubsubtopic
request:
collection: pubsublite.admin.projects.locations.subscriptions
method: create
issue_request_hook: googlecloudsdk.command_lib.pubsub.lite_util:ExecuteCreateSubscriptionRequest
arguments:
resource:
help_text: Identifies the Cloud zone this command will be executed on.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:location
is_parent_resource: true
is_positional: false
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone
- _REF_: googlecloudsdk.command_lib.pubsub.flags:subscription-name
required: true
- _REF_: googlecloudsdk.command_lib.pubsub.flags:subscription-topic-name
required: true
- _REF_: googlecloudsdk.command_lib.pubsub.flags:delivery-requirement
default: deliver-immediately
- group:
mutex: true
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:starting-offset
default: end
- _REF_: googlecloudsdk.command_lib.pubsub.flags:publish-time
- _REF_: googlecloudsdk.command_lib.pubsub.flags:event-time
- group:
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:export-desired-state
default: active
- _REF_: googlecloudsdk.command_lib.pubsub.flags:export-pubsub-topic
required: true
- _REF_: googlecloudsdk.command_lib.pubsub.flags:export-dead-letter-topic

View File

@@ -0,0 +1,26 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Delete a Pub/Sub Lite subscription.
description: Delete a Pub/Sub Lite subscription.
examples: |
To delete a Pub/Sub Lite subscription, run:
$ {command} mysubscription \
--location=us-central1-a
request:
collection: pubsublite.admin.projects.locations.subscriptions
method: delete
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Subscription to delete.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_subscription
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone

View File

@@ -0,0 +1,26 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Describe a Pub/Sub Lite subscription.
description: Describe a Pub/Sub Lite subscription.
examples: |
To describe a Pub/Sub Lite subscription, run:
$ {command} mysubscription \
--location=us-central1-a
request:
collection: pubsublite.admin.projects.locations.subscriptions
method: get
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Subscription to describe.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_subscription
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone

View File

@@ -0,0 +1,26 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: List Pub/Sub Lite subscriptions.
description: List Pub/Sub Lite subscriptions.
examples: |
To list Pub/Sub Lite subscriptions, run:
$ {command} --location=us-central1-a \
--limit=5
request:
collection: pubsublite.admin.projects.locations.subscriptions
method: list
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: ID of the location or fully qualified identifier for the location.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:location
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone

View File

@@ -0,0 +1,51 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Seek a Pub/Sub Lite subscription.
description: |
Initiate an out-of-band seek operation for a Pub/Sub Lite subscription to a specified target,
which may be timestamps or named locations within the message backlog.
The seek operation will complete once subscriber clients react to the seek for all partitions of
the topic. Note that the seek operation will not complete until subscribers are online. It may
take some time (usually within 30 seconds) for the seek to propagate if subscribers are online.
Use the --async flag if it's not necessary to wait for completion.
examples: |
To seek a Pub/Sub Lite subscription to the beginning of the message backlog, run:
$ {command} mysubscription \
--location=us-central1-a \
--starting-offset=beginning
To seek a Pub/Sub Lite subscription to a publish time without waiting for the operation to
complete, run:
$ {command} mysubscription \
--location=us-central1-a \
--publish-time="2021-01-01T12:00:00Z"
--async
request:
collection: pubsublite.admin.projects.locations.subscriptions
method: seek
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
- googlecloudsdk.command_lib.pubsub.lite_util:SetSeekTarget
async:
collection: pubsublite.admin.projects.locations.operations
# The response does not contain a resource. Print operation metadata instead.
extract_resource_result: false
arguments:
resource:
help_text: Subscription to seek.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_subscription
params:
- group:
mutex: true
required: true
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:starting-offset
- _REF_: googlecloudsdk.command_lib.pubsub.flags:publish-time
- _REF_: googlecloudsdk.command_lib.pubsub.flags:event-time

View File

@@ -0,0 +1,117 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Pub/Sub Lite lite-subscriptions subscribe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import lite_util
from googlecloudsdk.command_lib.util.args import resource_args
from googlecloudsdk.core import log
from googlecloudsdk.core.resource import resource_printer
MESSAGE_FORMAT = """\
default(
data,
message_id,
ordering_key,
attributes
)
"""
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA)
class Subscribe(base.Command):
"""Stream messages from a Pub/Sub Lite subscription."""
detailed_help = {
'DESCRIPTION':
"""\
Streams messages from a Pub/Sub Lite subscription. This command
requires Python 3.6 or greater, and requires the grpcio Python package
to be installed.
For MacOS, Linux, and Cloud Shell users, to install the gRPC client
libraries, run:
$ sudo pip3 install grpcio
$ export CLOUDSDK_PYTHON_SITEPACKAGES=1
""",
'EXAMPLES':
"""\
To subscribe to a Pub/Sub Lite subscription and automatically
acknowledge messages, run:
$ {command} mysubscription --location=us-central1-a --auto-ack
To subscribe to specific partitions in a subscription, run:
$ {command} mysubscription --location=us-central1-a --partitions=0,1,2
"""
}
@staticmethod
def Args(parser):
resource_args.AddResourceArgToParser(
parser,
resource_path='pubsub.lite_subscription',
required=True,
help_text='The Pub/Sub Lite subscription to receive messages from.')
parser.add_argument(
'--num-messages',
type=arg_parsers.BoundedInt(1, 1000),
default=1,
help="""The number of messages to stream before exiting. This value must
be less than or equal to 1000.""")
parser.add_argument(
'--auto-ack',
action='store_true',
default=False,
help='Automatically ACK every message received on this subscription.')
parser.add_argument(
'--partitions',
metavar='INT',
type=arg_parsers.ArgList(element_type=int),
help="""The partitions this subscriber should connect to to receive
messages. If empty, partitions will be automatically assigned.""")
def Run(self, args):
lite_util.RequirePython36('gcloud pubsub lite-subscriptions subscribe')
try:
# pylint: disable=g-import-not-at-top
from googlecloudsdk.api_lib.pubsub import lite_subscriptions
# pylint: enable=g-import-not-at-top
except ImportError:
raise lite_util.NoGrpcInstalled()
log.out.Print(
'Initializing the Subscriber stream... This may take up to 30 seconds.')
printer = resource_printer.Printer(args.format or MESSAGE_FORMAT)
with lite_subscriptions.SubscriberClient(
args.CONCEPTS.subscription.Parse(), args.partitions or [],
args.num_messages, args.auto_ack) as subscriber_client:
received = 0
while received < args.num_messages:
message = subscriber_client.Pull()
if message:
splits = message.message_id.split(',')
message.message_id = 'Partition: {}, Offset: {}'.format(
splits[0], splits[1])
printer.Print([message])
received += 1

View File

@@ -0,0 +1,35 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Update a Pub/Sub Lite subscription.
description: Update a Pub/Sub Lite subscription.
examples: |
To update a Pub/Sub Lite subscription, run:
$ {command} mysubscription \
--location=us-central1-a \
--delivery-requirement=DELIVER_IMMEDIATELY
request:
collection: pubsublite.admin.projects.locations.subscriptions
method: patch
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
- googlecloudsdk.command_lib.pubsub.lite_util:AddExportResources
arguments:
resource:
help_text: Subscription to update.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_subscription
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone
- group:
required: true
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:delivery-requirement
- _REF_: googlecloudsdk.command_lib.pubsub.flags:export-desired-state
- _REF_: googlecloudsdk.command_lib.pubsub.flags:export-pubsub-topic
- _REF_: googlecloudsdk.command_lib.pubsub.flags:export-dead-letter-topic

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Manage Pub/Sub Lite topics."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class LiteTopics(base.Group):
"""Manage Pub/Sub Lite topics."""

View File

@@ -0,0 +1,42 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Create a Pub/Sub Lite topic.
description: Create a Pub/Sub Lite topic.
examples: |
To create a Pub/Sub lite-topic, run:
$ {command} mytopic \
--location=us-central1-a \
--partitions=1 \
--per-partition-bytes=30GiB \
--message-retention-period=2w
request:
collection: pubsublite.admin.projects.locations.topics
method: create
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
- googlecloudsdk.command_lib.pubsub.lite_util:AddTopicReservationResource
- googlecloudsdk.command_lib.pubsub.lite_util:AddTopicDefaultsWithoutReservation
arguments:
resource:
help_text: Identifies the Cloud zone this command will be executed on.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:location
is_parent_resource: true
is_positional: false
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:topic-name
- _REF_: googlecloudsdk.command_lib.pubsub.flags:partitions
required: true
- _REF_: googlecloudsdk.command_lib.pubsub.flags:per-partition-publish-mib
- _REF_: googlecloudsdk.command_lib.pubsub.flags:per-partition-subscribe-mib
- _REF_: googlecloudsdk.command_lib.pubsub.flags:per-partition-bytes
required: true
- _REF_: googlecloudsdk.command_lib.pubsub.flags:message-retention-period
- _REF_: googlecloudsdk.command_lib.pubsub.flags:topic-throughput-reservation-name
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone

View File

@@ -0,0 +1,26 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Delete a Pub/Sub Lite topic.
description: Delete a Pub/Sub Lite topic.
examples: |
To delete a Pub/Sub Lite topic, run:
$ {command} mytopic \
--location=us-central1-a
request:
collection: pubsublite.admin.projects.locations.topics
method: delete
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Topic to delete.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_topic
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone

View File

@@ -0,0 +1,26 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Describe a Pub/Sub Lite topic.
description: Describe a Pub/Sub Lite topic.
examples: |
To describe a Pub/Sub Lite topic, run:
$ {command} mytopic \
--location=us-central1-a
request:
collection: pubsublite.admin.projects.locations.topics
method: get
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Topic to describe.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_topic
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone

View File

@@ -0,0 +1,25 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: List Pub/Sub Lite topics.
description: List Pub/Sub Lite topics.
examples: |
To list Pub/Sub Lite topics, run:
$ {command} --location=us-central1-a \
--limit=5
request:
collection: pubsublite.admin.projects.locations.topics
method: list
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Zone to list topics for.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:location
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone

View File

@@ -0,0 +1,31 @@
release_tracks: [ALPHA, BETA, GA]
command_type: LIST
help_text:
brief: List Pub/Sub Lite subscriptions for a given Lite topic.
description: List Pub/Sub Lite subscriptions for a given Lite topic.
examples: |
To list Pub/Sub Lite subscriptions for a given Lite topic, run:
$ {command} mytopic \
--location=us-central1-a
request:
collection: pubsublite.admin.projects.locations.topics.subscriptions
method: list
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
arguments:
resource:
help_text: Topic to list subscriptions for.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_topic
is_parent_resource: true
is_positional: true
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone
response:
result_attribute: subscriptions

View File

@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Pub/Sub lite-topics publish command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import lite_util
from googlecloudsdk.command_lib.util.args import resource_args
_DESCRIPTION = """\
Publishes a message to the specified Pub/Sub Lite topic. This command requires
Python 3.6 or greater, and requires the grpcio Python package to be installed.
For MacOS, Linux, and Cloud Shell users, to install the gRPC client libraries,
run:
$ sudo pip3 install grpcio
$ export CLOUDSDK_PYTHON_SITEPACKAGES=1
"""
_EXAMPLES = """\
To publish a message to a Pub/Sub Lite topic, run:
$ {command} mytopic --location=us-central1-a --message="Hello World!"
To publish a message to a Pub/Sub Lite topic with an ordering key and
attributes, run:
$ {command} mytopic --location=us-central1-a --message="Hello World!" --ordering-key="key" --attributes=KEY1=VAL1,KEY2=VAL2
To publish a message to a Pub/Sub Lite topic with an event time, run:
$ {command} mytopic --location=us-central1-a --message="Hello World!" --event-time="2021-01-01T12:00:00Z"
"""
def _AddPublishFlags(parser):
"""Adds publish arguments to the parser."""
resource_args.AddResourceArgToParser(
parser,
resource_path='pubsub.lite_topic',
help_text='The pubsub lite topic to publish to.',
required=True)
parser.add_argument(
'--message',
help="""The body of the message to publish to the given topic name.""")
parser.add_argument(
'--attributes',
metavar='KEY=VALUE',
type=arg_parsers.ArgDict(key_type=str, value_type=str, max_length=100),
help="""Comma-separated list of attributes. Each ATTRIBUTE has the form
name="value". You can specify up to 100 attributes.""")
parser.add_argument(
'--ordering-key',
help="""A string key, used for ordering delivery to subscribers. All
messages with the same ordering key will be assigned to the same
partition for ordered delivery.""")
parser.add_argument(
'--event-time',
type=arg_parsers.Datetime.Parse,
metavar='DATETIME',
help="""A user-specified event time. Run `gcloud topic datetimes` for
information on time formats.""")
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA)
class Publish(base.Command):
"""Publish Pub/Sub Lite messages."""
detailed_help = {'DESCRIPTION': _DESCRIPTION, 'EXAMPLES': _EXAMPLES}
@staticmethod
def Args(parser):
_AddPublishFlags(parser)
def Run(self, args):
lite_util.RequirePython36('gcloud pubsub lite-topics publish')
try:
# pylint: disable=g-import-not-at-top
from googlecloudsdk.api_lib.pubsub import lite_topics
# pylint: enable=g-import-not-at-top
except ImportError:
raise lite_util.NoGrpcInstalled()
with lite_topics.PublisherClient() as publisher_client:
return publisher_client.Publish(
topic_resource=args.CONCEPTS.topic.Parse(),
message=args.message,
ordering_key=args.ordering_key,
attributes=args.attributes,
event_time=args.event_time if hasattr(args, 'event_time') else None)

View File

@@ -0,0 +1,38 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Update a Pub/Sub Lite topic.
description: Update a Pub/Sub Lite topic.
examples: |
To update a Pub/Sub Lite topic, run:
$ {command} mytopic \
--location=us-central1-a \
--per-partition-publish-mib=10
request:
collection: pubsublite.admin.projects.locations.topics
method: patch
modify_request_hooks:
- googlecloudsdk.command_lib.pubsub.lite_util:UpdateAdminRequest
- googlecloudsdk.command_lib.pubsub.lite_util:ConfirmPartitionsUpdate
- googlecloudsdk.command_lib.pubsub.lite_util:AddTopicReservationResource
arguments:
resource:
help_text: Topic to update.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:lite_topic
command_level_fallthroughs:
location:
- arg_name: 'zone'
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:zone
- group:
required: true
params:
- _REF_: googlecloudsdk.command_lib.pubsub.flags:per-partition-publish-mib
- _REF_: googlecloudsdk.command_lib.pubsub.flags:per-partition-subscribe-mib
- _REF_: googlecloudsdk.command_lib.pubsub.flags:per-partition-bytes
- _REF_: googlecloudsdk.command_lib.pubsub.flags:message-retention-period
- _REF_: googlecloudsdk.command_lib.pubsub.flags:partitions
- _REF_: googlecloudsdk.command_lib.pubsub.flags:topic-throughput-reservation-name

View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The main command group for Cloud Pub/Sub snapshots."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.GA, base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA
)
class MessageTransforms(base.Group):
"""Manage Cloud Pub/Sub message transforms."""

View File

@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub message transforms test command."""
from googlecloudsdk.api_lib.pubsub import message_transforms
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core.util import http_encoding
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.GA, base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA
)
class Test(base.Command):
"""Tests message transforms against a given message."""
@staticmethod
def Args(parser):
flags.AddTestMessageTransformFlags(parser)
def Run(self, args):
client = message_transforms.MessageTransformsClient()
message_body = getattr(args, 'message', None)
attributes = util.ParseAttributes(
getattr(args, 'attribute', None), client.messages
)
message_transforms_file = getattr(args, 'message_transforms_file', None)
topic = getattr(args, 'topic', None)
if topic:
topic = args.CONCEPTS.topic.Parse()
subscription = getattr(args, 'subscription', None)
if subscription:
subscription = args.CONCEPTS.subscription.Parse()
result = client.Test(
project_ref=util.ParseProject(),
message_body=http_encoding.Encode(message_body),
attributes=attributes,
message_transforms_file=message_transforms_file,
topic_ref=topic,
subscription_ref=subscription,
)
output = []
for transformed_message in result.transformedMessages:
if message := transformed_message.transformedMessage:
message_copy = {}
for field in message.all_fields():
value = getattr(message, field.name)
if value:
if field.name == 'data':
value = message.data.decode()
message_copy[field.name] = value
output.append(message_copy)
else:
output.append(transformed_message)
return output

View File

@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub message transforms validate command."""
from googlecloudsdk.api_lib.pubsub import message_transforms
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.GA, base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA
)
class Validate(base.Command):
"""Validates a message transform."""
@staticmethod
def Args(parser):
flags.AddValidateMessageTransformFlags(parser)
def Run(self, args):
client = message_transforms.MessageTransformsClient()
message_transform_file = getattr(args, 'message_transform_file', None)
client.Validate(util.ParseProject(), message_transform_file)
log.status.Print('Message transform is valid.')

View File

@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The command group for the schemas CLI."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
class Schemas(base.Group):
"""Manage Pub/Sub schemas.
The {command} group lets you create and manage Pub/Sub schemas. These
schemas can be attached to topics to enable validation of published messages.
Commands to validate schemas and messages against schemas are also available.
"""

View File

@@ -0,0 +1,91 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub schemas commit command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import schemas
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
class Commit(base.Command):
"""Commit a Pub/Sub schema revision."""
detailed_help = {
'EXAMPLES': """\
To commit a PROTOCOL_BUFFER schema revision called "key-schema" that requires exactly one-string field named "key", run:
\
\n$ {command} key-schema --definition="syntax = 'proto3'; message Message { optional string key = 1; }" --type=protocol-buffer
\
To commit an equivalent AVRO schema revision, run:
\
\n$ {command} key-schema --definition="{ 'type': 'record', 'namespace': 'my.ns', 'name': 'KeyMsg', 'fields': [ { 'name': 'key', 'type': 'string' } ] }" --type=avro
"""
}
@staticmethod
def Args(parser):
# The flag name is 'schema'.
resource_args.AddSchemaResourceArg(parser, 'to revise.')
flags.AddCommitSchemaFlags(parser)
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
A serialized object (dict) describing the results of the operation.
This description fits the Resource described in the ResourceRegistry under
'pubsub.projects.schemas'.
Raises:
util.RequestFailedError: if any of the requests to the API failed.
"""
client = schemas.SchemasClient()
schema_ref = util.ParseSchemaName(args.schema)
if args.definition_file:
definition = args.definition_file
else:
definition = args.definition
try:
result = client.Commit(
schema_ref=schema_ref,
schema_definition=definition,
schema_type=args.type,
)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.CreatedResource(
schema_ref,
kind='schema revision',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
return
log.CreatedResource(result.name, kind='schema revision')
return result

View File

@@ -0,0 +1,61 @@
- release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Create a Pub/Sub schema.
description: |
Create a new Pub/Sub schema.
examples: |
To create a PROTOCOL_BUFFER schema called "key-schema" that requires exactly one string field named "key", run:
$ {command} key-schema --definition="syntax = 'proto3'; message Message { optional string key = 1; }" --type=PROTOCOL_BUFFER
To create an equivalent AVRO schema, run:
$ {command} key-schema --definition='{ "type": "record", "namespace": "my.ns", "name": "KeyMsg", "fields": [ { "name": "key", "type": "string" } ] }' --type=AVRO
request:
collection: pubsub.projects.schemas
api_version: v1
arguments:
resource:
help_text: Pub/Sub schema to create.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:schema
params:
- group:
help_text: |
Schema definition.
mutex: true
required: true
params:
- arg_name: definition
api_field: schema.definition
help_text: |
Inline schema definition.
- arg_name: definition-file
api_field: schema.definition
type: "googlecloudsdk.calliope.arg_parsers:FileContents:"
help_text: |
File containing schema definition.
- arg_name: type
api_field: schema.type
required: true
help_text: |
Type of the schema.
choices:
- arg_value: avro
enum_value: AVRO
- arg_value: protocol-buffer
enum_value: PROTOCOL_BUFFER
- arg_name: tags
release_tracks: [ALPHA]
hidden: true
api_field: schema.tags.additionalProperties
metavar: KEY=VALUE
help_text: |
List of tag KEY=VALUE pairs to add.
type:
arg_dict:
flatten: true
spec:
- api_field: key
- api_field: value

View File

@@ -0,0 +1,19 @@
- release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Delete a Pub/Sub schema.
description: |
Delete a Pub/Sub schema.
examples: |
To delete a schema called `my-schema`, run:
$ {command} my-schema
request:
collection: pubsub.projects.schemas
api_version: v1
arguments:
resource:
help_text: Pub/Sub schema to delete.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:schema

View File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub schemas delete revision command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import schemas
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
class DeleteRevision(base.Command):
"""Delete a Pub/Sub schema revision."""
detailed_help = {
'EXAMPLES': """\
To roll back to an existing schema revision called "key-schema" with revision_id: "0a0b0c0d", run:
\
\n$ {command} key-schema@0a0b0c0d
"""
}
@staticmethod
def Args(parser):
# The flag name is 'schema'.
resource_args.AddSchemaResourceArg(parser, 'revision to delete.')
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
A serialized object (dict) describing the results of the operation.
This description fits the Resource described in the ResourceRegistry under
'pubsub.projects.schemas'.
Raises:
util.RequestFailedError: if any of the requests to the API failed.
"""
client = schemas.SchemasClient()
schema_ref = util.ParseSchemaName(args.schema)
try:
result = client.DeleteRevision(schema_ref=schema_ref)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.DeletedResource(
schema_ref,
kind='schema revision',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
return
log.DeletedResource(result.name, kind='schema revision')
return result

View File

@@ -0,0 +1,21 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Show details of a Pub/Sub schema.
description: Show details of a Pub/Sub schema.
examples: |
To show details about a schema named `my-schema`, run:
$ {command} my-schema
request:
collection: pubsub.projects.schemas
api_version: v1
# Ask for the full schema view, which returns the schema definition, too.
static_fields:
view: FULL
arguments:
resource:
help_text: The schema you want to describe.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:schema

View File

@@ -0,0 +1,47 @@
- release_tracks: [ALPHA, BETA, GA]
help_text:
brief: List Pub/Sub schemas.
description: |
List Pub/Sub schemas.
examples: |
To list the schemas, run:
$ {command}
request:
collection: pubsub.projects.schemas
api_version: v1
response:
id_field: name
arguments:
resource:
help_text: Parent Pub/Sub project to list all contained Pubsub schemas.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:project
params:
- arg_name: view
api_field: view
help_text: |
There are two possible views, 'basic' and 'full', default is 'basic'
choices:
- enum_value: BASIC
arg_value: basic
help_text: |
Include the name and type of the schema, but not the definition.
- enum_value: FULL
arg_value: full
help_text: |
Include all Schema object fields.
default: basic
output:
format: |
table(
name.basename(),
type,
revisionId,
revisionCreateTime:label=CREATE_TIME,
definition:optional
)

View File

@@ -0,0 +1,48 @@
- release_tracks: [GA, ALPHA, BETA]
help_text:
brief: List revisions of a Pub/Sub schema.
description: |
List revisions of a Pub/Sub schema.
examples: |
To list the revisions for a schema, run:
$ {command} my-schema
command_type: LIST
request:
collection: pubsub.projects.schemas
api_version: v1
method: listRevisions
disable_pagination: true
response:
id_field: name
result_attribute: schemas
arguments:
resource:
help_text: Parent Pub/Sub schema to list all contained revisions.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:schema
params:
- arg_name: view
api_field: view
help_text: |
There are two possible views, 'basic' and 'full', default is 'basic'
choices:
- enum_value: BASIC
arg_value: basic
help_text: |
Include the name and type of the schema, but not the definition.
- enum_value: FULL
arg_value: full
help_text: |
Include all Schema object fields.
default: basic
output:
format: |
table(
revisionId,
revisionCreateTime:label=CREATE_TIME,
type:label=TYPE,
definition:optional
)

View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub schemas rollback command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import schemas
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
class Rollback(base.Command):
"""Roll back a Pub/Sub schema to a specified revision."""
detailed_help = {
'EXAMPLES': """\
To roll back to an existing schema revision called "key-schema" with revision_id: "0a0b0c0d", run:
\
\n$ {command} key-schema --revision-id=0a0b0c0d
"""
}
@staticmethod
def Args(parser):
# The flag name is 'schema'.
resource_args.AddSchemaResourceArg(parser, 'to rollback.')
parser.add_argument(
'--revision-id',
type=str,
help='The revision to roll back to.',
required=True,
)
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
A serialized object (dict) describing the results of the operation.
This description fits the Resource described in the ResourceRegistry under
'pubsub.projects.schemas'.
Raises:
util.RequestFailedError: if any of the requests to the API failed.
"""
client = schemas.SchemasClient()
schema_ref = util.ParseSchemaName(args.schema)
revision_id = getattr(args, 'revision_id', None)
try:
result = client.Rollback(schema_ref=schema_ref, revision_id=revision_id)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.CreatedResource(
schema_ref,
kind='schema revision',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
return
log.CreatedResource(result.name, kind='schema revision')
return result

View File

@@ -0,0 +1,83 @@
- release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Validate a message against a Pub/Sub schema.
description: |
Validate a message against a Pub/Sub schema.
examples: |
To validate message against provided PROTOCOL_BUFFER schema, run:
$ {command} --message="{\"key\": \"my-key\"}" --message-encoding=JSON --definition="syntax = 'proto3'; message Message { optional string key = 1; }" --type=PROTOCOL_BUFFER
To validate an equivalent AVRO schema, run:
$ {command} --definition='{ "type": "record", "namespace": "my.ns", "name": "KeyMsg", "fields": [ { "name": "key", "type": "string" } ] }' --type=AVRO
request:
collection: pubsub.projects.schemas
api_version: v1
method: validateMessage
arguments:
resource:
help_text: Parent Pub/Sub project in which to validate the message.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:project
is_parent_resource: true
params:
- arg_name: message
api_field: validateMessageRequest.message
required: true
help_text: |
The message to validate against the schema.
- arg_name: message-encoding
api_field: validateMessageRequest.encoding
required: true
help_text: |
The encoding of the message.
choices:
- arg_value: json
enum_value: JSON
- arg_value: binary
enum_value: BINARY
- group:
help_text: |
Schema definition.
mutex: true
required: true
params:
- arg_name: schema-name
api_field: validateMessageRequest.name
processor: googlecloudsdk.command_lib.pubsub.util:ParseSchemaName
help_text: |
Name or full path of an existing schema.
- group:
params:
- group:
help_text: |
Schema specification.
mutex: true
required: true
params:
- arg_name: definition
api_field: validateMessageRequest.schema.definition
help_text: |
Inline schema definition.
- arg_name: definition-file
api_field: validateMessageRequest.schema.definition
type: "googlecloudsdk.calliope.arg_parsers:FileContents:"
help_text: |
File containing schema definition.
- arg_name: type
api_field: validateMessageRequest.schema.type
help_text: |
Type of inline schema.
required: true
choices:
- arg_value: avro
enum_value: AVRO
- arg_value: protocol-buffer
enum_value: PROTOCOL_BUFFER
response:
modify_response_hooks:
- googlecloudsdk.command_lib.pubsub.util:OutputMessageValidated

View File

@@ -0,0 +1,56 @@
- release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Validate a Pub/Sub schema.
description: |
Validate a new Pub/Sub schema.
examples: |
To validate a PROTOCOL_BUFFER schema, run:
$ {command} --definition="syntax = 'proto3'; message Message { optional string key = 1; }" --type=PROTOCOL_BUFFER
To validate an equivalent AVRO schema, run:
$ {command} --definition='{ "type": "record", "namespace": "my.ns", "name": "KeyMsg", "fields": [ { "name": "key", "type": "string" } ] }' --type=AVRO
request:
collection: pubsub.projects.schemas
api_version: v1
method: validate
arguments:
resource:
help_text: |
Parent Pub/Sub project in which to validate the schema.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:project
is_parent_resource: true
params:
- group:
help_text: |
Schema definition.
mutex: true
required: true
params:
- arg_name: definition
api_field: validateSchemaRequest.schema.definition
help_text: |
Inline schema definition.
- arg_name: definition-file
api_field: validateSchemaRequest.schema.definition
type: "googlecloudsdk.calliope.arg_parsers:FileContents:"
help_text: |
File containing schema definition.
- arg_name: type
api_field: validateSchemaRequest.schema.type
required: true
help_text: |
Type of the schema.
choices:
- arg_value: avro
enum_value: AVRO
- arg_value: protocol-buffer
enum_value: PROTOCOL_BUFFER
response:
modify_response_hooks:
- googlecloudsdk.command_lib.pubsub.util:OutputSchemaValidated

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The main command group for Cloud Pub/Sub snapshots."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
class Snapshots(base.Group):
"""Manage Cloud Pub/Sub snapshots."""

View File

@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub snapshots create command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import snapshots
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class Create(base.CreateCommand):
"""Creates one or more Cloud Pub/Sub snapshots."""
@staticmethod
def Args(parser):
"""Registers flags for this command."""
parser.add_argument(
'snapshot', nargs='+', help='One or more snapshot names to create.')
parser.add_argument(
'--subscription',
required=True,
help=('The subscription whose backlog the snapshot retains. '
' Specifically, the created snapshot is guaranteed to retain a)'
' The existing backlog on the subscription, i.e., the set of'
' messages in the subscription that are unacknowledged upon the'
' successful completion of the create snapshot request, b) Any'
' messages published to the subscription\'s topic following the'
' successful creation of the snapshot.'))
parser.add_argument(
'--subscription-project',
default='',
help=('The name of the project the provided subscription belongs to.'
' If not set, it defaults to the currently selected'
' cloud project.'))
labels_util.AddCreateLabelsFlags(parser)
flags.AddTagsFlag(parser)
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Yields:
A serialized object (dict) describing the results of the operation.
This description fits the Resource described in the ResourceRegistry under
'pubsub.projects.snapshots'.
Raises:
util.RequestFailedError: if any of the requests to the API failed.
"""
client = snapshots.SnapshotsClient()
subscription_ref = util.ParseSubscription(args.subscription,
args.subscription_project)
labels = labels_util.ParseCreateArgs(
args, client.messages.CreateSnapshotRequest.LabelsValue)
tags = flags.GetTagsMessage(
args, client.messages.CreateSnapshotRequest.TagsValue
)
failed = []
for snapshot_name in args.snapshot:
snapshot_ref = util.ParseSnapshot(snapshot_name)
try:
result = client.Create(
snapshot_ref, subscription_ref, labels=labels, tags=tags
)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.CreatedResource(
snapshot_ref.RelativeName(),
kind='snapshot',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
failed.append(snapshot_name)
continue
result = util.SnapshotDisplayDict(result)
log.CreatedResource(snapshot_ref.RelativeName(), kind='snapshot')
yield result
if failed:
raise util.RequestsFailedError(failed, 'create')
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(Create):
"""Creates one or more Cloud Pub/Sub snapshots."""
@staticmethod
def Args(parser):
super(CreateAlpha, CreateAlpha).Args(parser)

View File

@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub snapshots delete command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import snapshots
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
class Delete(base.DeleteCommand):
"""Deletes one or more Cloud Pub/Sub snapshots."""
@staticmethod
def Args(parser):
"""Registers flags for this command."""
parser.add_argument(
'snapshot', nargs='+', help='One or more snapshot names to delete.')
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Yields:
A serialized object (dict) describing the results of the operation.
This description fits the Resource described in the ResourceRegistry under
'pubsub.projects.snapshots'.
Raises:
util.RequestFailedError: if any of the requests to the API failed.
"""
client = snapshots.SnapshotsClient()
failed = []
for snapshot_name in args.snapshot:
snapshot_ref = util.ParseSnapshot(snapshot_name)
try:
client.Delete(snapshot_ref)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.DeletedResource(
snapshot_ref.RelativeName(),
kind='snapshot',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
failed.append(snapshot_name)
continue
result = util.SnapshotDisplayDict(
client.messages.Snapshot(name=snapshot_ref.RelativeName()))
log.DeletedResource(snapshot_ref.RelativeName(), kind='snapshot')
yield result
if failed:
raise util.RequestsFailedError(failed, 'delete')

View File

@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub snapshot describe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import snapshots
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import util
class Describe(base.DescribeCommand):
"""Describes a Cloud Pub/Sub snapshot."""
@staticmethod
def Args(parser):
"""Registers flags for this command."""
parser.add_argument('snapshot', help='snapshot to describe.')
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
A serialized object (dict) describing the results of the operation.
This description fits the Resource described in the ResourceRegistry under
'pubsub.projects.snapshots'.
"""
client = snapshots.SnapshotsClient()
snapshot_ref = util.ParseSnapshot(args.snapshot)
return client.Get(snapshot_ref)

View File

@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub snapshots list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import snapshots
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import util
class List(base.ListCommand):
"""Lists all the snapshots in a given project."""
@staticmethod
def Args(parser):
parser.display_info.AddFormat("""
table[box](
projectId:label=PROJECT,
snapshotId:label=SNAPSHOT,
topicId:label=TOPIC,
expireTime:label=EXPIRE_TIME
)
""")
parser.display_info.AddUriFunc(util.SnapshotUriFunc)
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Yields:
Snapshot paths that match the regular expression in args.name_filter.
Raises:
sdk_ex.HttpException if there is an error with the regular
expression syntax.
"""
client = snapshots.SnapshotsClient()
for snapshot in client.List(util.ParseProject(), page_size=args.page_size):
yield util.ListSnapshotDisplayDict(snapshot)

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The main command group for Cloud Pub/Sub subscriptions."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.UniverseCompatible
class Subscriptions(base.Group):
"""Manage Cloud Pub/Sub subscriptions."""
pass

View File

@@ -0,0 +1,120 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscriptions ack command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def _Run(args, ack_ids, legacy_output=False, capture_failures=False):
"""Acks one or more messages."""
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
if not capture_failures:
result = client.Ack(ack_ids, subscription_ref)
log.status.Print(
'Acked the messages with the following ackIds: [{}]'.format(
','.join(ack_ids)))
if legacy_output:
return {
'subscriptionId': subscription_ref.RelativeName(),
'ackIds': ack_ids
}, {}
else:
return result, {}
result = None
ack_ids_and_failure_reasons = {}
try:
result = client.Ack(ack_ids, subscription_ref)
except api_ex.HttpError as error:
ack_ids_and_failure_reasons = util.HandleExactlyOnceDeliveryError(error)
failed_ack_ids, successfully_processed_ack_ids = util.ParseExactlyOnceAckIdsAndFailureReasons(
ack_ids_and_failure_reasons, ack_ids)
log.status.Print('Acked the messages with the following ackIds: [{}]'.format(
','.join(successfully_processed_ack_ids)))
if failed_ack_ids:
log.status.Print(
'Failed to ack the messages with the following ackIds: [{}]'.format(
','.join(failed_ack_ids)))
if legacy_output:
result = {
'subscriptionId': subscription_ref.RelativeName(),
'ackIds': ack_ids
}
return result, ack_ids_and_failure_reasons
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Ack(base.Command):
"""Acknowledges one or more messages on the specified subscription."""
detailed_help = {
'DESCRIPTION':
"""\
Acknowledges one or more messages as having been successfully received.
If a delivered message is not acknowledged within the Subscription's
ack deadline, Cloud Pub/Sub will attempt to deliver it again.
To automatically acknowledge messages when pulling from a Subscription,
you can use the `--auto-ack` flag on `gcloud pubsub subscriptions pull`.
"""
}
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'to ACK messages on.')
flags.AddAckIdFlag(parser, 'acknowledge.')
def Run(self, args):
result, ack_ids_and_failure_reasons = _Run(
args, args.ack_ids, capture_failures=True)
if ack_ids_and_failure_reasons:
return ack_ids_and_failure_reasons
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class AckBeta(Ack):
"""Acknowledges one or more messages on the specified subscription."""
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'to ACK messages on.')
flags.AddAckIdFlag(parser, 'acknowledge.', add_deprecated=True)
def Run(self, args):
ack_ids = flags.ParseAckIdsArgs(args)
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
result, ack_ids_and_failure_reasons = _Run(
args, ack_ids, capture_failures=True, legacy_output=legacy_output)
if ack_ids_and_failure_reasons:
return ack_ids_and_failure_reasons
return result

View File

@@ -0,0 +1,60 @@
release_tracks: [GA, BETA, ALPHA]
help_text:
brief: Add IAM policy binding to a subscription.
description: |
Add an IAM policy binding to a Cloud Pub/Sub Subscription.
examples: |
To add an IAM policy binding with the role of 'roles/editor' for the user 'test-user@example.com'
on the subscription 'my-subscription', run:
$ {command} my-subscription --member='user:test-user@example.com' --role='roles/editor'
To add an IAM policy binding with the role of 'roles/editor' for the service account
'my-iam-account@my-project.iam.gserviceaccount.com' on the subscription 'my-subscription', run:
$ {command} my-subscription \
--member='serviceAccount:my-iam-account@my-project.iam.gserviceaccount.com' \
--role='roles/editor'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
request:
collection: pubsub.projects.subscriptions
arguments:
resource:
help_text: The subscription to add the IAM policy binding.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:subscription
ALPHA:
help_text:
brief: Add IAM policy binding to a subscription.
description: |
Add an IAM policy binding to the IAM policy of a Cloud Pub/Sub Subscription. One binding consists of a member,
a role, and an optional condition.
examples: |
To add an IAM policy binding with the role of 'roles/editor' for the user
'test-user@example.com' on the subscription 'my-subscription', run:
$ {command} my-subscription --member='user:test-user@example.com' --role='roles/editor'
To add an IAM policy binding with the role of 'roles/editor' for the service account
'my-iam-account@my-project.iam.gserviceaccount.com' on the subscription 'my-subscription', run:
$ {command} my-subscription \
--member='serviceAccount:my-iam-account@my-project.iam.gserviceaccount.com' \
--role='roles/editor'
To add an IAM policy binding which expires at the end of the year 2018 for the role of
'roles/pubsub.subscriber' and the user 'test-user@example.com' with subscription 'my-subscription', run:
$ {command} my-subscription --member='user:test-user@example.com' --role='roles/pubsub.subscriber' --condition='expression=request.time < timestamp("2019-01-01T00:00:00Z"),title=expires_end_of_2018,description=Expires at midnight on 2018-12-31'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
iam:
enable_condition: true

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command group for managing Pub/Sub subscription configurations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class Config(base.Group):
"""Manage Pub/Sub subscription configurations."""

View File

@@ -0,0 +1,38 @@
release_tracks: [ALPHA]
command_type: CONFIG_EXPORT
help_text:
brief: Export the configuration for a Pub/Sub subscription.
description: |
*{command}* exports the configuration for a Pub/Sub subscription.
Subscription configurations can be exported in
Kubernetes Resource Model (krm) or Terraform HCL formats. The
default format is `krm`.
Specifying `--all` allows you to export the configurations for all
subscriptions within the project.
Specifying `--path` allows you to export the configuration(s) to
a local directory.
examples: |
To export the configuration for a subscription, run:
$ {command} my-subscription
To export the configuration for a subscription to a file, run:
$ {command} my-subscription --path=/path/to/dir/
To export the configuration for a subscription in Terraform
HCL format, run:
$ {command} my-subscription --resource-format=terraform
To export the configurations for all subscriptions within a
project, run:
$ {command} --all
arguments:
resource:
help_text: Subscription to export the configuration for.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:subscription

View File

@@ -0,0 +1,269 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscriptions create command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def _Run(
args,
/,
*,
enable_labels=False,
legacy_output=False,
enable_push_to_cps=False,
enable_vertex_ai_smt=False,
):
"""Creates one or more subscriptions."""
flags.ValidateDeadLetterPolicy(args)
client = subscriptions.SubscriptionsClient()
topic_ref = args.CONCEPTS.topic.Parse()
push_config = util.ParsePushConfig(args)
enable_message_ordering = getattr(args, 'enable_message_ordering', None)
filter_string = getattr(args, 'message_filter', None)
dead_letter_topic = getattr(args, 'dead_letter_topic', None)
max_delivery_attempts = getattr(args, 'max_delivery_attempts', None)
retain_acked_messages = getattr(args, 'retain_acked_messages', None)
retention_duration = getattr(args, 'message_retention_duration', None)
enable_exactly_once_delivery = getattr(
args, 'enable_exactly_once_delivery', None
)
if args.IsSpecified('message_retention_duration'):
retention_duration = util.FormatDuration(retention_duration)
min_retry_delay = getattr(args, 'min_retry_delay', None)
if args.IsSpecified('min_retry_delay'):
min_retry_delay = util.FormatDuration(min_retry_delay)
max_retry_delay = getattr(args, 'max_retry_delay', None)
if args.IsSpecified('max_retry_delay'):
max_retry_delay = util.FormatDuration(max_retry_delay)
bigquery_table = getattr(args, 'bigquery_table', None)
use_topic_schema = getattr(args, 'use_topic_schema', None)
use_table_schema = getattr(args, 'use_table_schema', None)
write_metadata = getattr(args, 'write_metadata', None)
drop_unknown_fields = getattr(args, 'drop_unknown_fields', None)
bigquery_service_account_email = getattr(
args, 'bigquery_service_account_email', None
)
cloud_storage_bucket = getattr(args, 'cloud_storage_bucket', None)
cloud_storage_file_prefix = getattr(args, 'cloud_storage_file_prefix', None)
cloud_storage_file_suffix = getattr(args, 'cloud_storage_file_suffix', None)
cloud_storage_file_datetime_format = getattr(
args, 'cloud_storage_file_datetime_format', None
)
cloud_storage_max_bytes = getattr(args, 'cloud_storage_max_bytes', None)
cloud_storage_max_duration = getattr(args, 'cloud_storage_max_duration', None)
cloud_storage_max_messages = getattr(args, 'cloud_storage_max_messages', None)
if args.IsSpecified('cloud_storage_max_duration'):
cloud_storage_max_duration = util.FormatDuration(cloud_storage_max_duration)
cloud_storage_output_format_list = getattr(
args, 'cloud_storage_output_format', None
)
cloud_storage_output_format = None
if cloud_storage_output_format_list:
cloud_storage_output_format = cloud_storage_output_format_list[0]
cloud_storage_use_topic_schema = getattr(
args, 'cloud_storage_use_topic_schema', None
)
cloud_storage_write_metadata = getattr(
args, 'cloud_storage_write_metadata', None
)
cloud_storage_service_account_email = getattr(
args, 'cloud_storage_service_account_email', None
)
pubsub_export_topic = (
getattr(args, 'pubsub_export_topic', None) if enable_push_to_cps else None
)
pubsub_export_topic_region = getattr(args, 'pubsub_export_topic_region', None)
message_transforms_file = getattr(args, 'message_transforms_file', None)
no_expiration = False
expiration_period = getattr(args, 'expiration_period', None)
if args.IsSpecified('expiration_period'):
if expiration_period == subscriptions.NEVER_EXPIRATION_PERIOD_VALUE:
no_expiration = True
expiration_period = None
if dead_letter_topic:
dead_letter_topic = args.CONCEPTS.dead_letter_topic.Parse().RelativeName()
if pubsub_export_topic:
pubsub_export_topic = (
args.CONCEPTS.pubsub_export_topic.Parse().RelativeName()
)
labels = None
if enable_labels:
labels = labels_util.ParseCreateArgs(
args, client.messages.Subscription.LabelsValue
)
tags = flags.GetTagsMessage(args, client.messages.Subscription.TagsValue)
failed = []
for subscription_ref in args.CONCEPTS.subscription.Parse():
try:
result = client.Create(
subscription_ref,
topic_ref,
args.ack_deadline,
push_config,
retain_acked_messages,
retention_duration,
labels=labels,
no_expiration=no_expiration,
expiration_period=expiration_period,
enable_message_ordering=enable_message_ordering,
filter_string=filter_string,
dead_letter_topic=dead_letter_topic,
max_delivery_attempts=max_delivery_attempts,
min_retry_delay=min_retry_delay,
max_retry_delay=max_retry_delay,
enable_exactly_once_delivery=enable_exactly_once_delivery,
bigquery_table=bigquery_table,
use_topic_schema=use_topic_schema,
use_table_schema=use_table_schema,
write_metadata=write_metadata,
drop_unknown_fields=drop_unknown_fields,
bigquery_service_account_email=bigquery_service_account_email,
cloud_storage_bucket=cloud_storage_bucket,
cloud_storage_file_prefix=cloud_storage_file_prefix,
cloud_storage_file_suffix=cloud_storage_file_suffix,
cloud_storage_file_datetime_format=cloud_storage_file_datetime_format,
cloud_storage_max_bytes=cloud_storage_max_bytes,
cloud_storage_max_duration=cloud_storage_max_duration,
cloud_storage_max_messages=cloud_storage_max_messages,
cloud_storage_output_format=cloud_storage_output_format,
cloud_storage_use_topic_schema=cloud_storage_use_topic_schema,
cloud_storage_write_metadata=cloud_storage_write_metadata,
cloud_storage_service_account_email=cloud_storage_service_account_email,
pubsub_export_topic=pubsub_export_topic,
pubsub_export_topic_region=pubsub_export_topic_region,
message_transforms_file=message_transforms_file,
tags=tags,
enable_vertex_ai_smt=enable_vertex_ai_smt,
)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.CreatedResource(
subscription_ref.RelativeName(),
kind='subscription',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
failed.append(subscription_ref.subscriptionsId)
continue
if legacy_output:
result = util.SubscriptionDisplayDict(result)
log.CreatedResource(subscription_ref.RelativeName(), kind='subscription')
yield result
if failed:
raise util.RequestsFailedError(failed, 'create')
def _Args(parser, enable_push_to_cps=False):
"""Add flags to the arg parser for creating a subscription."""
topic_help_text = (
'from which this subscription is receiving messages. Each subscription is'
' attached to a single topic.'
)
topic = resource_args.CreateTopicResourceArg(
topic_help_text, positional=False
)
subscription = resource_args.CreateSubscriptionResourceArg(
'to create.', plural=True
)
resource_args.AddResourceArgs(parser, [topic, subscription])
flags.AddSubscriptionSettingsFlags(
parser, enable_push_to_cps=enable_push_to_cps
)
labels_util.AddCreateLabelsFlags(parser)
flags.AddMessageTransformsFlags(parser)
flags.AddTagsFlag(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Creates one or more Cloud Pub/Sub subscriptions."""
detailed_help = {'DESCRIPTION': """\
Creates one or more Cloud Pub/Sub subscriptions for a given topic.
The new subscription defaults to a PULL subscription unless a push
endpoint is specified."""}
@classmethod
def Args(cls, parser):
_Args(parser)
def Run(self, args):
flags.ValidateFilterString(args)
return _Run(args, enable_labels=True)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Creates one or more Cloud Pub/Sub subscriptions."""
@classmethod
def Args(cls, parser):
_Args(parser, enable_push_to_cps=True)
def Run(self, args):
flags.ValidateFilterString(args)
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(
args,
enable_labels=True,
legacy_output=legacy_output,
enable_push_to_cps=True,
)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Creates one or more Cloud Pub/Sub subscriptions."""
@classmethod
def Args(cls, parser):
super(CreateAlpha, cls).Args(parser)
def Run(self, args):
flags.ValidateFilterString(args)
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(
args,
enable_labels=True,
legacy_output=legacy_output,
enable_push_to_cps=True,
enable_vertex_ai_smt=True,
)

View File

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscription delete command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def _Run(args, legacy_output=False):
"""Deletes one or more subscriptions."""
client = subscriptions.SubscriptionsClient()
failed = []
for subscription_ref in args.CONCEPTS.subscription.Parse():
try:
result = client.Delete(subscription_ref)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.DeletedResource(
subscription_ref.RelativeName(),
kind='subscription',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
failed.append(subscription_ref.subscriptionsId)
continue
subscription = client.messages.Subscription(
name=subscription_ref.RelativeName())
if legacy_output:
result = util.SubscriptionDisplayDict(subscription)
log.DeletedResource(subscription_ref.RelativeName(), kind='subscription')
yield result
if failed:
raise util.RequestsFailedError(failed, 'delete')
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Delete(base.DeleteCommand):
"""Deletes one or more Cloud Pub/Sub subscriptions."""
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'to delete.', plural=True)
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class DeleteBeta(Delete):
"""Deletes one or more Cloud Pub/Sub subscriptions."""
def Run(self, args):
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, legacy_output=legacy_output)

View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscription describe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
class Describe(base.DescribeCommand):
"""Describes a Cloud Pub/Sub subscription."""
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'to describe.')
def Run(self, args):
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
return client.Get(subscription_ref)

View File

@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscriptions get-iam-policy command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class GetIamPolicy(base.ListCommand):
"""Get the IAM policy for a Cloud Pub/Sub Subscription."""
detailed_help = {
'DESCRIPTION':
'{description}',
'EXAMPLES':
"""\
To print the IAM policy for a given subscription, run:
$ {command} my-subscription
""",
}
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser,
'to get the IAM policy of.')
base.URI_FLAG.RemoveFromParser(parser)
def Run(self, args):
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
return client.GetIamPolicy(subscription_ref)

View File

@@ -0,0 +1,23 @@
- release_tracks: [ALPHA]
help_text:
brief: Get the IAM policy for a subscription.
description: |
*{command}* displays the IAM policy associated with a subscription.
If formatted as JSON, the output can be edited and used as
a policy file for *set-iam-policy*. The output includes an "etag"
field identifying the version emitted and allowing detection of
concurrent policy updates; see
$ {parent} set-iam-policy for additional details.
examples: |
To print the IAM policy for a given subscription, run:
$ {command} my-subscription
request:
collection: pubsub.projects.subscriptions
arguments:
resource:
help_text: The subscription for which to display the IAM policy.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:subscription

View File

@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscriptions list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import properties
def _Run(args, legacy_output=False):
client = subscriptions.SubscriptionsClient()
for sub in client.List(util.ParseProject(), page_size=args.page_size):
if legacy_output:
sub = util.ListSubscriptionDisplayDict(sub)
yield sub
@base.ReleaseTracks(base.ReleaseTrack.GA)
class List(base.ListCommand):
"""Lists Cloud Pub/Sub subscriptions."""
detailed_help = {
'DESCRIPTION': 'Lists all of the Cloud Pub/Sub subscriptions that exist '
'in a given project.'
}
@staticmethod
def Args(parser):
parser.display_info.AddUriFunc(util.SubscriptionUriFunc)
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class ListBeta(List):
"""Lists Cloud Pub/Sub subscriptions."""
def Run(self, args):
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, legacy_output=legacy_output)

View File

@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscription modify command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
@base.Deprecate(
is_removed=False,
warning='This command has been renamed. Please use '
'`modify-message-ack-deadline` instead.')
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class ModifyAckDeadline(base.Command):
"""Modifies the ACK deadline for a specific Cloud Pub/Sub message.
This method is useful to indicate that more time is needed to process a
message by the subscriber, or to make the message available for
redelivery if the processing was interrupted.
"""
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'messages belong to.')
flags.AddAckIdFlag(parser, 'modify the deadline for.', add_deprecated=True)
flags.AddAckDeadlineFlag(parser, required=True)
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
Display dictionary with information about the new ACK deadline seconds
for the given subscription and ackId.
"""
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
ack_ids = flags.ParseAckIdsArgs(args)
result = None
ack_ids_and_failure_reasons = {}
try:
result = client.ModifyAckDeadline(subscription_ref, ack_ids,
args.ack_deadline)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
ack_ids_and_failure_reasons = util.ParseExactlyOnceErrorInfo(
exc.payload.details)
# If the failure doesn't have more information (specifically for exactly
# once related failures), re-raise the exception.
if not ack_ids_and_failure_reasons:
raise
failed_ack_ids = [ack['AckId'] for ack in ack_ids_and_failure_reasons]
successfully_processed_ack_ids = [
ack_id for ack_id in ack_ids if ack_id not in failed_ack_ids
]
log.status.Print('Set ackDeadlineSeconds to [{0}] for messages with ackId '
'[{1}]] for subscription [{2}]'.format(
args.ack_deadline,
','.join(successfully_processed_ack_ids),
subscription_ref.RelativeName()))
if failed_ack_ids:
log.status.Print(
'Set ackDeadlineSeconds to [{0}] for messages with ackId '
'[{1}]] failed for subscription [{2}]'.format(
args.ack_deadline, ','.join(failed_ack_ids),
subscription_ref.RelativeName()))
if ack_ids_and_failure_reasons:
return ack_ids_and_failure_reasons
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
if legacy_output:
result = {
'subscriptionId': subscription_ref.RelativeName(),
'ackId': ack_ids,
'ackDeadlineSeconds': args.ack_deadline
}
return result

View File

@@ -0,0 +1,128 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscription modify command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def _Run(args, ack_ids, legacy_output=False, capture_failures=False):
"""Modifies the ack deadline for one or more messages."""
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
if not capture_failures:
result = client.ModifyAckDeadline(subscription_ref, ack_ids,
args.ack_deadline)
log.status.Print('Set ackDeadlineSeconds to [{0}] for messages with ackId '
'[{1}]] for subscription [{2}]'.format(
args.ack_deadline, ','.join(ack_ids),
subscription_ref.RelativeName()))
if legacy_output:
return {
'subscriptionId': subscription_ref.RelativeName(),
'ackId': ack_ids,
'ackDeadlineSeconds': args.ack_deadline
}, {}
else:
return result, {}
result = None
ack_ids_and_failure_reasons = {}
try:
result = client.ModifyAckDeadline(subscription_ref, ack_ids,
args.ack_deadline)
except api_ex.HttpError as error:
ack_ids_and_failure_reasons = util.HandleExactlyOnceDeliveryError(error)
failed_ack_ids, successfully_processed_ack_ids = util.ParseExactlyOnceAckIdsAndFailureReasons(
ack_ids_and_failure_reasons, ack_ids)
log.status.Print('Set ackDeadlineSeconds to [{0}] for messages with ackId '
'[{1}]] for subscription [{2}]'.format(
args.ack_deadline,
','.join(successfully_processed_ack_ids),
subscription_ref.RelativeName()))
if failed_ack_ids:
log.status.Print('Set ackDeadlineSeconds to [{0}] for messages with ackId '
'[{1}]] failed for subscription [{2}]'.format(
args.ack_deadline, ','.join(failed_ack_ids),
subscription_ref.RelativeName()))
if legacy_output:
result = {
'subscriptionId': subscription_ref.RelativeName(),
'ackId': ack_ids,
'ackDeadlineSeconds': args.ack_deadline
}
return result, ack_ids_and_failure_reasons
@base.ReleaseTracks(base.ReleaseTrack.GA)
class ModifyMessageAckDeadline(base.Command):
"""Modifies the ACK deadline for a specific Cloud Pub/Sub message."""
detailed_help = {
'DESCRIPTION':
"""\
This method is useful to indicate that more time is needed to process
a message by the subscriber, or to make the message available for
redelivery if the processing was interrupted."""
}
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'messages belong to.')
flags.AddAckIdFlag(parser, 'modify the deadline for.')
flags.AddAckDeadlineFlag(parser, required=True)
def Run(self, args):
result, ack_ids_and_failure_reasons = _Run(
args, args.ack_ids, capture_failures=True)
if ack_ids_and_failure_reasons:
return ack_ids_and_failure_reasons
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class ModifyMessageAckDeadlineBeta(ModifyMessageAckDeadline):
"""Modifies the ACK deadline for a specific Cloud Pub/Sub message."""
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'messages belong to.')
flags.AddAckIdFlag(parser, 'modify the deadline for.', add_deprecated=True)
flags.AddAckDeadlineFlag(parser, required=True)
def Run(self, args):
ack_ids = flags.ParseAckIdsArgs(args)
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
result, ack_ids_and_failure_reasons = _Run(
args, ack_ids, legacy_output=legacy_output, capture_failures=True)
if ack_ids_and_failure_reasons:
return ack_ids_and_failure_reasons
return result

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscription modify-push-config command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def _Run(args, legacy_output=False):
"""Modifies the push config for a subscription."""
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
push_config = util.ParsePushConfig(args)
result = client.ModifyPushConfig(subscription_ref, push_config)
log.UpdatedResource(subscription_ref.RelativeName(), kind='subscription')
if legacy_output:
return {
'subscriptionId': subscription_ref.RelativeName(),
'pushEndpoint': args.push_endpoint
}
else:
return result
def _Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'to modify.')
flags.AddPushConfigFlags(
parser, required=True, is_modify_push_config_request=True
)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class ModifyPushConfig(base.Command):
"""Modifies the push configuration of a Cloud Pub/Sub subscription."""
@classmethod
def Args(cls, parser):
_Args(parser)
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class ModifyPushConfigBeta(ModifyPushConfig):
"""Modifies the push configuration of a Cloud Pub/Sub subscription."""
@classmethod
def Args(cls, parser):
_Args(parser)
def Run(self, args):
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, legacy_output=legacy_output)

View File

@@ -0,0 +1,165 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscription pull command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.api_lib.util import exceptions as util_ex
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
import six
MESSAGE_FORMAT = """\
table[box](
message.data.decode(base64).decode(utf-8),
message.messageId,
message.orderingKey,
message.attributes.list(separator='\n'),
deliveryAttempt,
ackId.if(NOT auto_ack)
)
"""
MESSAGE_FORMAT_WITH_ACK_STATUS = """\
table[box](
message.data.decode(base64).decode(utf-8),
message.messageId,
message.orderingKey,
message.attributes.list(separator='\n'),
deliveryAttempt,
ackId.if(NOT auto_ack),
ackStatus.if(auto_ack)
)
"""
def _Run(args, max_messages, return_immediately=False):
"""Pulls messages from a subscription."""
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
pull_response = client.Pull(subscription_ref, max_messages,
return_immediately)
failed_ack_ids = {}
ack_ids_and_failure_reasons = []
if args.auto_ack and pull_response.receivedMessages:
ack_ids = [message.ackId for message in pull_response.receivedMessages]
try:
client.Ack(ack_ids, subscription_ref)
except api_ex.HttpError as error:
exc = util_ex.HttpException(error)
ack_ids_and_failure_reasons = util.ParseExactlyOnceErrorInfo(
exc.payload.details)
# If the failure doesn't have more information (specifically for exactly
# once related failures), assume all the ack ids have failed with the
# same status.
if not ack_ids_and_failure_reasons:
for ack_id in ack_ids:
failed_ack_ids[ack_id] = 'FAILURE_' + six.text_type(error.status_code)
if not failed_ack_ids:
for ack_ids_and_failure_reason in ack_ids_and_failure_reasons:
failed_ack_ids[ack_ids_and_failure_reason[
'AckId']] = ack_ids_and_failure_reason['FailureReason']
if not args.auto_ack:
return pull_response.receivedMessages
# We attempted to auto-ack this message. Augment the response with ackStatus.
return_val = []
for message in pull_response.receivedMessages:
# Copy the message into a separate object so we can mutate it.
message_copy = {}
for field in message.all_fields():
value = getattr(message, field.name)
if value:
message_copy[field.name] = value
if message.ackId in failed_ack_ids:
message_copy['ackStatus'] = failed_ack_ids[message.ackId]
else:
message_copy['ackStatus'] = 'SUCCESS'
return_val.append(message_copy)
return return_val
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Pull(base.ListCommand):
"""Pulls one or more Cloud Pub/Sub messages from a subscription."""
detailed_help = {
'DESCRIPTION':
"""\
Returns one or more messages from the specified Cloud Pub/Sub
subscription, if there are any messages enqueued.
By default, this command returns only one message from the
subscription. Use the `--limit` flag to specify the max messages to
return.
Please note that this command is not guaranteed to return all the
messages in your backlog or the maximum specified in the --limit
argument. Receiving fewer messages than available occasionally
is normal."""
}
@staticmethod
def Args(parser):
parser.display_info.AddFormat(MESSAGE_FORMAT_WITH_ACK_STATUS)
resource_args.AddSubscriptionResourceArg(parser, 'to pull messages from.')
flags.AddPullFlags(parser)
base.LIMIT_FLAG.SetDefault(parser, 1)
def Run(self, args):
return _Run(args, args.limit)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class PullBeta(Pull):
"""Pulls one or more Cloud Pub/Sub messages from a subscription."""
@staticmethod
def Args(parser):
parser.display_info.AddFormat(MESSAGE_FORMAT_WITH_ACK_STATUS)
resource_args.AddSubscriptionResourceArg(parser, 'to pull messages from.')
flags.AddPullFlags(
parser, add_deprecated=True, add_wait=True, add_return_immediately=True
)
def Run(self, args):
if args.IsSpecified('limit'):
if args.IsSpecified('max_messages'):
raise exceptions.ConflictingArgumentsException('--max-messages',
'--limit')
max_messages = args.limit
else:
max_messages = args.max_messages
return_immediately = False
if args.IsSpecified('return_immediately'):
return_immediately = args.return_immediately
elif args.IsSpecified('wait'):
return_immediately = not args.wait
return _Run(args, max_messages, return_immediately)

View File

@@ -0,0 +1,60 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Remove IAM policy binding of a subscription
description: |
Remove an IAM policy binding of a Cloud Pub/Sub Subscription.
examples: |
To Remove an IAM policy binding for the role of 'roles/editor' for the user 'test-user@gmail.com'
with subscription 'my-subscription', run:
$ {command} my-subscription --member='user:test-user@gmail.com' --role='roles/editor'
The following command will remove an IAM policy binding for the role of
'roles/editor' from all authenticated users on subscription
'my-subscription':
$ {command} my-subscription --member='allAuthenticatedUsers' \
--role='roles/editor'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
request:
collection: pubsub.projects.subscriptions
arguments:
resource:
help_text: The subscription to remove the IAM policy binding from.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:subscription
ALPHA:
help_text:
brief: Remove IAM policy binding of a subscription.
description: |
Remove an IAM policy binding from the IAM policy of a Cloud Pub/Sub Subscription. One binding consists of a member,
a role, and an optional condition.
examples: |
To remove an IAM policy binding for the role of 'roles/editor' for the user 'test-user@gmail.com'
with subscription 'my-subscription', run:
$ {command} my-subscription --member='user:test-user@gmail.com' --role='roles/editor'
The following command will remove an IAM policy binding for the role of
'roles/editor' from all authenticated users on subscription
'my-subscription':
$ {command} my-subscription --member='allAuthenticatedUsers' \
--role='roles/editor'
To remove an IAM policy binding which expires at the end of the year 2018 for the role of
'roles/pubsub.subscriber' and the user 'test-user@gmail.com' with subscription 'my-subscription', run:
$ {command} my-subscription --member='user:test-user@gmail.com' --role='roles/pubsub.subscriber' --condition='expression=request.time < timestamp("2019-01-01T00:00:00Z"),title=expires_end_of_2018,description=Expires at midnight on 2018-12-31'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
iam:
enable_condition: true

View File

@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscriptions seek command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
def _Run(args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
A serialized object (dict) describing the results of the operation. This
description fits the Resource described in the ResourceRegistry under
'pubsub.subscriptions.seek'.
"""
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
result = {'subscriptionId': subscription_ref.RelativeName()}
snapshot_ref = None
time = None
if args.snapshot:
snapshot_ref = util.ParseSnapshot(args.snapshot, args.snapshot_project)
result['snapshotId'] = snapshot_ref.RelativeName()
else:
time = util.FormatSeekTime(args.time)
result['time'] = time
client.Seek(subscription_ref, time=time, snapshot_ref=snapshot_ref)
return result
@base.DefaultUniverseOnly
class Seek(base.Command):
"""Resets a subscription's backlog to a point in time or to a given snapshot."""
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'to affect.')
flags.AddSeekFlags(parser)
def Run(self, args):
return _Run(args)

View File

@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscriptions set-iam-policy command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.iam import iam_util
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.core import log
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class SetIamPolicy(base.Command):
"""Set the IAM policy for a Cloud Pub/Sub Subscription."""
detailed_help = iam_util.GetDetailedHelpForSetIamPolicy(
'subscription', 'my-subscription')
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'to set an IAM policy on.')
flags.AddIamPolicyFileFlag(parser)
def Run(self, args):
client = subscriptions.SubscriptionsClient()
messages = client.messages
subscription_ref = args.CONCEPTS.subscription.Parse()
policy = iam_util.ParsePolicyFile(args.policy_file, messages.Policy)
response = client.SetIamPolicy(subscription_ref, policy=policy)
log.status.Print('Updated IAM policy for subscription [{}].'.format(
subscription_ref.Name()))
return response

View File

@@ -0,0 +1,30 @@
- release_tracks: [ALPHA]
help_text:
brief: Set the IAM policy for a Cloud Pub/Sub Subscription.
description: |
This command replaces the existing IAM policy for a subscription, given a
subscription and a file encoded in JSON or YAML that contains the IAM
policy.
If the given policy file specifies an "etag" value, then the
replacement will succeed only if the policy already in place matches that
etag. (An etag obtained via `get-iam-policy` will prevent the replacement
if the policy for the subscription has been subsequently updated.) A
policy file that does not contain an etag value will replace any existing
policy for the subscription.
examples: |
The following command will read an IAM policy defined in 'policy.json'
and set it for a subscription 'my-sub'
$ {command} my-sub policy.json
See https://cloud.google.com/iam/docs/managing-policies for details of
the policy file format and contents.
request:
collection: pubsub.projects.subscriptions
arguments:
resource:
help_text: The subscription for which to set the IAM policy.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:subscription

View File

@@ -0,0 +1,280 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub subscriptions update command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import subscriptions
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
def _Args(
parser,
enable_push_to_cps=False,
):
"""Adds the arguments for this command.
Args:
parser: the parser for the command.
enable_push_to_cps: whether or not to enable Pubsub Export config flags
support.
"""
resource_args.AddSubscriptionResourceArg(parser, 'to update.')
flags.AddSubscriptionSettingsFlags(
parser,
is_update=True,
enable_push_to_cps=enable_push_to_cps,
)
labels_util.AddUpdateLabelsFlags(parser)
flags.AddMessageTransformsFlags(parser, is_update=True)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Updates an existing Cloud Pub/Sub subscription."""
@classmethod
def Args(cls, parser):
_Args(parser)
@exceptions.CatchHTTPErrorRaiseHTTPException()
def Run(
self,
args,
/,
*,
enable_push_to_cps=False,
enable_vertex_ai_smt=False,
):
"""This is what gets called when the user runs this command.
Args:
args: An argparse namespace. All the arguments that were provided to this
command invocation.
enable_push_to_cps: Whether or not to enable Pubsub Export config flags
support.
enable_vertex_ai_smt: Whether to enable Vertex AI SMTs.
Returns:
A serialized object (dict) describing the results of the operation. This
description fits the Resource described in the ResourceRegistry under
'pubsub.projects.subscriptions'.
Raises:
An HttpException if there was a problem calling the
API subscriptions.Patch command.
"""
flags.ValidateDeadLetterPolicy(args)
client = subscriptions.SubscriptionsClient()
subscription_ref = args.CONCEPTS.subscription.Parse()
dead_letter_topic = getattr(args, 'dead_letter_topic', None)
max_delivery_attempts = getattr(args, 'max_delivery_attempts', None)
clear_dead_letter_policy = getattr(args, 'clear_dead_letter_policy', None)
clear_retry_policy = getattr(args, 'clear_retry_policy', None)
clear_bigquery_config = getattr(args, 'clear_bigquery_config', None)
clear_cloud_storage_config = getattr(
args, 'clear_cloud_storage_config', None
)
clear_push_no_wrapper_config = getattr(
args, 'clear_push_no_wrapper_config', None
)
clear_pubsub_export_config = (
getattr(args, 'clear_pubsub_export_config', None)
if enable_push_to_cps
else None
)
labels_update = labels_util.ProcessUpdateArgsLazy(
args,
client.messages.Subscription.LabelsValue,
orig_labels_thunk=lambda: client.Get(subscription_ref).labels,
)
no_expiration = False
expiration_period = getattr(args, 'expiration_period', None)
if expiration_period:
if expiration_period == subscriptions.NEVER_EXPIRATION_PERIOD_VALUE:
no_expiration = True
expiration_period = None
if dead_letter_topic:
dead_letter_topic = args.CONCEPTS.dead_letter_topic.Parse().RelativeName()
min_retry_delay = getattr(args, 'min_retry_delay', None)
if args.IsSpecified('min_retry_delay'):
min_retry_delay = util.FormatDuration(min_retry_delay)
max_retry_delay = getattr(args, 'max_retry_delay', None)
if args.IsSpecified('max_retry_delay'):
max_retry_delay = util.FormatDuration(max_retry_delay)
bigquery_table = getattr(args, 'bigquery_table', None)
use_topic_schema = getattr(args, 'use_topic_schema', None)
use_table_schema = getattr(args, 'use_table_schema', None)
write_metadata = getattr(args, 'write_metadata', None)
drop_unknown_fields = getattr(args, 'drop_unknown_fields', None)
bigquery_service_account_email = getattr(
args, 'bigquery_service_account_email', None
)
cloud_storage_bucket = getattr(args, 'cloud_storage_bucket', None)
cloud_storage_file_prefix = getattr(args, 'cloud_storage_file_prefix', None)
cloud_storage_file_suffix = getattr(args, 'cloud_storage_file_suffix', None)
cloud_storage_file_datetime_format = getattr(
args, 'cloud_storage_file_datetime_format', None
)
cloud_storage_max_bytes = getattr(args, 'cloud_storage_max_bytes', None)
cloud_storage_max_duration = getattr(
args, 'cloud_storage_max_duration', None
)
cloud_storage_max_messages = getattr(
args, 'cloud_storage_max_messages', None
)
if args.IsSpecified('cloud_storage_max_duration'):
cloud_storage_max_duration = util.FormatDuration(
cloud_storage_max_duration
)
cloud_storage_output_format_list = getattr(
args, 'cloud_storage_output_format', None
)
cloud_storage_output_format = None
if cloud_storage_output_format_list:
cloud_storage_output_format = cloud_storage_output_format_list[0]
cloud_storage_use_topic_schema = getattr(
args, 'cloud_storage_use_topic_schema', None
)
cloud_storage_write_metadata = getattr(
args, 'cloud_storage_write_metadata', None
)
cloud_storage_service_account_email = getattr(
args, 'cloud_storage_service_account_email', None
)
pubsub_export_topic = (
getattr(args, 'pubsub_export_topic', None)
if enable_push_to_cps
else None
)
if pubsub_export_topic:
pubsub_export_topic = (
args.CONCEPTS.pubsub_export_topic.Parse().RelativeName()
)
pubsub_export_topic_region = getattr(
args, 'pubsub_export_topic_region', None
)
enable_exactly_once_delivery = getattr(
args, 'enable_exactly_once_delivery', None
)
message_transforms_file = getattr(args, 'message_transforms_file', None)
clear_message_transforms = getattr(args, 'clear_message_transforms', None)
try:
result = client.Patch(
subscription_ref,
ack_deadline=args.ack_deadline,
push_config=util.ParsePushConfig(args),
retain_acked_messages=args.retain_acked_messages,
labels=labels_update.GetOrNone(),
message_retention_duration=args.message_retention_duration,
no_expiration=no_expiration,
expiration_period=expiration_period,
dead_letter_topic=dead_letter_topic,
max_delivery_attempts=max_delivery_attempts,
clear_dead_letter_policy=clear_dead_letter_policy,
clear_retry_policy=clear_retry_policy,
min_retry_delay=min_retry_delay,
max_retry_delay=max_retry_delay,
enable_exactly_once_delivery=enable_exactly_once_delivery,
bigquery_table=bigquery_table,
use_topic_schema=use_topic_schema,
use_table_schema=use_table_schema,
write_metadata=write_metadata,
drop_unknown_fields=drop_unknown_fields,
bigquery_service_account_email=bigquery_service_account_email,
clear_bigquery_config=clear_bigquery_config,
cloud_storage_bucket=cloud_storage_bucket,
cloud_storage_file_prefix=cloud_storage_file_prefix,
cloud_storage_file_suffix=cloud_storage_file_suffix,
cloud_storage_file_datetime_format=cloud_storage_file_datetime_format,
cloud_storage_max_bytes=cloud_storage_max_bytes,
cloud_storage_max_duration=cloud_storage_max_duration,
cloud_storage_max_messages=cloud_storage_max_messages,
cloud_storage_output_format=cloud_storage_output_format,
cloud_storage_use_topic_schema=cloud_storage_use_topic_schema,
cloud_storage_write_metadata=cloud_storage_write_metadata,
cloud_storage_service_account_email=cloud_storage_service_account_email,
clear_cloud_storage_config=clear_cloud_storage_config,
clear_push_no_wrapper_config=clear_push_no_wrapper_config,
pubsub_export_topic=pubsub_export_topic,
pubsub_export_topic_region=pubsub_export_topic_region,
clear_pubsub_export_config=clear_pubsub_export_config,
message_transforms_file=message_transforms_file,
clear_message_transforms=clear_message_transforms,
enable_vertex_ai_smt=enable_vertex_ai_smt,
)
except subscriptions.NoFieldsSpecifiedError:
if not any(
args.IsSpecified(arg)
for arg in ('clear_labels', 'update_labels', 'remove_labels')
):
raise
log.status.Print('No update to perform.')
result = None
else:
log.UpdatedResource(subscription_ref.RelativeName(), kind='subscription')
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Updates an existing Cloud Pub/Sub subscription."""
@classmethod
def Args(cls, parser):
_Args(
parser,
enable_push_to_cps=True,
)
@exceptions.CatchHTTPErrorRaiseHTTPException()
def Run(self, args, /, *, enable_vertex_ai_smt=False):
return super(UpdateBeta, self).Run(
args,
enable_push_to_cps=True,
enable_vertex_ai_smt=enable_vertex_ai_smt,
)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Updates an existing Cloud Pub/Sub subscription."""
@classmethod
def Args(cls, parser):
super(UpdateAlpha, cls).Args(parser)
@exceptions.CatchHTTPErrorRaiseHTTPException()
def Run(self, args):
return super(UpdateAlpha, self).Run(args, enable_vertex_ai_smt=True)

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The main command group for Cloud Pub/Sub topics."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.UniverseCompatible
class Topics(base.Group):
"""Manage Cloud Pub/Sub topics."""
pass

View File

@@ -0,0 +1,56 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Add IAM policy binding to a topic.
description: |
Add an IAM policy binding to a Cloud Pub/Sub Topic.
examples: |
To add an IAM policy binding with the role of 'roles/editor' for the user 'test-user@example.com'
on the topic 'my-topic', run:
$ {command} my-topic --member='user:test-user@example.com' --role='roles/editor'
To add an IAM policy binding with the role of 'roles/editor' for the service account
'my-iam-account@my-project.iam.gserviceaccount.com' on the topic 'my-topic', run:
$ {command} my-topic --member='serviceAccount:my-iam-account@my-project.iam.gserviceaccount.com' --role='roles/editor'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
request:
collection: pubsub.projects.topics
arguments:
resource:
help_text: The topic to add the IAM policy binding.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:topic
ALPHA:
help_text:
brief: Add IAM policy binding to a topic.
description: |
Add an IAM policy binding to the IAM policy of a Cloud Pub/Sub Topic. One binding consists of a member,
a role, and an optional condition.
examples: |
To add an IAM policy binding with the role of 'roles/editor' for the user
'test-user@example.com' on the topic 'my-topic', run:
$ {command} my-topic --member='user:test-user@example.com' --role='roles/editor'
To add an IAM policy binding with the role of 'roles/editor' for the service account
'my-iam-account@my-project.iam.gserviceaccount.com' on the topic 'my-topic', run:
$ {command} my-topic --member='serviceAccount:my-iam-account@my-project.iam.gserviceaccount.com' --role='roles/editor'
To add an IAM policy binding which expires at the end of the year 2018 for the role of
'roles/pubsub.publisher' and the user 'test-user@example.com' with topic 'my-topic', run:
$ {command} my-topic --member='user:test-user@example.com' --role='roles/pubsub.publisher' --condition='expression=request.time < timestamp("2019-01-01T00:00:00Z"),title=expires_end_of_2018,description=Expires at midnight on 2018-12-31'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
iam:
enable_condition: true

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*- #
# Copyright 2021 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command group for managing Pub/Sub topic configurations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class Config(base.Group):
"""Manage Pub/Sub topic configurations."""

View File

@@ -0,0 +1,38 @@
release_tracks: [ALPHA]
command_type: CONFIG_EXPORT
help_text:
brief: Export the configuration for a Pub/Sub topic.
description: |
*{command}* exports the configuration for a Pub/Sub topic.
Topic configurations can be exported in
Kubernetes Resource Model (krm) or Terraform HCL formats. The
default format is `krm`.
Specifying `--all` allows you to export the configurations for all
topics within the project.
Specifying `--path` allows you to export the configuration(s) to
a local directory.
examples: |
To export the configuration for a topic, run:
$ {command} my-topic
To export the configuration for a topic to a file, run:
$ {command} my-topic --path=/path/to/dir/
To export the configuration for a topic in Terraform
HCL format, run:
$ {command} my-topic --resource-format=terraform
To export the configurations for all topics within a
project, run:
$ {command} --all
arguments:
resource:
help_text: Topic to export the configuration for.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:topic

View File

@@ -0,0 +1,337 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics create command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.kms import resource_args as kms_resource_args
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import exceptions as core_exceptions
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
_KMS_FLAG_OVERRIDES = {
'kms-key': '--topic-encryption-key',
'kms-keyring': '--topic-encryption-key-keyring',
'kms-location': '--topic-encryption-key-location',
'kms-project': '--topic-encryption-key-project',
}
_KMS_PERMISSION_INFO = """
The specified Cloud KMS key should have purpose set to "ENCRYPT_DECRYPT".
The service account,
"service-${CONSUMER_PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
requires the IAM cryptoKeyEncrypterDecrypter role for the given Cloud KMS key.
CONSUMER_PROJECT_NUMBER is the project number of the project that is the parent of the
topic being created"""
def _GetKmsKeyPresentationSpec():
return kms_resource_args.GetKmsKeyPresentationSpec(
'topic',
flag_overrides=_KMS_FLAG_OVERRIDES,
permission_info=_KMS_PERMISSION_INFO,
)
def _GetTopicPresentationSpec():
return resource_args.CreateTopicResourceArg(
'to create.', positional=True, plural=True
)
def _Run(args, /, *, legacy_output=False, enable_vertex_ai_smt=False):
"""Creates one or more topics."""
client = topics.TopicsClient()
labels = labels_util.ParseCreateArgs(args, client.messages.Topic.LabelsValue)
kms_key = None
kms_ref = args.CONCEPTS.kms_key.Parse()
if kms_ref:
kms_key = kms_ref.RelativeName()
else:
# Did user supply any topic-encryption-key flags?
for keyword in [
'topic-encryption-key',
'topic-encryption-key-project',
'topic-encryption-key-location',
'topic-encryption-key-keyring',
]:
if args.IsSpecified(keyword.replace('-', '_')):
raise core_exceptions.Error(
'--topic-encryption-key was not fully specified.'
)
retention_duration = getattr(args, 'message_retention_duration', None)
if args.IsSpecified('message_retention_duration'):
retention_duration = util.FormatDuration(retention_duration)
message_storage_policy_allowed_regions = (
args.message_storage_policy_allowed_regions
)
message_storage_policy_enforce_in_transit = getattr(
args, 'message_storage_policy_enforce_in_transit', None
)
schema = getattr(args, 'schema', None)
first_revision_id = None
last_revision_id = None
if schema:
schema = args.CONCEPTS.schema.Parse().RelativeName()
first_revision_id = getattr(args, 'first_revision_id', None)
last_revision_id = getattr(args, 'last_revision_id', None)
message_encoding_list = getattr(args, 'message_encoding', None)
message_encoding = None
if message_encoding_list:
message_encoding = message_encoding_list[0]
kinesis_ingestion_stream_arn = getattr(
args, 'kinesis_ingestion_stream_arn', None
)
kinesis_ingestion_consumer_arn = getattr(
args, 'kinesis_ingestion_consumer_arn', None
)
kinesis_ingestion_role_arn = getattr(args, 'kinesis_ingestion_role_arn', None)
kinesis_ingestion_service_account = getattr(
args, 'kinesis_ingestion_service_account', None
)
cloud_storage_ingestion_bucket = getattr(
args, 'cloud_storage_ingestion_bucket', None
)
cloud_storage_ingestion_input_format_list = getattr(
args, 'cloud_storage_ingestion_input_format', None
)
cloud_storage_ingestion_input_format = None
if cloud_storage_ingestion_input_format_list:
cloud_storage_ingestion_input_format = (
cloud_storage_ingestion_input_format_list[0]
)
cloud_storage_ingestion_text_delimiter = getattr(
args, 'cloud_storage_ingestion_text_delimiter', None
)
if cloud_storage_ingestion_text_delimiter:
# Interprets special characters representations (i.e., "\n") as their
# expected characters (i.e., newline).
cloud_storage_ingestion_text_delimiter = (
cloud_storage_ingestion_text_delimiter.encode('utf-8').decode(
'unicode-escape'
)
)
cloud_storage_ingestion_minimum_object_create_time = getattr(
args, 'cloud_storage_ingestion_minimum_object_create_time', None
)
cloud_storage_ingestion_match_glob = getattr(
args, 'cloud_storage_ingestion_match_glob', None
)
azure_event_hubs_ingestion_resource_group = getattr(
args, 'azure_event_hubs_ingestion_resource_group', None
)
azure_event_hubs_ingestion_namespace = getattr(
args, 'azure_event_hubs_ingestion_namespace', None
)
azure_event_hubs_ingestion_event_hub = getattr(
args, 'azure_event_hubs_ingestion_event_hub', None
)
azure_event_hubs_ingestion_client_id = getattr(
args, 'azure_event_hubs_ingestion_client_id', None
)
azure_event_hubs_ingestion_tenant_id = getattr(
args, 'azure_event_hubs_ingestion_tenant_id', None
)
azure_event_hubs_ingestion_subscription_id = getattr(
args, 'azure_event_hubs_ingestion_subscription_id', None
)
azure_event_hubs_ingestion_service_account = getattr(
args, 'azure_event_hubs_ingestion_service_account', None
)
aws_msk_ingestion_cluster_arn = getattr(
args, 'aws_msk_ingestion_cluster_arn', None
)
aws_msk_ingestion_topic = getattr(args, 'aws_msk_ingestion_topic', None)
aws_msk_ingestion_aws_role_arn = getattr(
args, 'aws_msk_ingestion_aws_role_arn', None
)
aws_msk_ingestion_service_account = getattr(
args, 'aws_msk_ingestion_service_account', None
)
confluent_cloud_ingestion_bootstrap_server = getattr(
args, 'confluent_cloud_ingestion_bootstrap_server', None
)
confluent_cloud_ingestion_cluster_id = getattr(
args, 'confluent_cloud_ingestion_cluster_id', None
)
confluent_cloud_ingestion_topic = getattr(
args, 'confluent_cloud_ingestion_topic', None
)
confluent_cloud_ingestion_identity_pool_id = getattr(
args, 'confluent_cloud_ingestion_identity_pool_id', None
)
confluent_cloud_ingestion_service_account = getattr(
args, 'confluent_cloud_ingestion_service_account', None
)
ingestion_log_severity = getattr(args, 'ingestion_log_severity', None)
message_transforms_file = getattr(args, 'message_transforms_file', None)
tags = flags.GetTagsMessage(args, client.messages.Topic.TagsValue)
failed = []
for topic_ref in args.CONCEPTS.topic.Parse():
try:
result = client.Create(
topic_ref,
labels=labels,
kms_key=kms_key,
message_retention_duration=retention_duration,
message_storage_policy_allowed_regions=message_storage_policy_allowed_regions,
message_storage_policy_enforce_in_transit=message_storage_policy_enforce_in_transit,
schema=schema,
message_encoding=message_encoding,
first_revision_id=first_revision_id,
last_revision_id=last_revision_id,
kinesis_ingestion_stream_arn=kinesis_ingestion_stream_arn,
kinesis_ingestion_consumer_arn=kinesis_ingestion_consumer_arn,
kinesis_ingestion_role_arn=kinesis_ingestion_role_arn,
kinesis_ingestion_service_account=kinesis_ingestion_service_account,
cloud_storage_ingestion_bucket=cloud_storage_ingestion_bucket,
cloud_storage_ingestion_input_format=cloud_storage_ingestion_input_format,
cloud_storage_ingestion_text_delimiter=cloud_storage_ingestion_text_delimiter,
cloud_storage_ingestion_minimum_object_create_time=cloud_storage_ingestion_minimum_object_create_time,
cloud_storage_ingestion_match_glob=cloud_storage_ingestion_match_glob,
azure_event_hubs_ingestion_resource_group=azure_event_hubs_ingestion_resource_group,
azure_event_hubs_ingestion_namespace=azure_event_hubs_ingestion_namespace,
azure_event_hubs_ingestion_event_hub=azure_event_hubs_ingestion_event_hub,
azure_event_hubs_ingestion_client_id=azure_event_hubs_ingestion_client_id,
azure_event_hubs_ingestion_tenant_id=azure_event_hubs_ingestion_tenant_id,
azure_event_hubs_ingestion_subscription_id=azure_event_hubs_ingestion_subscription_id,
azure_event_hubs_ingestion_service_account=azure_event_hubs_ingestion_service_account,
aws_msk_ingestion_cluster_arn=aws_msk_ingestion_cluster_arn,
aws_msk_ingestion_topic=aws_msk_ingestion_topic,
aws_msk_ingestion_aws_role_arn=aws_msk_ingestion_aws_role_arn,
aws_msk_ingestion_service_account=aws_msk_ingestion_service_account,
confluent_cloud_ingestion_bootstrap_server=confluent_cloud_ingestion_bootstrap_server,
confluent_cloud_ingestion_cluster_id=confluent_cloud_ingestion_cluster_id,
confluent_cloud_ingestion_topic=confluent_cloud_ingestion_topic,
confluent_cloud_ingestion_identity_pool_id=confluent_cloud_ingestion_identity_pool_id,
confluent_cloud_ingestion_service_account=confluent_cloud_ingestion_service_account,
ingestion_log_severity=ingestion_log_severity,
message_transforms_file=message_transforms_file,
tags=tags,
enable_vertex_ai_smt=enable_vertex_ai_smt,
)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.CreatedResource(
topic_ref.RelativeName(),
kind='topic',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
failed.append(topic_ref.topicsId)
continue
if legacy_output:
result = util.TopicDisplayDict(result)
log.CreatedResource(topic_ref.RelativeName(), kind='topic')
yield result
if failed:
raise util.RequestsFailedError(failed, 'create')
def _Args(
parser,
):
"""Custom args implementation.
Args:
parser: The current parser.
"""
resource_args.AddResourceArgs(
parser, [_GetKmsKeyPresentationSpec(), _GetTopicPresentationSpec()]
)
# This group should not be hidden
flags.AddSchemaSettingsFlags(parser, is_update=False)
flags.AddIngestionDatasourceFlags(
parser,
is_update=False,
)
labels_util.AddCreateLabelsFlags(parser)
flags.AddTopicMessageRetentionFlags(parser, is_update=False)
flags.AddTopicMessageStoragePolicyFlags(parser, is_update=False)
flags.AddMessageTransformsFlags(parser)
flags.AddTagsFlag(parser)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Creates one or more Cloud Pub/Sub topics."""
detailed_help = {'EXAMPLES': """\
To create a Cloud Pub/Sub topic, run:
$ {command} mytopic"""}
@staticmethod
def Args(parser):
_Args(
parser,
)
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Creates one or more Cloud Pub/Sub topics."""
@staticmethod
def Args(parser):
_Args(
parser,
)
def Run(self, args):
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, legacy_output=legacy_output, enable_vertex_ai_smt=False)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Creates one or more Cloud Pub/Sub topics."""
@staticmethod
def Args(parser):
super(CreateAlpha, CreateAlpha).Args(parser)
def Run(self, args):
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, legacy_output=legacy_output, enable_vertex_ai_smt=True)

View File

@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics delete command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def _Run(args, legacy_output=False):
"""Deletes one or more topics."""
client = topics.TopicsClient()
failed = []
for topic_ref in args.CONCEPTS.topic.Parse():
try:
result = client.Delete(topic_ref)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.DeletedResource(
topic_ref.RelativeName(),
kind='topic',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
failed.append(topic_ref.topicsId)
continue
topic = client.messages.Topic(name=topic_ref.RelativeName())
if legacy_output:
result = util.TopicDisplayDict(topic)
log.DeletedResource(topic_ref.RelativeName(), kind='topic')
yield result
if failed:
raise util.RequestsFailedError(failed, 'delete')
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Delete(base.DeleteCommand):
"""Deletes one or more Cloud Pub/Sub topics."""
detailed_help = {
'EXAMPLES':
"""\
To delete a Cloud Pub/Sub topic, run:
$ {command} mytopic"""
}
@staticmethod
def Args(parser):
resource_args.AddTopicResourceArg(parser, 'to delete.', plural=True)
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class DeleteBeta(Delete):
"""Deletes one or more Cloud Pub/Sub topics."""
def Run(self, args):
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, legacy_output=legacy_output)

View File

@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topic describe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
def _FormatRequiresDelimiterEscaping(output_format):
return (
output_format is None
or output_format.startswith('yaml')
or output_format.startswith('default')
)
@base.UniverseCompatible
class Describe(base.DescribeCommand):
"""Describes a Cloud Pub/Sub topic."""
@staticmethod
def Args(parser):
resource_args.AddTopicResourceArg(parser, 'to describe.')
def Run(self, args):
client = topics.TopicsClient()
topic_ref = args.CONCEPTS.topic.Parse()
topic_result = client.Get(topic_ref)
if (not _FormatRequiresDelimiterEscaping(args.format)):
return topic_result
# Ensure that the newline character is displayed correctly when used as the
# delimiter for ingestion from Cloud Storage.
ingestion_settings = topic_result.ingestionDataSourceSettings
if (
ingestion_settings
and ingestion_settings.cloudStorage
and ingestion_settings.cloudStorage.textFormat
and ingestion_settings.cloudStorage.textFormat.delimiter == '\n'
):
topic_result.ingestionDataSourceSettings.cloudStorage.textFormat.delimiter = (
'\\n'
)
return topic_result

View File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics detach-subscription command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as api_ex
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.api_lib.util import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import log
def _Run(args):
"""Detaches one or more subscriptions."""
client = topics.TopicsClient()
failed = []
for subscription_ref in args.CONCEPTS.subscription.Parse():
try:
result = client.DetachSubscription(subscription_ref)
except api_ex.HttpError as error:
exc = exceptions.HttpException(error)
log.DetachedResource(
subscription_ref.RelativeName(),
kind='subscription',
failed=util.CreateFailureErrorMessage(exc.payload.status_message),
)
failed.append(subscription_ref.subscriptionsId)
continue
subscription = client.messages.Subscription(
name=subscription_ref.RelativeName())
log.DetachedResource(subscription_ref.RelativeName(), kind='subscription')
yield result
if failed:
raise util.RequestsFailedError(failed, 'detach')
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class DetachSubscription(base.UpdateCommand):
"""Detaches one or more Cloud Pub/Sub subscriptions."""
detailed_help = {
'EXAMPLES':
"""\
To detach a Cloud Pub/Sub subscription, run:
$ {command} mysubscription"""
}
@staticmethod
def Args(parser):
resource_args.AddSubscriptionResourceArg(parser, 'to detach.', plural=True)
def Run(self, args):
return _Run(args)

View File

@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics get-iam-policy command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class GetIamPolicy(base.ListCommand):
"""Get the IAM policy for a Cloud Pub/Sub Topic."""
detailed_help = {
'DESCRIPTION':
'{description}',
'EXAMPLES':
"""\
To print the IAM policy for a given topic, run:
$ {command} my-topic
""",
}
@staticmethod
def Args(parser):
resource_args.AddTopicResourceArg(parser, 'to get the IAM policy of.')
base.URI_FLAG.RemoveFromParser(parser)
def Run(self, args):
client = topics.TopicsClient()
topic_ref = args.CONCEPTS.topic.Parse()
return client.GetIamPolicy(topic_ref)

View File

@@ -0,0 +1,23 @@
- release_tracks: [ALPHA]
help_text:
brief: Get the IAM policy for a topic.
description: |
*{command}* displays the IAM policy associated with a topic.
If formatted as JSON, the output can be edited and used as
a policy file for *set-iam-policy*. The output includes an "etag"
field identifying the version emitted and allowing detection of
concurrent policy updates; see
$ {parent} set-iam-policy for additional details.
examples: |
To print the IAM policy for a given topic, run:
$ {command} my-topic
request:
collection: pubsub.projects.topics
arguments:
resource:
help_text: The topic for which to display the IAM policy.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:topic

View File

@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import properties
def _Run(args, legacy_output=False):
client = topics.TopicsClient()
for topic in client.List(util.ParseProject(), page_size=args.page_size):
if legacy_output:
topic = util.ListTopicDisplayDict(topic)
yield topic
@base.ReleaseTracks(base.ReleaseTrack.GA)
class List(base.ListCommand):
"""Lists Cloud Pub/Sub topics within a project."""
detailed_help = {
'DESCRIPTION':
"""\
Lists all of the Cloud Pub/Sub topics that exist in a given project that
match the given topic name filter.""",
'EXAMPLES':
"""\
To filter results by topic name (ie. only show topic 'my-topic'), run:
$ {command} --filter="name.scope(topic):'my-topic'"
To combine multiple filters (with AND or OR), run:
$ {command} --filter="name.scope(topic):'my-topic' OR name.scope(topic):'my-other-topic'"
To filter topics that match an expression:
$ {command} --filter="name.scope(topic):'my-topic_*'"
""",
}
@staticmethod
def Args(parser):
parser.display_info.AddFormat('yaml')
parser.display_info.AddUriFunc(util.TopicUriFunc)
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class ListBeta(List):
"""Lists Cloud Pub/Sub topics within a project."""
def Run(self, args):
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, legacy_output=legacy_output)

View File

@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics list-snapshots command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListSnapshots(base.ListCommand):
"""Lists Cloud Pub/Sub snapshots from a given topic."""
detailed_help = {
'DESCRIPTION':
"""\
Lists all of the Cloud Pub/Sub snapshots attached to the given
topic and that match the given filter.""",
'EXAMPLES':
"""\
To filter results by snapshot name
(ie. only show snapshot 'mysnaps'), run:
$ {command} mytopic --filter=snapshotId:mysnaps
To combine multiple filters (with AND or OR), run:
$ {command} mytopic --filter="snapshotId:mysnaps1 AND snapshotId:mysnaps2"
To filter snapshots that match an expression:
$ {command} mytopic --filter="snapshotId:snaps_*"
""",
}
@staticmethod
def Args(parser):
parser.display_info.AddFormat('yaml')
parser.display_info.AddUriFunc(util.SnapshotUriFunc)
resource_args.AddTopicResourceArg(parser, 'to list snapshots for.')
def Run(self, args):
client = topics.TopicsClient()
topic_ref = args.CONCEPTS.topic.Parse()
return client.ListSnapshots(topic_ref, page_size=args.page_size)

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics list_subscriptions command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import properties
def _Run(args, legacy_output=False):
client = topics.TopicsClient()
topic_ref = args.CONCEPTS.topic.Parse()
for topic_sub in client.ListSubscriptions(
topic_ref, page_size=args.page_size):
if legacy_output:
topic_sub = util.ListTopicSubscriptionDisplayDict(topic_sub)
yield topic_sub
@base.ReleaseTracks(base.ReleaseTrack.GA)
class ListSubscriptions(base.ListCommand):
"""Lists Cloud Pub/Sub subscriptions from a given topic."""
detailed_help = {
'DESCRIPTION':
"""\
Lists all of the Cloud Pub/Sub subscriptions attached to the given
topic and that match the given filter.""",
'EXAMPLES':
"""\
To filter results by subscription name
(ie. only show subscription 'mysubs'), run:
$ {command} mytopic --filter=mysubs
To combine multiple filters (with AND or OR), run:
$ {command} mytopic --filter="mysubs1 OR mysubs2"
""",
}
@staticmethod
def Args(parser):
parser.display_info.AddFormat('yaml')
parser.display_info.AddUriFunc(util.SubscriptionUriFunc)
resource_args.AddTopicResourceArg(parser, 'to list subscriptions for.')
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class ListSubscriptionsBeta(ListSubscriptions):
"""Lists Cloud Pub/Sub subscriptions from a given topic."""
def Run(self, args):
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, legacy_output=legacy_output)

View File

@@ -0,0 +1,92 @@
# -*- coding: utf-8 -*- #
# Copyright 2015 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics publish command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.core import properties
from googlecloudsdk.core.resource import resource_projector
from googlecloudsdk.core.util import http_encoding
def _Run(args, message_body, legacy_output=False):
"""Publishes a message to a topic."""
client = topics.TopicsClient()
attributes = util.ParseAttributes(args.attribute, messages=client.messages)
ordering_key = getattr(args, 'ordering_key', None)
topic_ref = args.CONCEPTS.topic.Parse()
result = client.Publish(topic_ref, http_encoding.Encode(message_body),
attributes, ordering_key)
if legacy_output:
# We only allow to publish one message at a time, so do not return a
# list of messageId.
result = resource_projector.MakeSerializable(result)
result['messageIds'] = result['messageIds'][0]
return result
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Publish(base.Command):
"""Publishes a message to the specified topic."""
detailed_help = {
'DESCRIPTION':
"""\
Publishes a message to the specified topic name for testing and
troubleshooting. Use with caution: all associated subscribers must
be able to consume and acknowledge any message you publish,
otherwise the system will continuously re-attempt delivery of the
bad message for 7 days.""",
'EXAMPLES':
"""\
To publish messages in a batch to a specific Cloud Pub/Sub topic,
run:
$ {command} mytopic --message="Hello World!" --attribute=KEY1=VAL1,KEY2=VAL2
"""
}
@classmethod
def Args(cls, parser):
resource_args.AddTopicResourceArg(parser, 'to publish messages to.')
flags.AddPublishMessageFlags(parser)
def Run(self, args):
return _Run(args, args.message)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class PublishBeta(Publish):
"""Publishes a message to the specified topic."""
@classmethod
def Args(cls, parser):
resource_args.AddTopicResourceArg(parser, 'to publish messages to.')
flags.AddPublishMessageFlags(parser, add_deprecated=True)
def Run(self, args):
message_body = flags.ParseMessageBody(args)
legacy_output = properties.VALUES.pubsub.legacy_output.GetBool()
return _Run(args, message_body, legacy_output=legacy_output)

View File

@@ -0,0 +1,58 @@
release_tracks: [ALPHA, BETA, GA]
help_text:
brief: Remove IAM policy binding of a topic
description: |
Remove an IAM policy binding of a Cloud Pub/Sub Topic.
examples: |
To Remove an IAM policy binding for the role of 'roles/editor' for the user 'test-user@gmail.com'
with topic 'my-topic', run:
$ {command} my-topic --member='user:test-user@gmail.com' --role='roles/editor'
The following command will remove an IAM policy binding for the role of
'roles/editor' from all authenticated users on topic
'my-topic':
$ {command} my-topic --member='allAuthenticatedUsers' --role='roles/editor'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
request:
collection: pubsub.projects.topics
arguments:
resource:
help_text: The topic to remove the IAM policy binding from.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:topic
ALPHA:
help_text:
brief: Remove IAM policy binding of a topic.
description: |
Remove an IAM policy binding from the IAM policy of a Cloud Pub/Sub Topic. One binding consists of a member,
a role, and an optional condition.
examples: |
To remove an IAM policy binding for the role of 'roles/editor' for the user 'test-user@gmail.com'
with topic 'my-topic', run:
$ {command} my-topic --member='user:test-user@gmail.com' --role='roles/editor'
The following command will remove an IAM policy binding for the role of
'roles/editor' from all authenticated users on topic
'my-topic':
$ {command} my-topic --member='allAuthenticatedUsers' --role='roles/editor'
To remove an IAM policy binding which expires at the end of the year 2018 for the role of
'roles/pubsub.publisher' and the user 'test-user@gmail.com' with topic 'my-topic', run:
$ {command} my-topic --member='user:test-user@gmail.com' --role='roles/pubsub.publisher' --condition='expression=request.time < timestamp("2019-01-01T00:00:00Z"),title=expires_end_of_2018,description=Expires at midnight on 2018-12-31'
See https://cloud.google.com/iam/docs/managing-policies for details of
policy role and member types.
iam:
enable_condition: true

View File

@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics set-iam-policy command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.iam import iam_util
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.core import log
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class SetIamPolicy(base.Command):
"""Set the IAM policy for a Cloud Pub/Sub Topic."""
detailed_help = iam_util.GetDetailedHelpForSetIamPolicy('topic', 'my-topic')
@staticmethod
def Args(parser):
resource_args.AddTopicResourceArg(parser, 'to set an IAM policy on.')
flags.AddIamPolicyFileFlag(parser)
def Run(self, args):
client = topics.TopicsClient()
messages = client.messages
topic_ref = args.CONCEPTS.topic.Parse()
policy = iam_util.ParsePolicyFile(args.policy_file, messages.Policy)
response = client.SetIamPolicy(topic_ref, policy=policy)
log.status.Print('Updated IAM policy for topic [{}].'.format(
topic_ref.Name()))
return response

View File

@@ -0,0 +1,27 @@
- release_tracks: [ALPHA]
help_text:
brief: Set the IAM policy for a Cloud Pub/Sub Topic.
description: |
This command replaces the existing IAM policy for a topic, given a topic
and a file encoded in JSON or YAML that contains the IAM policy. If the
given policy file specifies an "etag" value, then the replacement will
succeed only if the policy already in place matches that etag. (An etag
obtained via `get-iam-policy` will prevent the replacement if the policy
for the topic has been subsequently updated.) A policy file that does not
contain an etag value will replace any existing policy for the topic.
examples: |
The following command will read an IAM policy defined in a JSON file
'policy.json' and set it for a topic with identifier 'my-topic'
$ {command} my-topic policy.json
See https://cloud.google.com/iam/docs/managing-policies for details of the
policy file format and contents.
request:
collection: pubsub.projects.topics
arguments:
resource:
help_text: The topic for which to set the IAM policy.
spec: !REF googlecloudsdk.command_lib.pubsub.resources:topic

View File

@@ -0,0 +1,385 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Cloud Pub/Sub topics update command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.pubsub import topics
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.kms import resource_args as kms_resource_args
from googlecloudsdk.command_lib.pubsub import flags
from googlecloudsdk.command_lib.pubsub import resource_args
from googlecloudsdk.command_lib.pubsub import util
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import exceptions as core_exceptions
from googlecloudsdk.core import log
DETAILED_HELP = {'EXAMPLES': """\
To update existing labels on a Cloud Pub/Sub topic, run:
$ {command} mytopic --update-labels=KEY1=VAL1,KEY2=VAL2
To clear all labels on a Cloud Pub/Sub topic, run:
$ {command} mytopic --clear-labels
To remove an existing label on a Cloud Pub/Sub topic, run:
$ {command} mytopic --remove-labels=KEY1,KEY2
To enable customer-managed encryption for a Cloud Pub/Sub topic by protecting message data with a Cloud KMS CryptoKey, run:
$ {command} mytopic --topic-encryption-key=projects/PROJECT_ID/locations/KMS_LOCATION/keyRings/KEYRING/cryptoKeys/KEY
To enable or update retention on a Cloud Pub/Sub topic, run:
$ {command} mytopic --message-retention-duration=MESSAGE_RETENTION_DURATION
To disable retention on a Cloud Pub/Sub topic, run:
$ {command} mytopic --clear-message-retention-duration
To update a Cloud Pub/Sub topic's message storage policy, run:
$ {command} mytopic --message-storage-policy-allowed-regions=some-cloud-region1,some-cloud-region2
To recompute a Cloud Pub/Sub topic's message storage policy based on your organization's "Resource Location Restriction" policy, run:
$ {command} mytopic --recompute-message-storage-policy
To enforce both at-rest and in-transit guarantees for messages published to the topic, run:
$ {command} mytopic --message-storage-policy-allowed-regions=some-cloud-region1,some-cloud-region2 --message-storage-policy-enforce-in-transit
"""}
_KMS_FLAG_OVERRIDES = {
'kms-key': '--topic-encryption-key',
'kms-keyring': '--topic-encryption-key-keyring',
'kms-location': '--topic-encryption-key-location',
'kms-project': '--topic-encryption-key-project',
}
_KMS_PERMISSION_INFO = """
The specified Cloud KMS key should have purpose set to "ENCRYPT_DECRYPT".
The service account,
"service-${CONSUMER_PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
requires the IAM cryptoKeyEncrypterDecrypter role for the given Cloud KMS key.
CONSUMER_PROJECT_NUMBER is the project number of the project that is the parent
of the topic being updated"""
def _GetKmsKeyNameFromArgs(args):
"""Parses the KMS key resource name from args.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
The KMS CryptoKey resource name for the key specified in args, or None.
"""
kms_ref = args.CONCEPTS.kms_key.Parse()
if kms_ref:
return kms_ref.RelativeName()
# Check whether the user specified any topic-encryption-key flags.
for keyword in [
'topic-encryption-key',
'topic-encryption-key-project',
'topic-encryption-key-location',
'topic-encryption-key-keyring',
]:
if args.IsSpecified(keyword.replace('-', '_')):
raise core_exceptions.Error(
'--topic-encryption-key was not fully specified.'
)
return None
def _Args(
parser,
):
"""Registers flags for this command."""
resource_args.AddTopicResourceArg(parser, 'to update.')
labels_util.AddUpdateLabelsFlags(parser)
resource_args.AddResourceArgs(
parser,
[
kms_resource_args.GetKmsKeyPresentationSpec(
'topic',
flag_overrides=_KMS_FLAG_OVERRIDES,
permission_info=_KMS_PERMISSION_INFO,
)
],
)
flags.AddTopicMessageRetentionFlags(parser, is_update=True)
flags.AddTopicMessageStoragePolicyFlags(parser, is_update=True)
flags.AddSchemaSettingsFlags(parser, is_update=True)
flags.AddIngestionDatasourceFlags(
parser,
is_update=True,
)
flags.AddMessageTransformsFlags(parser, is_update=True)
def _Run(args, /, *, enable_vertex_ai_smt=False):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
enable_vertex_ai_smt: Whether to enable Vertex AI SMTs.
Returns:
A serialized object (dict) describing the results of the operation.
Raises:
An HttpException if there was a problem calling the
API topics.Patch command.
"""
client = topics.TopicsClient()
topic_ref = args.CONCEPTS.topic.Parse()
message_retention_duration = getattr(args, 'message_retention_duration', None)
if message_retention_duration:
message_retention_duration = util.FormatDuration(message_retention_duration)
clear_message_retention_duration = getattr(
args, 'clear_message_retention_duration', None
)
labels_update = labels_util.ProcessUpdateArgsLazy(
args,
client.messages.Topic.LabelsValue,
orig_labels_thunk=lambda: client.Get(topic_ref).labels,
)
schema = getattr(args, 'schema', None)
if schema:
schema = args.CONCEPTS.schema.Parse().RelativeName()
message_encoding_list = getattr(args, 'message_encoding', None)
message_encoding = None
if message_encoding_list:
message_encoding = message_encoding_list[0]
first_revision_id = getattr(args, 'first_revision_id', None)
last_revision_id = getattr(args, 'last_revision_id', None)
result = None
clear_schema_settings = getattr(args, 'clear_schema_settings', None)
message_storage_policy_enforce_in_transit = getattr(
args, 'message_storage_policy_enforce_in_transit', None
)
kinesis_ingestion_stream_arn = getattr(
args, 'kinesis_ingestion_stream_arn', None
)
kinesis_ingestion_consumer_arn = getattr(
args, 'kinesis_ingestion_consumer_arn', None
)
kinesis_ingestion_role_arn = getattr(args, 'kinesis_ingestion_role_arn', None)
kinesis_ingestion_service_account = getattr(
args, 'kinesis_ingestion_service_account', None
)
cloud_storage_ingestion_bucket = getattr(
args, 'cloud_storage_ingestion_bucket', None
)
cloud_storage_ingestion_input_format_list = getattr(
args, 'cloud_storage_ingestion_input_format', None
)
cloud_storage_ingestion_input_format = None
if cloud_storage_ingestion_input_format_list:
cloud_storage_ingestion_input_format = (
cloud_storage_ingestion_input_format_list[0]
)
cloud_storage_ingestion_text_delimiter = getattr(
args, 'cloud_storage_ingestion_text_delimiter', None
)
if cloud_storage_ingestion_text_delimiter:
# Interprets special characters representations (i.e., "\n") as their
# expected characters (i.e., newline).
cloud_storage_ingestion_text_delimiter = (
cloud_storage_ingestion_text_delimiter.encode('utf-8').decode(
'unicode-escape'
)
)
cloud_storage_ingestion_minimum_object_create_time = getattr(
args, 'cloud_storage_ingestion_minimum_object_create_time', None
)
cloud_storage_ingestion_match_glob = getattr(
args, 'cloud_storage_ingestion_match_glob', None
)
azure_event_hubs_ingestion_resource_group = getattr(
args, 'azure_event_hubs_ingestion_resource_group', None
)
azure_event_hubs_ingestion_namespace = getattr(
args, 'azure_event_hubs_ingestion_namespace', None
)
azure_event_hubs_ingestion_event_hub = getattr(
args, 'azure_event_hubs_ingestion_event_hub', None
)
azure_event_hubs_ingestion_client_id = getattr(
args, 'azure_event_hubs_ingestion_client_id', None
)
azure_event_hubs_ingestion_tenant_id = getattr(
args, 'azure_event_hubs_ingestion_tenant_id', None
)
azure_event_hubs_ingestion_subscription_id = getattr(
args, 'azure_event_hubs_ingestion_subscription_id', None
)
azure_event_hubs_ingestion_service_account = getattr(
args, 'azure_event_hubs_ingestion_service_account', None
)
aws_msk_ingestion_cluster_arn = getattr(
args, 'aws_msk_ingestion_cluster_arn', None
)
aws_msk_ingestion_topic = getattr(args, 'aws_msk_ingestion_topic', None)
aws_msk_ingestion_aws_role_arn = getattr(
args, 'aws_msk_ingestion_aws_role_arn', None
)
aws_msk_ingestion_service_account = getattr(
args, 'aws_msk_ingestion_service_account', None
)
confluent_cloud_ingestion_bootstrap_server = getattr(
args, 'confluent_cloud_ingestion_bootstrap_server', None
)
confluent_cloud_ingestion_cluster_id = getattr(
args, 'confluent_cloud_ingestion_cluster_id', None
)
confluent_cloud_ingestion_topic = getattr(
args, 'confluent_cloud_ingestion_topic', None
)
confluent_cloud_ingestion_identity_pool_id = getattr(
args, 'confluent_cloud_ingestion_identity_pool_id', None
)
confluent_cloud_ingestion_service_account = getattr(
args, 'confluent_cloud_ingestion_service_account', None
)
ingestion_log_severity = getattr(args, 'ingestion_log_severity', None)
clear_ingestion_data_source_settings = getattr(
args, 'clear_ingestion_data_source_settings', None
)
message_transforms_file = getattr(args, 'message_transforms_file', None)
clear_message_transforms = getattr(args, 'clear_message_transforms', None)
try:
result = client.Patch(
topic_ref,
labels_update.GetOrNone(),
_GetKmsKeyNameFromArgs(args),
message_retention_duration,
clear_message_retention_duration,
args.recompute_message_storage_policy,
args.message_storage_policy_allowed_regions,
message_storage_policy_enforce_in_transit,
schema=schema,
message_encoding=message_encoding,
first_revision_id=first_revision_id,
last_revision_id=last_revision_id,
clear_schema_settings=clear_schema_settings,
kinesis_ingestion_stream_arn=kinesis_ingestion_stream_arn,
kinesis_ingestion_consumer_arn=kinesis_ingestion_consumer_arn,
kinesis_ingestion_role_arn=kinesis_ingestion_role_arn,
kinesis_ingestion_service_account=kinesis_ingestion_service_account,
cloud_storage_ingestion_bucket=cloud_storage_ingestion_bucket,
cloud_storage_ingestion_input_format=cloud_storage_ingestion_input_format,
cloud_storage_ingestion_text_delimiter=cloud_storage_ingestion_text_delimiter,
cloud_storage_ingestion_minimum_object_create_time=cloud_storage_ingestion_minimum_object_create_time,
cloud_storage_ingestion_match_glob=cloud_storage_ingestion_match_glob,
azure_event_hubs_ingestion_resource_group=azure_event_hubs_ingestion_resource_group,
azure_event_hubs_ingestion_namespace=azure_event_hubs_ingestion_namespace,
azure_event_hubs_ingestion_event_hub=azure_event_hubs_ingestion_event_hub,
azure_event_hubs_ingestion_client_id=azure_event_hubs_ingestion_client_id,
azure_event_hubs_ingestion_tenant_id=azure_event_hubs_ingestion_tenant_id,
azure_event_hubs_ingestion_subscription_id=azure_event_hubs_ingestion_subscription_id,
azure_event_hubs_ingestion_service_account=azure_event_hubs_ingestion_service_account,
aws_msk_ingestion_cluster_arn=aws_msk_ingestion_cluster_arn,
aws_msk_ingestion_topic=aws_msk_ingestion_topic,
aws_msk_ingestion_aws_role_arn=aws_msk_ingestion_aws_role_arn,
aws_msk_ingestion_service_account=aws_msk_ingestion_service_account,
confluent_cloud_ingestion_bootstrap_server=confluent_cloud_ingestion_bootstrap_server,
confluent_cloud_ingestion_cluster_id=confluent_cloud_ingestion_cluster_id,
confluent_cloud_ingestion_topic=confluent_cloud_ingestion_topic,
confluent_cloud_ingestion_identity_pool_id=confluent_cloud_ingestion_identity_pool_id,
confluent_cloud_ingestion_service_account=confluent_cloud_ingestion_service_account,
clear_ingestion_data_source_settings=clear_ingestion_data_source_settings,
ingestion_log_severity=ingestion_log_severity,
message_transforms_file=message_transforms_file,
clear_message_transforms=clear_message_transforms,
enable_vertex_ai_smt=enable_vertex_ai_smt,
)
except topics.NoFieldsSpecifiedError:
operations = [
'clear_labels',
'update_labels',
'remove_labels',
'recompute_message_storage_policy',
'message_storage_policy_allowed_regions',
]
if not any(args.IsSpecified(arg) for arg in operations):
raise
log.status.Print('No update to perform.')
else:
log.UpdatedResource(topic_ref.RelativeName(), kind='topic')
return result
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Updates an existing Cloud Pub/Sub topic."""
detailed_help = DETAILED_HELP
@staticmethod
def Args(parser):
"""Registers flags for this command."""
_Args(
parser,
)
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Updates an existing Cloud Pub/Sub topic."""
@staticmethod
def Args(parser):
_Args(
parser,
)
def Run(self, args):
return _Run(args)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Updates an existing Cloud Pub/Sub topic."""
@staticmethod
def Args(parser):
_Args(
parser,
)
def Run(self, args):
return _Run(args, enable_vertex_ai_smt=True)