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,51 @@
# -*- 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 command group for the DeploymentManager CLI."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.GA,
base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA)
class DmV2(base.Group):
"""Manage deployments of cloud resources.
The {command} command group lets you manage the deployment of Google Cloud
Platform resources using Google Cloud Deployment Manager.
Google Cloud Deployment Manager allows you to specify all the resources needed
for your application in a declarative format using YAML. You can also use
Python or Jinja2 templates to parameterize the configuration and allow reuse
of common deployment paradigms such as a load balanced, auto-scaled instance
group.
More information on Cloud Deployment Manager can be found here:
https://cloud.google.com/deployment-manager and detailed documentation can be
found here: https://cloud.google.com/deployment-manager/docs/
"""
category = base.MANAGEMENT_TOOLS_CATEGORY
def Filter(self, context, args):
# TODO(b/190530874): Determine if command group works with project number
base.RequireProjectID(args)
del context, args
base.DisableUserProjectQuota()

View File

@@ -0,0 +1,61 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""Deployment Manager deployments sub-group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Deployments(base.Group):
"""Commands for Deployment Manager deployments.
Commands to create, update, delete, and examine deployments of resources.
"""
detailed_help = {
'EXAMPLES': """\
To create a deployment, run:
$ {command} create my-deployment --config config.yaml
To update a deployment, run:
$ {command} update my-deployment --config new_config.yaml
To stop a deployment create or update in progress, run:
$ {command} stop my-deployment
To cancel a previewed create or update, run:
$ {command} cancel-preview my-deployment
To delete a deployment, run:
$ {command} delete my-deployment
To view the details of a deployment, run:
$ {command} describe my-deployment
To see the list of all deployments, run:
$ {command} list
""",
}

View File

@@ -0,0 +1,153 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""deployments cancel command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.deployment_manager import dm_util
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
# Number of seconds (approximately) to wait for cancel operation to complete.
OPERATION_TIMEOUT = 20 * 60 # 20 mins
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class CancelPreview(base.Command, dm_base.DmCommand):
"""Cancel a pending or running deployment preview.
This command will cancel a currently running or pending preview operation on
a deployment.
"""
detailed_help = {
'EXAMPLES': """
To cancel a running operation on a deployment, run:
$ {command} my-deployment
To issue a cancel preview command without waiting for the operation to complete, run:
$ {command} my-deployment --async
To cancel a preview command providing a fingerprint:
$ {command} my-deployment --fingerprint=deployment-fingerprint
When a deployment preview is cancelled, the deployment itself is not
deleted.
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
flags.AddDeploymentNameFlag(parser)
flags.AddAsyncFlag(parser)
flags.AddFingerprintFlag(parser)
def Run(self, args):
"""Run 'deployments cancel-preview'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
If --async=true, returns Operation to poll.
Else, returns boolean indicating whether cancel preview operation
succeeded.
Raises:
HttpException: An http error response was received while executing api
request.
"""
if args.fingerprint:
fingerprint = dm_util.DecodeFingerprint(args.fingerprint)
else:
# If no fingerprint is present, default to an empty fingerprint.
# TODO(b/34966984): Remove the empty default after cleaning up all
# deployments that has no fingerprint
fingerprint = dm_api_util.FetchDeploymentFingerprint(
self.client,
self.messages,
dm_base.GetProject(),
args.deployment_name,) or b''
try:
operation = self.client.deployments.CancelPreview(
self.messages.
DeploymentmanagerDeploymentsCancelPreviewRequest(
project=dm_base.GetProject(),
deployment=args.deployment_name,
deploymentsCancelPreviewRequest=
self.messages.DeploymentsCancelPreviewRequest(
fingerprint=fingerprint,
),
)
)
# Fetch and print the latest fingerprint of the deployment.
new_fingerprint = dm_api_util.FetchDeploymentFingerprint(
self.client,
self.messages,
dm_base.GetProject(),
args.deployment_name)
dm_util.PrintFingerprint(new_fingerprint)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
if args.async_:
return operation
else:
op_name = operation.name
try:
operation = dm_write.WaitForOperation(
self.client,
self.messages,
op_name,
'cancel-preview',
dm_base.GetProject(),
timeout=OPERATION_TIMEOUT)
dm_util.LogOperationStatus(operation, 'Cancel preview')
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
try:
# Fetch a list of the canceled resources.
response = self.client.resources.List(
self.messages.DeploymentmanagerResourcesListRequest(
project=dm_base.GetProject(),
deployment=args.deployment_name,
)
)
# TODO(b/36052523): Pagination
return response.resources if response.resources else []
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)

View File

@@ -0,0 +1,348 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""deployments create command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import exceptions as dm_exceptions
from googlecloudsdk.api_lib.util import apis
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.deployment_manager import alpha_flags
from googlecloudsdk.command_lib.deployment_manager import dm_util
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.command_lib.deployment_manager import importer
from googlecloudsdk.command_lib.util.apis import arg_utils
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
import six
# Number of seconds (approximately) to wait for create operation to complete.
OPERATION_TIMEOUT = 20 * 60 # 20 mins
@base.UnicodeIsSupported
@base.ReleaseTracks(base.ReleaseTrack.GA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Create(base.CreateCommand, dm_base.DmCommand):
"""Create a deployment.
This command inserts (creates) a new deployment based on a provided config
file.
"""
detailed_help = {
'EXAMPLES': """
To create a new deployment from a top-level YAML file, run:
$ {command} my-deployment --config=config.yaml --description="My deployment"
To create a new deployment from a top-level template file, run:
$ gcloud deployment-manager deployments create my-deployment \
--template=template.{jinja|py} \
--properties="string-key:'string-value',integer-key:12345"
To create a new deployment directly from a composite type, run:
$ gcloud deployment-manager deployments create my-deployment \
--composite-type=<project-id>/composite:<type-name> \
--properties="string-key:'string-value',integer-key:12345"
To preview a deployment without actually creating resources, run:
$ {command} my-new-deployment --config=config.yaml --preview
To instantiate a deployment that has been previewed, issue an update command for that deployment without specifying a config file.
More information is available at https://cloud.google.com/deployment-manager/docs/configuration/.
""",
}
_create_policy_flag_map = arg_utils.ChoiceEnumMapper(
'--create-policy',
(apis.GetMessagesModule('deploymentmanager', 'v2beta')
.DeploymentmanagerDeploymentsUpdateRequest.CreatePolicyValueValuesEnum),
help_str='Create policy for resources that have changed in the update',
default='create-or-acquire')
@staticmethod
def Args(parser, version=base.ReleaseTrack.GA):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
version: The version this tool is running as. base.ReleaseTrack.GA
is the default.
"""
group = parser.add_mutually_exclusive_group()
config_group = parser.add_mutually_exclusive_group(required=True)
flags.AddConfigFlags(config_group)
flags.AddAsyncFlag(group)
flags.AddDeploymentNameFlag(parser)
flags.AddPropertiesFlag(parser)
labels_util.AddCreateLabelsFlags(parser)
group.add_argument(
'--automatic-rollback-on-error',
help='If the create request results in a deployment with resource '
'errors, delete that deployment immediately after creation. '
'(default=False)',
dest='automatic_rollback',
default=False,
action='store_true')
parser.add_argument(
'--description',
help='Optional description of the deployment to insert.',
dest='description')
parser.add_argument(
'--preview',
help='Preview the requested create without actually instantiating the '
'underlying resources. (default=False)',
dest='preview',
default=False,
action='store_true')
parser.display_info.AddFormat(flags.RESOURCES_AND_OUTPUTS_FORMAT)
def Epilog(self, resources_were_displayed):
"""Called after resources are displayed if the default format was used.
Args:
resources_were_displayed: True if resources were displayed.
"""
if not resources_were_displayed:
log.status.Print('No resources or outputs found in your deployment.')
def Run(self, args):
"""Run 'deployments create'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
If --async=true, returns Operation to poll.
Else, returns a struct containing the list of resources and list of
outputs in the deployment.
Raises:
HttpException: An http error response was received while executing api
request.
ConfigError: Config file could not be read or parsed, or the
deployment creation operation encountered an error.
"""
deployment_ref = self.resources.Parse(
args.deployment_name,
params={'project': properties.VALUES.core.project.GetOrFail},
collection='deploymentmanager.deployments')
if (not args.IsSpecified('format')) and (args.async_):
args.format = flags.OPERATION_FORMAT
deployment = self.messages.Deployment(
name=deployment_ref.deployment,
target=importer.BuildTargetConfig(self.messages,
config=args.config,
template=args.template,
composite_type=args.composite_type,
properties=args.properties)
)
self._SetMetadata(args, deployment)
try:
operation = self.client.deployments.Insert(
self._BuildRequest(
args=args, project=dm_base.GetProject(), deployment=deployment))
# Fetch and print the latest fingerprint of the deployment.
fingerprint = dm_api_util.FetchDeploymentFingerprint(
self.client,
self.messages,
dm_base.GetProject(),
deployment_ref.deployment)
dm_util.PrintFingerprint(fingerprint)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
if args.async_:
return operation
else:
op_name = operation.name
try:
operation = dm_write.WaitForOperation(
self.client,
self.messages,
op_name,
operation_description='create',
project=dm_base.GetProject(),
timeout=OPERATION_TIMEOUT)
dm_util.LogOperationStatus(operation, 'Create')
except apitools_exceptions.HttpError as error:
# TODO(b/37911296): Use gcloud default error handling.
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
except dm_exceptions.OperationError as error:
response = self._HandleOperationError(error,
args,
operation,
dm_base.GetProject(),
deployment_ref)
if getattr(args, 'automatic_rollback', False):
args.format = flags.OPERATION_FORMAT
return response
return dm_api_util.FetchResourcesAndOutputs(self.client, self.messages,
dm_base.GetProject(),
deployment_ref.deployment)
def _BuildRequest(self,
args,
project,
deployment,
supports_create_policy=False):
request = self.messages.DeploymentmanagerDeploymentsInsertRequest(
project=project, deployment=deployment, preview=args.preview)
if supports_create_policy and args.create_policy:
parsed_create_flag = Create._create_policy_flag_map.GetEnumForChoice(
args.create_policy).name
request.createPolicy = (
self.messages.DeploymentmanagerDeploymentsInsertRequest.
CreatePolicyValueValuesEnum(parsed_create_flag))
return request
def _HandleOperationError(
self, error, args, operation, project, deployment_ref):
if args.automatic_rollback:
delete_operation = self._PerformRollback(deployment_ref.deployment,
six.text_type(error))
create_operation = dm_api_util.GetOperation(self.client, self.messages,
operation, project)
return [create_operation, delete_operation]
raise error
def _SetMetadata(self, args, deployment):
if args.description:
deployment.description = args.description
label_dict = labels_util.GetUpdateLabelsDictFromArgs(args)
if label_dict:
deployment.labels = [
self.messages.DeploymentLabelEntry(key=k, value=v)
for k, v in sorted(six.iteritems(label_dict))
]
def _PerformRollback(self, deployment_name, error_message):
# Print information about the failure.
log.warning('There was an error deploying '
+ deployment_name + ':\n' + error_message)
log.status.Print('`--automatic-rollback-on-error` flag was supplied; '
'deleting failed deployment...')
# Delete the deployment.
try:
delete_operation = self.client.deployments.Delete(
self.messages.DeploymentmanagerDeploymentsDeleteRequest(
project=dm_base.GetProject(),
deployment=deployment_name,
)
)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
# TODO(b/37481635): Use gcloud default operation polling.
dm_write.WaitForOperation(self.client,
self.messages,
delete_operation.name,
'delete',
dm_base.GetProject(),
timeout=OPERATION_TIMEOUT)
completed_operation = dm_api_util.GetOperation(self.client,
self.messages,
delete_operation,
dm_base.GetProject())
return completed_operation
@base.UnicodeIsSupported
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.ALPHA)
class CreateAlpha(Create):
"""Create a deployment.
This command inserts (creates) a new deployment based on a provided config
file.
"""
@staticmethod
def Args(parser):
Create.Args(parser, version=base.ReleaseTrack.ALPHA)
alpha_flags.AddCredentialFlag(parser)
parser.display_info.AddFormat(alpha_flags.RESOURCES_AND_OUTPUTS_FORMAT)
Create._create_policy_flag_map.choice_arg.AddToParser(parser)
def _SetMetadata(self, args, deployment):
if args.credential:
deployment.credential = dm_util.CredentialFrom(self.messages,
args.credential)
super(CreateAlpha, self)._SetMetadata(args, deployment)
def _BuildRequest(self, args, project, deployment):
return super(CreateAlpha, self)._BuildRequest(
args=args,
project=project,
deployment=deployment,
supports_create_policy=True)
@base.UnicodeIsSupported
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class CreateBeta(Create):
"""Create a deployment.
This command inserts (creates) a new deployment based on a provided config
file.
"""
@staticmethod
def Args(parser):
Create.Args(parser, version=base.ReleaseTrack.BETA)
Create._create_policy_flag_map.choice_arg.AddToParser(parser)
def _BuildRequest(self, args, project, deployment):
return super(CreateBeta, self)._BuildRequest(
args=args,
project=project,
deployment=deployment,
supports_create_policy=True)

View File

@@ -0,0 +1,153 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""deployments delete command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import exceptions
from googlecloudsdk.api_lib.util import apis
from googlecloudsdk.api_lib.util import exceptions as api_exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import dm_util
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.core import exceptions as core_exceptions
from googlecloudsdk.core import properties
from googlecloudsdk.core.console import console_io
# Number of seconds (approximately) to wait for each delete operation to
# complete.
OPERATION_TIMEOUT = 20 * 60 # 20 mins
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Delete(base.DeleteCommand, dm_base.DmCommand):
"""Delete a deployment.
This command deletes a deployment and deletes all associated resources.
"""
detailed_help = {
'EXAMPLES': """
To delete a deployment, run:
$ {command} my-deployment
To issue a delete command without waiting for the operation to complete, run:
$ {command} my-deployment --async
To delete several deployments, run:
$ {command} my-deployment-one my-deployment-two my-deployment-three
To disable the confirmation prompt on delete, run:
$ {command} my-deployment -q
""",
}
_delete_policy_flag_map = flags.GetDeleteFlagEnumMap(
(apis.GetMessagesModule('deploymentmanager', 'v2')
.DeploymentmanagerDeploymentsDeleteRequest.DeletePolicyValueValuesEnum))
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
parser.add_argument('deployment_name', nargs='+', help='Deployment name.')
Delete._delete_policy_flag_map.choice_arg.AddToParser(parser)
flags.AddAsyncFlag(parser)
def Run(self, args):
"""Run 'deployments delete'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
If --async=true, returns Operation to poll.
Else, returns boolean indicating whether insert operation succeeded.
Raises:
HttpException: An http error response was received while executing api
request.
"""
prompt_message = ('The following deployments will be deleted:\n- '
+ '\n- '.join(args.deployment_name))
if not args.quiet:
if not console_io.PromptContinue(message=prompt_message, default=False):
raise exceptions.OperationError('Deletion aborted by user.')
operations = []
errors = []
for deployment_name in args.deployment_name:
deployment_ref = self.resources.Parse(
deployment_name,
params={'project': properties.VALUES.core.project.GetOrFail},
collection='deploymentmanager.deployments')
try:
operation = self.client.deployments.Delete(
self.messages.DeploymentmanagerDeploymentsDeleteRequest(
project=dm_base.GetProject(),
deployment=deployment_ref.deployment,
deletePolicy=(Delete._delete_policy_flag_map.
GetEnumForChoice(args.delete_policy)),
)
)
if args.async_:
operations.append(operation)
else:
op_name = operation.name
try:
# TODO(b/62720778): Refactor to use waiter.CloudOperationPoller
operation = dm_write.WaitForOperation(
self.client,
self.messages,
op_name,
'delete',
dm_base.GetProject(),
timeout=OPERATION_TIMEOUT)
dm_util.LogOperationStatus(operation, 'Delete')
except exceptions.OperationError as e:
errors.append(exceptions.OperationError(
'Delete operation {0} failed.\n{1}'.format(op_name, e)))
completed_operation = self.client.operations.Get(
self.messages.DeploymentmanagerOperationsGetRequest(
project=dm_base.GetProject(),
operation=op_name,
)
)
operations.append(completed_operation)
except apitools_exceptions.HttpError as error:
errors.append(api_exceptions.HttpException(
error, dm_api_util.HTTP_ERROR_FORMAT))
if errors:
raise core_exceptions.MultiError(errors)
return operations

View File

@@ -0,0 +1,170 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""deployments describe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.deployment_manager import alpha_flags
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.core import properties
class _Results(object):
"""Encapsulate results into a single object to fit the Run() model."""
def __init__(self, deployment, resources, outputs):
self.deployment = deployment
self.resources = resources
self.outputs = outputs
@base.ReleaseTracks(base.ReleaseTrack.GA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Describe(base.DescribeCommand, dm_base.DmCommand):
"""Provide information about a deployment.
This command prints out all available details about a deployment.
"""
detailed_help = {
'EXAMPLES': """\
To display information about a deployment, run:
$ {command} my-deployment
""",
}
@staticmethod
def Args(parser, version=base.ReleaseTrack.GA):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
version: The version this tool is running as. base.ReleaseTrack.GA
is the default.
"""
flags.AddDeploymentNameFlag(parser)
parser.display_info.AddFormat("""
table(
deployment:format='default(name, id, description, fingerprint,
insertTime, manifest.basename(), labels, operation.operationType,
operation.name, operation.progress, operation.status,
operation.user, operation.endTime, operation.startTime,
operation.error, operation.warnings, update)',
resources:format='table(
name:label=NAME,
type:wrap:label=TYPE,
update.state.yesno(no="COMPLETED"),
update.intent)',
outputs:format='table(
name:label=OUTPUTS,
finalValue:label=VALUE)'
)
""")
def Run(self, args):
"""Run 'deployments describe'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The requested Deployment.
Raises:
HttpException: An http error response was received while executing api
request.
"""
deployment_ref = self.resources.Parse(
args.deployment_name,
params={'project': properties.VALUES.core.project.GetOrFail},
collection='deploymentmanager.deployments')
try:
deployment = self.client.deployments.Get(
self.messages.DeploymentmanagerDeploymentsGetRequest(
project=dm_base.GetProject(),
deployment=deployment_ref.deployment))
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
try:
response = self.client.resources.List(
self.messages.DeploymentmanagerResourcesListRequest(
project=dm_base.GetProject(), deployment=deployment.name))
resources = response.resources
if self.ReleaseTrack() is base.ReleaseTrack.ALPHA:
if (not args.IsSpecified('format')) and (deployment.update):
args.format = (
alpha_flags.PREVIEWED_DEPLOYMENT_AND_RESOURCES_AND_OUTPUTS_FORMAT)
except apitools_exceptions.HttpError:
# Couldn't get resources, skip adding them to the table.
resources = None
outputs = []
manifest = dm_api_util.ExtractManifestName(deployment)
if manifest:
manifest_response = self.client.manifests.Get(
self.messages.DeploymentmanagerManifestsGetRequest(
project=dm_base.GetProject(),
deployment=deployment_ref.deployment,
manifest=manifest,
)
)
# We might be lacking a layout if the manifest failed expansion.
if manifest_response.layout:
outputs = dm_api_util.FlattenLayoutOutputs(manifest_response.layout)
return _Results(deployment, resources, outputs)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.ALPHA)
class DescribeAlpha(Describe):
"""Provide information about a deployment.
This command prints out all available details about a deployment.
"""
@staticmethod
def Args(parser):
Describe.Args(parser, version=base.ReleaseTrack.ALPHA)
parser.display_info.AddFormat(
alpha_flags.DEPLOYMENT_AND_RESOURCES_AND_OUTPUTS_FORMAT)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DescribeBeta(Describe):
"""Provide information about a deployment.
This command prints out all available details about a deployment.
"""
@staticmethod
def Args(parser):
Describe.Args(parser, version=base.ReleaseTrack.BETA)

View File

@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""deployments list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import list_pager
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class List(base.ListCommand, dm_base.DmCommand):
"""List deployments in a project.
Prints a table with summary information on all deployments in the project.
"""
detailed_help = {
'EXAMPLES': """\
To print out a list of deployments with some summary information about each, run:
$ {command}
To print only the name of each deployment, run:
$ {command} --simple-list
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
dm_api_util.SIMPLE_LIST_FLAG.AddToParser(parser)
parser.display_info.AddFormat("""
table(
name,
operation.operationType:label=LAST_OPERATION_TYPE,
operation.status,
description,
manifest.basename(),
operation.error.errors.group(code)
)
""")
def Run(self, args):
"""Run 'deployments list'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The list of deployments for this project.
Raises:
HttpException: An http error response was received while executing api
request.
"""
request = self.messages.DeploymentmanagerDeploymentsListRequest(
project=dm_base.GetProject(),
)
return dm_api_util.YieldWithHttpExceptions(list_pager.YieldFromList(
self.client.deployments, request, field='deployments',
limit=args.limit, batch_size=args.page_size))

View File

@@ -0,0 +1,138 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""deployments stop command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.deployment_manager import dm_util
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
# Number of seconds (approximately) to wait for stop operation to complete.
OPERATION_TIMEOUT = 20 * 60 # 20 mins
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Stop(base.Command, dm_base.DmCommand):
"""Stop a pending or running deployment update or creation.
This command will stop a currently running or pending operation on
a deployment.
"""
detailed_help = {
'EXAMPLES': """
To stop a running operation on a deployment, run:
$ {command} my-deployment
To issue a stop command without waiting for the operation to complete, run:
$ {command} my-deployment --async
To stop a running operation on a deployment providing a fingerprint, run:
$ {command} my-deployment --fingerprint=deployment-fingerprint
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
flags.AddAsyncFlag(parser)
flags.AddDeploymentNameFlag(parser)
flags.AddFingerprintFlag(parser)
def Run(self, args):
"""Run 'deployments stop'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
If --async=true, returns Operation to poll.
Else, returns boolean indicating whether stop operation succeeded.
Raises:
HttpException: An http error response was received while executing api
request.
"""
if args.fingerprint:
fingerprint = dm_util.DecodeFingerprint(args.fingerprint)
else:
# If no fingerprint is present, default to an empty fingerprint.
# TODO(b/34966984): Remove the empty default after cleaning up all
# deployments that has no fingerprint
fingerprint = dm_api_util.FetchDeploymentFingerprint(
self.client,
self.messages,
dm_base.GetProject(),
args.deployment_name) or b''
try:
operation = self.client.deployments.Stop(
self.messages.DeploymentmanagerDeploymentsStopRequest(
project=dm_base.GetProject(),
deployment=args.deployment_name,
deploymentsStopRequest=(
self.messages.DeploymentsStopRequest(
fingerprint=fingerprint)
),
)
)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
if args.async_:
return operation
else:
op_name = operation.name
try:
operation = dm_write.WaitForOperation(
self.client,
self.messages,
op_name,
'stop',
dm_base.GetProject(),
timeout=OPERATION_TIMEOUT)
dm_util.LogOperationStatus(operation, 'Stop')
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
try:
# Fetch a list of the stopped resources.
response = self.client.resources.List(
self.messages.DeploymentmanagerResourcesListRequest(
project=dm_base.GetProject(),
deployment=args.deployment_name,
)
)
# TODO(b/36055861): Pagination
return response.resources if response.resources else []
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)

View File

@@ -0,0 +1,362 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""deployments update command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import dm_labels
from googlecloudsdk.api_lib.util import apis
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.deployment_manager import alpha_flags
from googlecloudsdk.command_lib.deployment_manager import dm_util
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.command_lib.deployment_manager import importer
from googlecloudsdk.command_lib.util.apis import arg_utils
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
import six
# Number of seconds (approximately) to wait for update operation to complete.
OPERATION_TIMEOUT = 20 * 60 # 20 mins
@base.UnicodeIsSupported
@base.ReleaseTracks(base.ReleaseTrack.GA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Update(base.UpdateCommand, dm_base.DmCommand):
"""Update a deployment based on a provided config file.
This command will update a deployment with the new config file provided.
Different policies for create, update, and delete policies can be specified.
"""
detailed_help = {
'EXAMPLES': """
To update an existing deployment with a new config YAML file, run:
$ {command} my-deployment --config=new_config.yaml
To update an existing deployment with a new config template file, run:
$ {command} my-deployment --template=new_config.{jinja|py}
To update an existing deployment with a composite type as a new config, run:
$ {command} my-deployment --composite-type=<project-id>/composite:<new-config>
To preview an update to an existing deployment without actually modifying the resources, run:
$ {command} my-deployment --config=new_config.yaml --preview
To apply an update that has been previewed, provide the name of the previewed deployment, and no config file:
$ {command} my-deployment
To specify different create, update, or delete policies, include any subset of the following flags:
$ {command} my-deployment --config=new_config.yaml --create-policy=acquire --delete-policy=abandon
To perform an update without waiting for the operation to complete, run:
$ {command} my-deployment --config=new_config.yaml --async
To update an existing deployment with a new config file and a fingerprint, run:
$ {command} my-deployment --config=new_config.yaml --fingerprint=deployment-fingerprint
Either the `--config`, `--template`, or `--composite-type` flag is required unless launching an already-previewed update to a deployment. If you want to update a deployment's metadata, such as the labels or description, you must run a separate command with `--update-labels`, `--remove-labels`, or `--description`, as applicable.
More information is available at https://cloud.google.com/deployment-manager/docs/deployments/updating-deployments.
""",
}
_delete_policy_flag_map = flags.GetDeleteFlagEnumMap(
(apis.GetMessagesModule('deploymentmanager', 'v2')
.DeploymentmanagerDeploymentsUpdateRequest.DeletePolicyValueValuesEnum))
_create_policy_flag_map = arg_utils.ChoiceEnumMapper(
'--create-policy',
(apis.GetMessagesModule('deploymentmanager', 'v2')
.DeploymentmanagerDeploymentsUpdateRequest.CreatePolicyValueValuesEnum),
help_str='Create policy for resources that have changed in the update',
default='create-or-acquire')
_create_policy_v2beta_flag_map = arg_utils.ChoiceEnumMapper(
'--create-policy',
(apis.GetMessagesModule('deploymentmanager', 'v2beta')
.DeploymentmanagerDeploymentsUpdateRequest.CreatePolicyValueValuesEnum),
help_str='Create policy for resources that have changed in the update',
default='create-or-acquire')
@staticmethod
def Args(parser, version=base.ReleaseTrack.GA):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
version: The version this tool is running as. base.ReleaseTrack.GA
is the default.
"""
flags.AddDeploymentNameFlag(parser)
flags.AddPropertiesFlag(parser)
flags.AddAsyncFlag(parser)
parser.add_argument(
'--description',
help='The new description of the deployment.',
dest='description'
)
group = parser.add_mutually_exclusive_group()
flags.AddConfigFlags(group)
if version in [base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA]:
group.add_argument(
'--manifest-id',
help='Manifest Id of a previous deployment. '
'This flag cannot be used with --config.',
dest='manifest_id')
labels_util.AddUpdateLabelsFlags(parser, enable_clear=False)
parser.add_argument(
'--preview',
help='Preview the requested update without making any changes to the '
'underlying resources. (default=False)',
dest='preview',
default=False,
action='store_true')
if version in [base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA]:
Update._create_policy_v2beta_flag_map.choice_arg.AddToParser(parser)
else:
Update._create_policy_flag_map.choice_arg.AddToParser(parser)
Update._delete_policy_flag_map.choice_arg.AddToParser(parser)
flags.AddFingerprintFlag(parser)
parser.display_info.AddFormat(flags.RESOURCES_AND_OUTPUTS_FORMAT)
def Epilog(self, resources_were_displayed):
"""Called after resources are displayed if the default format was used.
Args:
resources_were_displayed: True if resources were displayed.
"""
if not resources_were_displayed:
log.status.Print('No resources or outputs found in your deployment.')
def Run(self, args):
"""Run 'deployments update'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
If --async=true, returns Operation to poll.
Else, returns a struct containing the list of resources and list of
outputs in the deployment.
Raises:
HttpException: An http error response was received while executing api
request.
"""
deployment_ref = self.resources.Parse(
args.deployment_name,
params={'project': properties.VALUES.core.project.GetOrFail},
collection='deploymentmanager.deployments')
if not args.IsSpecified('format') and args.async_:
args.format = flags.OPERATION_FORMAT
patch_request = False
deployment = self.messages.Deployment(
name=deployment_ref.deployment,
)
if not (args.config is None and args.template is None
and args.composite_type is None):
deployment.target = importer.BuildTargetConfig(
self.messages,
config=args.config,
template=args.template,
composite_type=args.composite_type,
properties=args.properties)
elif (self.ReleaseTrack() in [base.ReleaseTrack.ALPHA,
base.ReleaseTrack.BETA]
and args.manifest_id):
deployment.target = importer.BuildTargetConfigFromManifest(
self.client, self.messages,
dm_base.GetProject(),
deployment_ref.deployment, args.manifest_id, args.properties)
# Get the fingerprint from the deployment to update.
try:
current_deployment = self.client.deployments.Get(
self.messages.DeploymentmanagerDeploymentsGetRequest(
project=dm_base.GetProject(),
deployment=deployment_ref.deployment
)
)
if args.fingerprint:
deployment.fingerprint = dm_util.DecodeFingerprint(args.fingerprint)
else:
# If no fingerprint is present, default to an empty fingerprint.
# TODO(b/34966984): Remove the empty default after cleaning up all
# deployments that has no fingerprint
deployment.fingerprint = current_deployment.fingerprint or b''
# Get the credential from the deployment to update.
if self.ReleaseTrack() in [base.ReleaseTrack.ALPHA] and args.credential:
deployment.credential = dm_util.CredentialFrom(self.messages,
args.credential)
# Update the labels of the deployment
deployment.labels = self._GetUpdatedDeploymentLabels(
args, current_deployment)
# If no config or manifest_id are specified, but try to update labels,
# only add patch_request header when directly updating a non-previewed
# deployment
no_manifest = (self.ReleaseTrack() is
base.ReleaseTrack.GA) or not args.manifest_id
patch_request = not args.config and no_manifest and (
bool(args.update_labels) or bool(args.remove_labels))
if args.description is None:
deployment.description = current_deployment.description
elif not args.description or args.description.isspace():
deployment.description = None
else:
deployment.description = args.description
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
if patch_request:
args.format = flags.DEPLOYMENT_FORMAT
try:
# Necessary to handle API Version abstraction below
parsed_delete_flag = Update._delete_policy_flag_map.GetEnumForChoice(
args.delete_policy).name
if self.ReleaseTrack() in [
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA
]:
parsed_create_flag = (
Update._create_policy_v2beta_flag_map.GetEnumForChoice(
args.create_policy).name)
else:
parsed_create_flag = (
Update._create_policy_flag_map.GetEnumForChoice(
args.create_policy).name)
request = self.messages.DeploymentmanagerDeploymentsUpdateRequest(
deploymentResource=deployment,
project=dm_base.GetProject(),
deployment=deployment_ref.deployment,
preview=args.preview,
createPolicy=(self.messages.DeploymentmanagerDeploymentsUpdateRequest.
CreatePolicyValueValuesEnum(parsed_create_flag)),
deletePolicy=(self.messages.DeploymentmanagerDeploymentsUpdateRequest.
DeletePolicyValueValuesEnum(parsed_delete_flag)))
client = self.client
client.additional_http_headers['X-Cloud-DM-Patch'] = six.text_type(
patch_request)
operation = client.deployments.Update(request)
# Fetch and print the latest fingerprint of the deployment.
updated_deployment = dm_api_util.FetchDeployment(
self.client, self.messages, dm_base.GetProject(),
deployment_ref.deployment)
if patch_request:
if args.async_:
log.warning(
'Updating Deployment metadata is synchronous, --async flag '
'is ignored.')
log.status.Print('Update deployment metadata completed successfully.')
return updated_deployment
dm_util.PrintFingerprint(updated_deployment.fingerprint)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
if args.async_:
return operation
else:
op_name = operation.name
try:
operation = dm_write.WaitForOperation(
self.client,
self.messages,
op_name,
'update',
dm_base.GetProject(),
timeout=OPERATION_TIMEOUT)
dm_util.LogOperationStatus(operation, 'Update')
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)
return dm_api_util.FetchResourcesAndOutputs(self.client, self.messages,
dm_base.GetProject(),
deployment_ref.deployment)
def _GetUpdatedDeploymentLabels(self, args, deployment):
update_labels = labels_util.GetUpdateLabelsDictFromArgs(args)
remove_labels = labels_util.GetRemoveLabelsListFromArgs(args)
return dm_labels.UpdateLabels(deployment.labels,
self.messages.DeploymentLabelEntry,
update_labels, remove_labels)
@base.UnicodeIsSupported
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.ALPHA)
class UpdateAlpha(Update):
"""Update a deployment based on a provided config file.
This command will update a deployment with the new config file provided.
Different policies for create, update, and delete policies can be specified.
"""
@staticmethod
def Args(parser):
Update.Args(parser, version=base.ReleaseTrack.ALPHA)
alpha_flags.AddCredentialFlag(parser)
parser.display_info.AddFormat(alpha_flags.RESOURCES_AND_OUTPUTS_FORMAT)
@base.UnicodeIsSupported
@base.ReleaseTracks(base.ReleaseTrack.BETA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class UpdateBeta(Update):
"""Update a deployment based on a provided config file.
This command will update a deployment with the new config file provided.
Different policies for create, update, and delete policies can be specified.
"""
@staticmethod
def Args(parser):
Update.Args(parser, version=base.ReleaseTrack.BETA)

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""Deployment Manager manifests sub-group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
class Manifests(base.Group):
"""Commands for Deployment Manager manifests.
Commands to list and examine manifests within a deployment.
"""
detailed_help = {
'EXAMPLES': """\
To view all details about a manifest, run:
$ {command} describe manifest-name --deployment my-deployment
To see the list of all manifests in a deployment, run:
$ {command} list --deployment my-deployment
""",
}

View File

@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""manifests describe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import exceptions as dm_exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Describe(base.DescribeCommand, dm_base.DmCommand):
"""Provide information about a manifest.
This command prints out all available details about a manifest.
"""
detailed_help = {
'EXAMPLES': """
To display information about a manifest, run:
$ {command} --deployment=my-deployment manifest-name
To display information about the latest manifest, run:
$ {command} --deployment=my-deployment
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
parser.add_argument('--deployment', help='Deployment name.', required=True)
parser.add_argument('manifest', nargs='?', help='Manifest name.')
def Run(self, args):
"""Run 'manifests describe'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The requested manifest.
Raises:
HttpException: An http error response was received while executing api
request.
"""
manifest = args.manifest
if not manifest:
try:
deployment = self.client.deployments.Get(
self.messages.DeploymentmanagerDeploymentsGetRequest(
project=dm_base.GetProject(),
deployment=args.deployment
)
)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error)
manifest = dm_api_util.ExtractManifestName(deployment)
if not manifest:
raise dm_exceptions.ManifestError(
'The deployment [%s] does not have a current manifest. '
'Please specify the manifest name.' % args.deployment)
try:
return self.client.manifests.Get(
self.messages.DeploymentmanagerManifestsGetRequest(
project=dm_base.GetProject(),
deployment=args.deployment,
manifest=manifest,
)
)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)

View File

@@ -0,0 +1,81 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""manifests list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import list_pager
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class List(base.ListCommand, dm_base.DmCommand):
"""List manifests in a deployment.
Prints a table with summary information on all manifests in the deployment.
"""
detailed_help = {
'EXAMPLES': """
To print out a list of manifests in a deployment, run:
$ {command} --deployment=my-deployment
To print only the name of each manifest, run:
$ {command} --deployment=my-deployment --simple-list
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
parser.add_argument('--deployment', help='Deployment name.', required=True)
dm_api_util.SIMPLE_LIST_FLAG.AddToParser(parser)
parser.display_info.AddFormat('table(name, id, insertTime)')
def Run(self, args):
"""Run 'manifests list'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The list of manifests for the specified deployment.
Raises:
HttpException: An http error response was received while executing api
request.
"""
request = self.messages.DeploymentmanagerManifestsListRequest(
project=dm_base.GetProject(),
deployment=args.deployment,
)
return dm_api_util.YieldWithHttpExceptions(list_pager.YieldFromList(
self.client.manifests, request, field='manifests',
limit=args.limit, batch_size=args.page_size))

View File

@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""Deployment Manager operations sub-group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Operations(base.Group):
"""Commands for Deployment Manager operations.
Commands to list, examine, and wait for long-running operations.
"""
detailed_help = {
'EXAMPLES': """\
To view the details of an operation, run:
$ {command} describe operation-name
To see the list of all operations, run:
$ {command} list
To wait for an operation to complete, run:
$ {command} wait operation-name
""",
}

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""operations describe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Describe(base.DescribeCommand, dm_base.DmCommand):
"""Provide information about an operation.
This command prints out all available details about an operation.
"""
detailed_help = {
'EXAMPLES': """\
To display information about an operation, run:
$ {command} operation-name
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
parser.add_argument('operation_name', help='Operation name.')
def Run(self, args):
"""Run 'operations describe'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The requested operation.
Raises:
HttpException: An http error response was received while executing api
request.
"""
try:
return self.client.operations.Get(
self.messages.DeploymentmanagerOperationsGetRequest(
project=dm_base.GetProject(),
operation=args.operation_name,
)
)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)

View File

@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""operations list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import list_pager
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import flags
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class List(base.ListCommand, dm_base.DmCommand):
"""List operations in a project.
Prints a table with summary information on all operations in the project.
"""
detailed_help = {
'EXAMPLES': """\
To print out a list of operations with some summary information about each, run:
$ {command}
To print only the name of each operation, run:
$ {command} --simple-list
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
dm_api_util.SIMPLE_LIST_FLAG.AddToParser(parser)
parser.display_info.AddFormat(flags.OPERATION_FORMAT)
def Run(self, args):
"""Run 'operations list'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The list of operations for this project.
Raises:
HttpException: An http error response was received while executing api
request.
"""
request = self.messages.DeploymentmanagerOperationsListRequest(
project=dm_base.GetProject(),
)
return dm_api_util.YieldWithHttpExceptions(list_pager.YieldFromList(
self.client.operations, request, field='operations',
limit=args.limit, batch_size=args.page_size))

View File

@@ -0,0 +1,94 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""operations wait command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.core import log
# Number of seconds (approximately) to wait for each operation to complete.
OPERATION_TIMEOUT = 120 * 60 # 2 hr
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Wait(base.Command, dm_base.DmCommand):
"""Wait for all operations specified to complete before returning.
Polls until all operations have finished, then prints the resulting operations
along with any operation errors.
"""
detailed_help = {
'EXAMPLES': """\
To poll until an operation has completed, run:
$ {command} operation-name
To poll until several operations have all completed, run:
$ {command} operation-one operation-two operation-three
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
parser.add_argument('operation_name', nargs='+', help='Operation name.')
def Run(self, args):
"""Run 'operations wait'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Raises:
HttpException: An http error response was received while executing api
request.
Raises:
OperationError: Operation finished with error(s) or timed out.
"""
failed_ops = []
for operation_name in args.operation_name:
try:
dm_write.WaitForOperation(self.client,
self.messages,
operation_name, '', dm_base.GetProject(),
timeout=OPERATION_TIMEOUT)
except exceptions.OperationError:
failed_ops.append(operation_name)
if failed_ops:
if len(failed_ops) == 1:
raise exceptions.OperationError(
'Operation %s failed to complete or has errors.' % failed_ops[0])
else:
raise exceptions.OperationError(
'Some operations failed to complete without errors:\n'
+ '\n'.join(failed_ops))
else:
log.status.Print('All operations completed successfully.')

View File

@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""Deployment Manager resources sub-group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import exceptions
from googlecloudsdk.calliope import base
class Resources(base.Group):
"""Commands for Deployment Manager resources.
Commands to list and examine resources within a deployment.
"""
detailed_help = {
'EXAMPLES': """\
To view all details about a resource, run:
$ {command} describe my-resource --deployment my-deployment
To see the list of all resources in a deployment, run:
$ {command} list --deployment my-deployment
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
parser.add_argument('--deployment', help='Deployment name')
def Filter(self, unused_tool_context, args):
if not args.deployment:
raise exceptions.ArgumentError('argument --deployment is required')

View File

@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""resources describe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import exceptions as apitools_exceptions
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class Describe(base.DescribeCommand, dm_base.DmCommand):
"""Provide information about a resource.
This command prints out all available details about a resource.
"""
detailed_help = {
'EXAMPLES': """
To display information about a resource, run:
$ {command} --deployment=my-deployment my-resource-name
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
parser.add_argument('resource', help='Resource name.')
def Run(self, args):
"""Run 'resources describe'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The requested resource.
Raises:
HttpException: An http error response was received while executing api
request.
"""
try:
return self.client.resources.Get(
self.messages.DeploymentmanagerResourcesGetRequest(
project=dm_base.GetProject(),
deployment=args.deployment,
resource=args.resource
)
)
except apitools_exceptions.HttpError as error:
raise exceptions.HttpException(error, dm_api_util.HTTP_ERROR_FORMAT)

View File

@@ -0,0 +1,160 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""resources list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import list_pager
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import alpha_flags
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class List(base.ListCommand, dm_base.DmCommand):
"""List resources in a deployment.
Prints a table with summary information on all resources in the deployment.
"""
detailed_help = {
'EXAMPLES': """
To print out a list of resources in the deployment with some summary information about each, run:
$ {command} --deployment=my-deployment
To print only the name of each resource, run:
$ {command} --deployment=my-deployment --simple-list
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
dm_api_util.SIMPLE_LIST_FLAG.AddToParser(parser)
parser.display_info.AddFormat("""
table(
name,
type:wrap,
update.state.yesno(no="COMPLETED"),
update.error.errors.group(code),
update.intent
)
""")
def Run(self, args):
"""Run 'resources list'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The list of resources for the specified deployment.
Raises:
HttpException: An http error response was received while executing api
request.
"""
request = self.messages.DeploymentmanagerResourcesListRequest(
project=dm_base.GetProject(),
deployment=args.deployment,
)
return dm_api_util.YieldWithHttpExceptions(
list_pager.YieldFromList(self.client.resources,
request,
field='resources',
limit=args.limit,
batch_size=args.page_size))
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.ALPHA)
class ListAlpha(List):
"""List resources in a deployment.
Prints a table with summary information on all resources in the deployment.
"""
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
dm_api_util.SIMPLE_LIST_FLAG.AddToParser(parser)
def _YieldPrintableResourcesOnErrors(self, args):
request = self.messages.DeploymentmanagerResourcesListRequest(
project=dm_base.GetProject(),
deployment=args.deployment,
)
paginated_resources = dm_api_util.YieldWithHttpExceptions(
list_pager.YieldFromList(
self.client.resources,
request,
field='resources',
limit=args.limit,
batch_size=args.page_size))
for resource in paginated_resources:
yield resource
def _isDeploymentInPreview(self, args):
deployment = dm_api_util.FetchDeployment(self.client, self.messages,
dm_base.GetProject(),
args.deployment)
if deployment.update:
return True
return False
def Run(self, args):
"""Run 'resources list'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The list of resources for the specified deployment.
Raises:
HttpException: An http error response was received while executing api
request.
"""
if args.IsSpecified('format'):
super(ListAlpha, self).Run(args)
elif self._isDeploymentInPreview(args):
args.format = alpha_flags.LIST_PREVIEWED_RESOURCES_FORMAT
else:
args.format = alpha_flags.LIST_RESOURCES_FORMAT
return dm_api_util.YieldWithHttpExceptions(
self._YieldPrintableResourcesOnErrors(args))

View File

@@ -0,0 +1,43 @@
# -*- 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.
"""Deployment Manager type providers sub-group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
class TypeProviders(base.Group):
"""Commands for Deployment Manager type providers."""
detailed_help = {
'EXAMPLES': """\
To view the details of a type provider, run:
$ {command} describe TYPE_NAME
To see the list of all type providers, run:
$ {command} list
More information about type providers:
https://cloud.google.com/deployment-manager/docs/fundamentals#basetypes
""",
}

View File

@@ -0,0 +1,113 @@
# -*- 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.
"""type-providers create command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import dm_labels
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.command_lib.deployment_manager import type_providers
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
def LogResource(request, is_async):
log.CreatedResource(request.typeProvider.name,
kind='type_provider',
is_async=is_async)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class Create(base.CreateCommand, dm_base.DmCommand):
"""Create a type provider.
This command inserts (creates) a new type provider based on a provided
configuration file.
"""
detailed_help = {
'EXAMPLES': """\
To create a new type provider, run:
$ {command} my-type-provider --api-options-file=my-options.yaml --descriptor-url=<descriptor URL> --description="My type."
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
flags.AddAsyncFlag(parser)
type_providers.AddTypeProviderNameFlag(parser)
type_providers.AddApiOptionsFileFlag(parser)
type_providers.AddDescriptionFlag(parser)
type_providers.AddDescriptorUrlFlag(parser)
type_providers.AddCustomCaCertificateFlag(parser)
labels_util.AddCreateLabelsFlags(parser)
def Run(self, args):
"""Run 'type-providers create'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Raises:
HttpException: An http error response was received while executing api
request.
"""
type_provider_ref = self.resources.Parse(
args.provider_name,
params={'project': properties.VALUES.core.project.GetOrFail},
collection='deploymentmanager.typeProviders')
update_labels_dict = labels_util.GetUpdateLabelsDictFromArgs(args)
labels = dm_labels.UpdateLabels([],
self.messages.TypeProviderLabelEntry,
update_labels=update_labels_dict)
type_provider = self.messages.TypeProvider(
name=type_provider_ref.typeProvider,
description=args.description,
descriptorUrl=args.descriptor_url,
customCertificateAuthorityRoots=args.custom_certificate_authority_roots,
labels=labels)
type_providers.AddOptions(self.messages,
args.api_options_file,
type_provider)
request = self.messages.DeploymentmanagerTypeProvidersInsertRequest(
project=type_provider_ref.project,
typeProvider=type_provider)
dm_write.Execute(self.client,
self.messages,
self.resources,
request,
args.async_,
self.client.typeProviders.Insert,
LogResource)

View File

@@ -0,0 +1,95 @@
# -*- 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.
"""type-providers delete command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.command_lib.deployment_manager import type_providers
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
def LogResource(request, is_async):
log.DeletedResource(request.typeProvider,
kind='type_provider',
is_async=is_async)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class Delete(base.DeleteCommand, dm_base.DmCommand):
"""Delete a type provider.
This command deletes a type provider.
"""
detailed_help = {
'EXAMPLES': """\
To delete a type provider, run:
$ {command} my-type-provider
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
flags.AddAsyncFlag(parser)
type_providers.AddTypeProviderNameFlag(parser)
def Run(self, args):
"""Run 'type-providers delete'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Raises:
HttpException: An http error response was received while executing api
request.
"""
type_provider_ref = type_providers.GetReference(self.resources,
args.provider_name)
if not args.quiet:
prompt_message = 'Are you sure you want to delete [{0}]?'.format(
type_provider_ref.typeProvider)
if not console_io.PromptContinue(message=prompt_message, default=False):
raise exceptions.OperationError('Deletion aborted by user.')
request = self.messages.DeploymentmanagerTypeProvidersDeleteRequest(
project=type_provider_ref.project,
typeProvider=type_provider_ref.typeProvider)
dm_write.Execute(self.client,
self.messages,
self.resources,
request,
args.async_,
self.client.typeProviders.Delete,
LogResource)

View File

@@ -0,0 +1,73 @@
# -*- 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.
"""'type-providers describe' command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import type_providers
from googlecloudsdk.core import properties
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class Describe(base.DescribeCommand, dm_base.DmCommand):
"""Describe a type provider entry in Type Registry."""
detailed_help = {
'EXAMPLES': """\
To display information about a type provider, run:
$ {command} NAME
""",
}
@staticmethod
def Args(parser):
"""Called by calliope to gather arguments for this command.
Args:
parser: argparse parser for specifying command line arguments
"""
type_providers.AddTypeProviderNameFlag(parser)
def Run(self, args):
"""Runs 'type-proivders describe'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The requested TypeProvider.
Raises:
HttpException: An http error response was received while executing the api
request.
InvalidArgumentException: The requested type provider could not be found.
"""
type_provider_ref = self.resources.Parse(
args.provider_name,
params={'project': properties.VALUES.core.project.GetOrFail},
collection='deploymentmanager.typeProviders')
request = self.messages.DeploymentmanagerTypeProvidersGetRequest(
**type_provider_ref.AsDict())
return self.client.typeProviders.Get(request)

View File

@@ -0,0 +1,73 @@
# -*- 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.
"""type-providers list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import list_pager
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class List(base.ListCommand, dm_base.DmCommand):
"""List type providers in a project.
Prints a list of the configured type providers.
"""
detailed_help = {
'EXAMPLES': """\
To print out a list of all type providers, run:
$ {command}
""",
}
@staticmethod
def Args(parser):
parser.display_info.AddFormat(
'table(name, insertTime.date(format="%Y-%m-%d"):label=INSERT_DATE)')
def Run(self, args):
"""Run 'type-providers list'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The list of type providers for this project.
Raises:
HttpException: An http error response was received while executing api
request.
"""
project = dm_base.GetProject()
request = (self.messages.
DeploymentmanagerTypeProvidersListRequest(project=project))
return dm_api_util.YieldWithHttpExceptions(
list_pager.YieldFromList(self.client.typeProviders,
request,
field='typeProviders',
batch_size=args.page_size,
limit=args.limit))

View File

@@ -0,0 +1,119 @@
# -*- 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.
"""type-providers update command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import dm_labels
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.command_lib.deployment_manager import type_providers
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
def LogResource(request, is_async):
log.UpdatedResource(request.typeProvider,
kind='type_provider',
is_async=is_async)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class Update(base.UpdateCommand, dm_base.DmCommand):
"""Update a type provider.
This command updates a type provider.
"""
detailed_help = {
'EXAMPLES': """\
To update a type provider, run:
$ {command} my-type-provider --api-options-file=my-options.yaml --descriptor-url=<descriptor URL> --description="My type."
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
flags.AddAsyncFlag(parser)
type_providers.AddTypeProviderNameFlag(parser)
type_providers.AddApiOptionsFileFlag(parser)
type_providers.AddDescriptionFlag(parser)
type_providers.AddDescriptorUrlFlag(parser)
type_providers.AddCustomCaCertificateFlag(parser)
labels_util.AddUpdateLabelsFlags(parser, enable_clear=False)
def Run(self, args):
"""Run 'type-providers update'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Raises:
HttpException: An http error response was received while executing api
request.
"""
type_provider_ref = type_providers.GetReference(self.resources,
args.provider_name)
project = type_provider_ref.project
name = type_provider_ref.typeProvider
get_request = self.messages.DeploymentmanagerTypeProvidersGetRequest(
project=project,
typeProvider=name)
existing_tp = self.client.typeProviders.Get(get_request)
labels = dm_labels.UpdateLabels(
existing_tp.labels,
self.messages.TypeProviderLabelEntry,
labels_util.GetUpdateLabelsDictFromArgs(args),
labels_util.GetRemoveLabelsListFromArgs(args))
type_provider = self.messages.TypeProvider(
name=name,
description=args.description,
descriptorUrl=(args.
descriptor_url),
customCertificateAuthorityRoots=args.custom_certificate_authority_roots,
labels=labels)
type_providers.AddOptions(self.messages,
args.api_options_file,
type_provider)
update_request = self.messages.DeploymentmanagerTypeProvidersUpdateRequest(
project=project,
typeProvider=args.provider_name,
typeProviderResource=type_provider)
dm_write.Execute(self.client,
self.messages,
self.resources,
update_request,
args.async_,
self.client.typeProviders.Update,
LogResource)

View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*- #
# Copyright 2014 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.
"""Deployment Manager types sub-group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Types(base.Group):
"""Commands for Deployment Manager types.
Commands to show available resource types.
"""
detailed_help = {
'EXAMPLES': """\
To see the list of all available resource types, run:
$ {command} list
""",
}

View File

@@ -0,0 +1,107 @@
# -*- 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.
"""types create command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import dm_labels
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import composite_types
from googlecloudsdk.command_lib.deployment_manager import dm_util
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
def LogResource(request, is_async):
log.CreatedResource(request.compositeType.name,
kind='composite_type',
is_async=is_async)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class Create(base.CreateCommand, dm_base.DmCommand):
"""Create a type.
This command inserts (creates) a new composite type based on a provided
configuration file.
"""
detailed_help = {
'EXAMPLES': """
To create a new composite type, run:
$ {command} my-composite-type --template=my-template.jinja --status=EXPERIMENTAL --description="My type."
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
flags.AddAsyncFlag(parser)
composite_types.AddCompositeTypeNameFlag(parser)
composite_types.AddTemplateFlag(parser)
composite_types.AddDescriptionFlag(parser)
composite_types.AddStatusFlag(parser)
labels_util.AddCreateLabelsFlags(parser)
def Run(self, args):
"""Run 'types create'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Raises:
HttpException: An http error response was received while executing api
request.
"""
composite_type_ref = composite_types.GetReference(self.resources, args.name)
update_labels_dict = labels_util.GetUpdateLabelsDictFromArgs(args)
labels = dm_labels.UpdateLabels([],
self.messages.CompositeTypeLabelEntry,
update_labels=update_labels_dict)
template_contents = composite_types.TemplateContentsFor(self.messages,
args.template)
computed_status = self.messages.CompositeType.StatusValueValuesEnum(
args.status) if args.status is not None else None
composite_type = self.messages.CompositeType(
name=args.name,
description=args.description,
status=computed_status,
templateContents=template_contents,
labels=labels)
request = self.messages.DeploymentmanagerCompositeTypesInsertRequest(
project=composite_type_ref.project,
compositeType=composite_type)
response = dm_write.Execute(self.client, self.messages, self.resources,
request, args.async_,
self.client.compositeTypes.Insert, LogResource)
dm_util.LogOperationStatus(response, 'Create')

View File

@@ -0,0 +1,90 @@
# -*- 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.
"""types delete command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import composite_types
from googlecloudsdk.command_lib.deployment_manager import dm_util
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
def LogResource(request, is_async):
log.DeletedResource(request.compositeType,
kind='composite_type',
is_async=is_async)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class Delete(base.DeleteCommand, dm_base.DmCommand):
"""Delete a composite type."""
detailed_help = {
'EXAMPLES': """\
To delete a composite type, run:
$ {command} my-composite-type
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
flags.AddAsyncFlag(parser)
composite_types.AddCompositeTypeNameFlag(parser)
def Run(self, args):
"""Run 'types delete'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Raises:
HttpException: An http error response was received while executing api
request.
"""
composite_type_ref = composite_types.GetReference(self.resources, args.name)
if not args.quiet:
prompt_message = 'Are you sure you want to delete [{0}]?'.format(
args.name)
if not console_io.PromptContinue(message=prompt_message, default=False):
raise exceptions.OperationError('Deletion aborted by user.')
request = (self.messages.
DeploymentmanagerCompositeTypesDeleteRequest(
project=composite_type_ref.project,
compositeType=args.name))
response = dm_write.Execute(self.client, self.messages, self.resources,
request, args.async_,
self.client.compositeTypes.Delete, LogResource)
dm_util.LogOperationStatus(response, 'Delete')

View File

@@ -0,0 +1,97 @@
# -*- 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.
"""'types describe' command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.calliope import base
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class Describe(base.DescribeCommand, dm_base.DmCommand):
"""Describe a type."""
detailed_help = {
'EXAMPLES': """\
To display information about a type provider type
$ {command} NAME --provider=PROVIDER
If you want to see information for a composite type you can use
$ {command} NAME --provider=composite --format="yaml[json-decode] (composite_type)"
""",
}
@staticmethod
def Args(parser):
"""Called by calliope to gather arguments for this command.
Args:
parser: argparse parser for specifying command line arguments
"""
parser.add_argument('name', help='Type name.')
parser.add_argument('--provider',
help='Type provider name or its self-link.',
required=True)
parser.display_info.AddFormat('yaml[json-decode](type_info)')
def Run(self, args):
"""Runs 'types describe'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The requested TypeInfo.
Raises:
HttpException: An http error response was received while executing the api
request.
InvalidArgumentException: The requested type provider type could not
be found.
"""
type_provider_ref = self.resources.Parse(
args.provider,
params={'project': properties.VALUES.core.project.GetOrFail},
collection='deploymentmanager.typeProviders')
request = self.messages.DeploymentmanagerTypeProvidersGetTypeRequest(
project=type_provider_ref.project,
type=args.name,
typeProvider=type_provider_ref.typeProvider)
type_message = self.client.typeProviders.GetType(request)
composite_type_message = 'This is not a composite type.'
if type_provider_ref.typeProvider == 'composite':
composite_request = (self.messages.
DeploymentmanagerCompositeTypesGetRequest(
project=type_provider_ref.project,
compositeType=args.name))
composite_type_message = self.client.compositeTypes.Get(composite_request)
log.status.Print('You can reference this type in Deployment Manager with '
'[{0}/{1}:{2}]'.format(type_provider_ref.project,
type_provider_ref.typeProvider,
args.name))
return {'type_info': type_message,
'composite_type': composite_type_message}

View File

@@ -0,0 +1,227 @@
# -*- 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.
"""types list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import collections
from apitools.base.py import list_pager
from googlecloudsdk.api_lib.deployment_manager import dm_api_util
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.util import apis
from googlecloudsdk.api_lib.util import exceptions as api_exceptions
from googlecloudsdk.calliope import base
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
GCP_TYPES_PROJECT = 'gcp-types'
@base.ReleaseTracks(base.ReleaseTrack.GA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2)
class List(base.ListCommand, dm_base.DmCommand):
"""List types in a project.
Prints a list of the available resource types.
## EXAMPLES
To print out a list of all available type names, run:
$ {command}
"""
@staticmethod
def Args(parser):
base.SORT_BY_FLAG.RemoveFromParser(parser)
base.URI_FLAG.RemoveFromParser(parser)
parser.display_info.AddFormat('table(name)')
def Run(self, args):
"""Run 'types list'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The list of types for this project.
Raises:
HttpException: An http error response was received while executing api
request.
"""
request = self.messages.DeploymentmanagerTypesListRequest(
project=dm_base.GetProject())
return dm_api_util.YieldWithHttpExceptions(
list_pager.YieldFromList(self.client.types, request,
field='types', batch_size=args.page_size,
limit=args.limit))
def Epilog(self, resources_were_displayed):
if not resources_were_displayed:
log.status.Print('No types were found for your project!')
def TypeProviderClient(version):
"""Return a Type Provider client specially suited for listing types.
Listing types requires many API calls, some of which may fail due to bad
user configurations which show up as errors that are retryable. We can
alleviate some of the latency and usability issues this causes by tuning
the client.
Args:
version: DM API version used for the client.
Returns:
A Type Provider API client.
"""
main_client = apis.GetClientInstance('deploymentmanager', version.id)
main_client.num_retries = 2
return main_client.typeProviders
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class ListALPHA(base.ListCommand, dm_base.DmCommand):
"""Describe a type provider type.
By default, you will see types from your project and gcp-types. To see types
from any single project, you can use the --provider-project flag.
## EXAMPLES
To print out a list of all available type names, run:
$ {command}
If you only want the types for a specific provider, you can specify
which one using --provider
$ {command} --provider=PROVIDER
By default, we'll show you types from your project and gcp-types,
which contains the default Google Cloud Platform types.
If you want types for only one project, use the 'provider-project'
flag. Specifying the provider without a provider-project will search
both your project and gcp-types for that provider's types.
"""
@staticmethod
def Args(parser):
# TODO(b/79993361): support URI flag after resolving the bug.
base.URI_FLAG.RemoveFromParser(parser)
parser.add_argument('--provider', help='Type provider name.')
parser.add_argument('--provider-project',
help='Project id with types you want to see.')
parser.display_info.AddFormat(
'yaml(provider:sort=1, error, types.map().format("{0}", name))')
def Run(self, args):
"""Run 'types list'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Returns:
The list of types for this project.
Raises:
HttpException: An http error response was received while executing api
request.
"""
type_provider_ref = self.resources.Parse(
args.provider if args.provider else 'NOT_A_PROVIDER',
params={'project': properties.VALUES.core.project.GetOrFail},
collection='deploymentmanager.typeProviders')
self.page_size = args.page_size
self.limit = args.limit
if args.provider_project:
projects = [args.provider_project]
else:
# Most users will be interested in the default gcp-types project types,
# so by default we want to display those
projects = [type_provider_ref.project, GCP_TYPES_PROJECT]
type_providers = collections.OrderedDict()
if not args.provider:
self._GetTypeProviders(projects, type_providers)
else:
for project in projects:
type_providers[project] = [type_provider_ref.typeProvider]
return dm_api_util.YieldWithHttpExceptions(
self._YieldPrintableTypesOrErrors(type_providers))
def _GetTypeProviders(self, projects, type_providers):
for project in projects:
request = (self.messages.
DeploymentmanagerTypeProvidersListRequest(
project=project))
project_providers = dm_api_util.YieldWithHttpExceptions(
list_pager.YieldFromList(TypeProviderClient(self.version),
request,
field='typeProviders',
batch_size=self.page_size,
limit=self.limit))
type_providers[project] = [provider.name for provider in
project_providers]
def _YieldPrintableTypesOrErrors(self, type_providers):
"""Yield dicts of types list, provider, and (optionally) an error message.
Args:
type_providers: A dict of project to Type Provider names to grab Type
Info messages for.
Yields:
A dict object with a list of types, a type provider reference (includes
project) like you would use in Deployment Manager, and (optionally) an
error message for display.
"""
for project in type_providers.keys():
for type_provider in type_providers[project]:
request = (self.messages.
DeploymentmanagerTypeProvidersListTypesRequest(
project=project,
typeProvider=type_provider))
try:
paginated_types = dm_api_util.YieldWithHttpExceptions(
list_pager.YieldFromList(TypeProviderClient(self.version),
request,
method='ListTypes',
field='types',
batch_size=self.page_size,
limit=self.limit))
types = list(paginated_types)
if types:
yield {'types': types,
'provider': project + '/' + type_provider}
except api_exceptions.HttpException as error:
self.exit_code = 1
yield {'types': [],
'provider': project + '/' + type_provider,
'error': error.message}

View File

@@ -0,0 +1,108 @@
# -*- 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.
"""types update command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.deployment_manager import dm_base
from googlecloudsdk.api_lib.deployment_manager import dm_labels
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.deployment_manager import composite_types
from googlecloudsdk.command_lib.deployment_manager import dm_util
from googlecloudsdk.command_lib.deployment_manager import dm_write
from googlecloudsdk.command_lib.deployment_manager import flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
def LogResource(request, is_async):
log.UpdatedResource(request.compositeType,
kind='composite_type',
is_async=is_async)
@base.ReleaseTracks(base.ReleaseTrack.BETA, base.ReleaseTrack.ALPHA)
@dm_base.UseDmApi(dm_base.DmApiVersion.V2BETA)
class Update(base.UpdateCommand, dm_base.DmCommand):
"""Update a composite type."""
detailed_help = {
'EXAMPLES': """
To update a composite type, run:
$ {command} my-composite-type --status=EXPERIMENTAL --description="My type."
""",
}
@staticmethod
def Args(parser):
"""Args is called by calliope to gather arguments for this command.
Args:
parser: An argparse parser that you can use to add arguments that go
on the command line after this command. Positional arguments are
allowed.
"""
flags.AddAsyncFlag(parser)
composite_types.AddCompositeTypeNameFlag(parser)
composite_types.AddDescriptionFlag(parser)
composite_types.AddStatusFlag(parser)
labels_util.AddUpdateLabelsFlags(parser, enable_clear=False)
def Run(self, args):
"""Run 'types update'.
Args:
args: argparse.Namespace, The arguments that this command was invoked
with.
Raises:
HttpException: An http error response was received while executing api
request.
"""
composite_type_ref = composite_types.GetReference(self.resources, args.name)
get_request = self.messages.DeploymentmanagerCompositeTypesGetRequest(
project=composite_type_ref.project,
compositeType=args.name)
existing_ct = self.client.compositeTypes.Get(get_request)
labels = dm_labels.UpdateLabels(
existing_ct.labels,
self.messages.CompositeTypeLabelEntry,
labels_util.GetUpdateLabelsDictFromArgs(args),
labels_util.GetRemoveLabelsListFromArgs(args))
computed_status = self.messages.CompositeType.StatusValueValuesEnum(
args.status) if args.status is not None else None
composite_type = self.messages.CompositeType(
name=args.name,
description=args.description,
status=computed_status,
templateContents=existing_ct.templateContents,
labels=labels)
update_request = self.messages.DeploymentmanagerCompositeTypesUpdateRequest(
project=composite_type_ref.project,
compositeType=args.name,
compositeTypeResource=composite_type)
response = dm_write.Execute(self.client, self.messages, self.resources,
update_request, args.async_,
self.client.compositeTypes.Update, LogResource)
dm_util.LogOperationStatus(response, 'Update')