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,44 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
"""Wrapper around Snapshot to provide file-order determinism."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import os
from googlecloudsdk.api_lib.storage import storage_util
class DeterministicSnapshot(storage_util.Snapshot):
"""DeterministicSnapshot is a thin wrapper around Snapshot."""
def GetSortedFiles(self):
"""Gets the values of `self.files` in a deterministic order.
Internally, `self.files` is a dictionary. Prior to Python 3.6, dictionaries
were ordered nondeterministically, but our tests require determinism. As
such, we have to convert the underlying dictionary to a list and sort that
list. The specific order itself (e.g. alphabetical vs. reverse-alphabetical)
doesn't matter.
Returns:
A list of files in a deterministic order.
"""
return sorted(
self.files.values(), key=lambda m: os.path.join(m.root, m.path)
)

View File

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
"""Definition for errors in Infra Manager."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.core import exceptions
class InvalidDataError(exceptions.Error):
"""Error indicating that invalid data is encountered."""
pass
class NotSupportedError(exceptions.Error):
"""Error indicating that feature is not supported."""
pass
class OperationFailedError(exceptions.Error):
"""Error indicating that operation has failed."""
pass

View File

@@ -0,0 +1,429 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
"""Flags and helpers for the config-manager command group."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.functions.v1 import util as functions_api_util
from googlecloudsdk.api_lib.infra_manager import configmanager_util
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
def AddLabelsFlag(parser, help_text):
"""Add --labels flag."""
parser.add_argument(
'--labels',
metavar='KEY=VALUE',
type=arg_parsers.ArgDict(),
help=help_text,
)
def AddAnnotationsFlag(parser, help_text):
"""Add --annotations flag."""
parser.add_argument(
'--annotations',
metavar='KEY=VALUE',
type=arg_parsers.ArgDict(),
help=help_text,
)
def AddAsyncFlag(parser):
"""Add --async flag."""
base.ASYNC_FLAG.AddToParser(parser)
def AddTerraformBlueprintFlag(parser):
"""Add TerraformBlueprint related flags."""
input_values_help_text = """\
Input variable values for the Terraform blueprint. It only
accepts (key, value) pairs where value is a scalar value.
Examples:
Pass input values on command line:
$ {command} projects/p1/location/us-central1/deployments/my-deployment --gcs-source="gs://my-bucket" --input-values=projects=p1,region=r
"""
inputs_file_help_text = """\
A .tfvars file containing terraform variable values. --inputs-file flag is supported for python version 3.6 and above.
Examples:
Pass input values on the command line:
$ {command} projects/p1/location/us-central1/deployments/my-deployment --gcs-source="gs://my-bucket" --inputs-file=path-to-tfvar-file.tfvar
"""
gcs_source_help_text = """\
URI of an object in Google Cloud Storage.
e.g. `gs://{bucket}/{object}`
Examples:
Create a deployment from a storage my-bucket:
$ {command} projects/p1/location/us-central1/deployments/my-deployment --gcs-source="gs://my-bucket"
"""
git_source_repo_help = """\
Repository URL.
Example: 'https://github.com/examples/repository.git'
Use in conjunction with `--git-source-directory` and `--git-source_ref`
Examples:
Create a deployment from the "https://github.com/examples/repository.git" repo, "staging/compute" folder, "mainline" branch:
$ {command} projects/p1/location/us-central1/deployments/my-deployment --git-source-repo="https://github.com/examples/repository.git"
--git-source-directory="staging/compute" --git-source-ref="mainline"
"""
git_source_directory_help = """\
Subdirectory inside the repository.
Example: 'staging/my-package'
Use in conjunction with `--git-source-repo` and `--git-source-ref`
Examples:
Create a deployment from the "https://github.com/examples/repository.git" repo, "staging/compute" folder, "mainline" branch:
$ {command} projects/p1/location/us-central1/deployments/my-deployment --git-source-repo="https://github.com/examples/repository.git"
--git-source-directory="staging/compute" --git-source-ref="mainline"
"""
git_source_ref_help = """\
Subdirectory inside the repository.
Example: 'staging/my-package'
Use in conjunction with `--git-source-repo` and `--git-source-directory`
Examples:
Create a deployment from the "https://github.com/examples/repository.git" repo, "staging/compute" folder, "mainline" branch:
$ {command} projects/p1/location/us-central1/deployments/my-deployment --git-source-repo="https://github.com/examples/repository.git"
--git-source-directory="staging/compute" --git-source-ref="mainline"
"""
local_source_help = """\
Local storage path where config files are stored. When using this option, Terraform config file references outside this storage path is not supported.
e.g. `./path/to/blueprint`
Examples:
Create a deployment from a local storage path `./path/to/blueprint`:
$ {command} projects/p1/location/us-central1/deployments/my-deployment --local-source="./path/to/blueprint"
"""
stage_bucket_help = """\
Use in conjunction with `--local-source` to specify a destination storage bucket for
uploading local files.
If unspecified, the bucket defaults to `gs://PROJECT_NAME_blueprints`. Uploaded
content will appear in the `source` object under a name comprised of the
timestamp and a UUID. The final output destination looks like this:
`gs://_BUCKET_/source/1615850562.234312-044e784992744951b0cd71c0b011edce/`
Examples:
Create a deployment from a local storage path `./path/to/blueprint` and stage-bucket `gs://my-bucket`:
$ {command} projects/p1/location/us-central1/deployments/my-deployment --local-source="./path/to/blueprint" --stage-bucket="gs://my-bucket"
"""
source_group = parser.add_group(mutex=False)
input_values = source_group.add_mutually_exclusive_group()
input_values.add_argument(
'--input-values',
metavar='KEY=VALUE',
type=arg_parsers.ArgDict(),
help=input_values_help_text,
)
input_values.add_argument(
'--inputs-file',
help=inputs_file_help_text,
)
source_details = source_group.add_mutually_exclusive_group()
source_details.add_argument(
'--gcs-source',
help=gcs_source_help_text,
)
git_source_group = source_details.add_group(mutex=False)
git_source_group.add_argument(
'--git-source-repo',
help=git_source_repo_help,
)
git_source_group.add_argument(
'--git-source-directory',
help=git_source_directory_help,
)
git_source_group.add_argument(
'--git-source-ref',
help=git_source_ref_help,
)
local_source_group = source_details.add_group(mutex=False)
local_source_group.add_argument(
'--local-source',
help=local_source_help,
)
local_source_group.add_argument(
'--ignore-file',
help=(
'Override the `.gcloudignore` file and use the specified file '
'instead. See `gcloud topic gcloudignore` for more information.'
),
)
# Note: we cannot specify a default here since the default value we would WANT
# to use is dynamic; it includes the project ID.
local_source_group.add_argument(
'--stage-bucket',
help=stage_bucket_help,
hidden=True,
# This will ensure that "--stage-bucket" takes on the form
# "gs://my-bucket/".
type=functions_api_util.ValidateAndStandarizeBucketUriOrRaise,
)
def AddServiceAccountFlag(parser, hidden=False):
"""Add --service-account flag."""
parser.add_argument(
'--service-account',
hidden=hidden,
help=(
'User-specified Service Account (SA) to be used as credential to'
' manage resources. Format:'
' `projects/{projectID}/serviceAccounts/{serviceAccount}`'
),
)
def AddImportExistingResourcesFlag(parser, hidden=False):
"""Add --import-existing-resources flag."""
parser.add_argument(
'--import-existing-resources',
hidden=hidden,
action='store_true',
help=(
'By default, Infrastructure Manager will return a failure when'
' Terraform encounters a 409 code (resource conflict error) during'
' actuation. If this flag is set to true, Infrastructure Manager will'
' instead attempt to automatically import the resource into the'
' Terraform state (for supported resource types) and continue'
' actuation.'
),
)
def AddWorkerPoolFlag(parser, hidden=False):
"""Add --worker-pool flag."""
parser.add_argument(
'--worker-pool',
hidden=hidden,
help=(
'User-specified Worker Pool resource in which the Cloud Build job '
'will execute. Format: '
'projects/{project}/locations/{location}/workerPools/{workerPoolId}'
),
)
def AddArtifactsGCSBucketFlag(parser, hidden=False):
"""Add --artifacts-gcs-bucket flag."""
parser.add_argument(
'--artifacts-gcs-bucket',
hidden=hidden,
help=(
'user-defined location of Cloud Build logs, artifacts, and Terraform'
' state files in Google Cloud Storage. Format:'
' `gs://{bucket}/{folder}` A default bucket will be bootstrapped if'
' the field is not set or empty'
),
)
def AddDraftFlag(parser, hidden=False):
"""Add --draft flag."""
parser.add_argument(
'--draft',
hidden=hidden,
help=(
'If this flag is set to true, the exported deployment state file will'
' be the draft state'
),
action='store_true',
)
def AddLockFlag(parser, hidden=False):
"""Add --lock-id flag."""
parser.add_argument(
'--lock-id',
required=True,
hidden=hidden,
help='Lock ID of the lock file to verify person importing owns lock.',
)
def AddDeploymentFlag(parser, hidden=False):
"""Add --deployment flag."""
parser.add_argument(
'--deployment',
hidden=hidden,
help='Deployment reference for preview.',
)
def AddPreviewModeFlag(parser, hidden=False):
"""Add --preview-mode flag."""
parser.add_argument(
'--preview-mode',
hidden=hidden,
help='Preview mode to set it to either default or delete.',
)
def AddFileFlag(parser, help_text, hidden=False):
"""Add --file flag."""
parser.add_argument(
'--file',
hidden=hidden,
help=help_text,
)
def AddTFVersionConstraintFlag(parser, hidden=False):
"""Add --tf-version-constraint flag."""
parser.add_argument(
'--tf-version-constraint',
hidden=hidden,
help=(
'User-specified Terraform version constraint, for example "=1.3.10".'
),
)
def AddQuotaValidationFlag(parser, hidden=False):
"""Add --quota-validation flag."""
parser.add_argument(
'--quota-validation',
hidden=hidden,
help=(
'Input to control quota checks for resources in terraform'
' configuration files. There are limited resources on which quota'
' validation applies. Supported values are'
' QUOTA_VALIDATION_UNSPECIFIED, ENABLED, ENFORCED'
),
type=QuotaValidationEnum,
)
def QuotaValidationEnum(quota_validation):
"""Checks if a quota validation provided by user is valid and returns corresponding enum type.
Args:
quota_validation: value for quota validation.
Returns:
quota validation enum
Raises:
ArgumentTypeError: If the value provided by user is not valid.
"""
messages = configmanager_util.GetMessagesModule()
quota_validation_enum_dict = {
'QUOTA_VALIDATION_UNSPECIFIED': (
messages.Deployment.QuotaValidationValueValuesEnum.QUOTA_VALIDATION_UNSPECIFIED
),
'ENABLED': messages.Deployment.QuotaValidationValueValuesEnum.ENABLED,
'ENFORCED': messages.Deployment.QuotaValidationValueValuesEnum.ENFORCED,
}
if quota_validation is None:
return
if quota_validation not in quota_validation_enum_dict:
raise arg_parsers.ArgumentTypeError(
"quota validation does not support: '{0}', supported values are: {1}"
.format(quota_validation, list(quota_validation_enum_dict))
)
return quota_validation_enum_dict[quota_validation]
# TODO: b/433318303 - Remove `hidden` annotation to make dark site
# commands public.
def AddProviderSourceFlag(parser, hidden=True):
"""Add --provider-source flag."""
parser.add_argument(
'--provider-source',
hidden=hidden,
help=(
'Input to control from where to fetch providers. Supported values are'
'PROVIDER_SOURCE_UNSPECIFIED, SERVICE_MAINTAINED'
),
type=ProviderSourceEnum,
)
def ProviderSourceEnum(provider_source):
"""Checks if a provider config provided by user is valid and returns corresponding enum type.
Args:
provider_source: value for provider source.
Returns:
provider source enum
Raises:
ArgumentTypeError: If the value provided by user is not valid.
"""
messages = configmanager_util.GetMessagesModule()
provider_source_enum_dict = {
'PROVIDER_SOURCE_UNSPECIFIED': (
messages.ProviderConfig.SourceTypeValueValuesEnum.PROVIDER_SOURCE_UNSPECIFIED
),
'SERVICE_MAINTAINED': (
messages.ProviderConfig.SourceTypeValueValuesEnum.SERVICE_MAINTAINED
),
}
if provider_source is None:
return
if provider_source not in provider_source_enum_dict:
raise arg_parsers.ArgumentTypeError(
"provider config does not support: '{0}', supported values are: {1}"
.format(provider_source, list(provider_source_enum_dict))
)
return provider_source_enum_dict[provider_source]

View File

@@ -0,0 +1,168 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
"""Shared resource flags for Config Manager commands."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope.concepts import concepts
from googlecloudsdk.calliope.concepts import deps
from googlecloudsdk.command_lib.util.concepts import presentation_specs
from googlecloudsdk.core import properties
def DeploymentAttributeConfig():
return concepts.ResourceParameterAttributeConfig(
name='deployment', help_text='The deployment for the {resource}.'
)
def RevisionAttributeConfig():
return concepts.ResourceParameterAttributeConfig(
name='revision', help_text='The revision for the {resource}.'
)
def LocationAttributeConfig():
fallthroughs = [
deps.PropertyFallthrough(properties.VALUES.inframanager.location)
]
return concepts.ResourceParameterAttributeConfig(
name='location',
fallthroughs=fallthroughs,
help_text='The Cloud location for the {resource}.',
)
def PreviewAttributeConfig():
return concepts.ResourceParameterAttributeConfig(
name='preview', help_text='The preview for the {resource}.'
)
def GetDeploymentResourceSpec():
return concepts.ResourceSpec(
'config.projects.locations.deployments',
resource_name='deployment',
deploymentsId=DeploymentAttributeConfig(),
locationsId=LocationAttributeConfig(),
projectsId=concepts.DEFAULT_PROJECT_ATTRIBUTE_CONFIG,
disable_auto_completers=False,
)
def GetRevisionResourceSpec():
return concepts.ResourceSpec(
'config.projects.locations.deployments.revisions',
resource_name='revision',
revisionsId=RevisionAttributeConfig(),
deploymentsId=DeploymentAttributeConfig(),
locationsId=LocationAttributeConfig(),
projectsId=concepts.DEFAULT_PROJECT_ATTRIBUTE_CONFIG,
disable_auto_completers=False,
)
def GetPreviewResourceSpec():
return concepts.ResourceSpec(
'config.projects.locations.previews',
resource_name='preview',
previewsId=PreviewAttributeConfig(),
locationsId=LocationAttributeConfig(),
projectsId=concepts.DEFAULT_PROJECT_ATTRIBUTE_CONFIG,
disable_auto_completers=False,
)
def GetLocationResourceSpec():
return concepts.ResourceSpec(
'config.projects.locations',
resource_name='location',
locationsId=LocationAttributeConfig(),
projectsId=concepts.DEFAULT_PROJECT_ATTRIBUTE_CONFIG,
disable_auto_completers=False,
)
def GetDeploymentResourceArgSpec(group_help):
"""Gets a resource presentation spec for a config manager deployment.
Args:
group_help: string, the help text for the entire arg group.
Returns:
ResourcePresentationSpec for a config manager deployment resource argument.
"""
name = 'DEPLOYMENT'
return presentation_specs.ResourcePresentationSpec(
name, GetDeploymentResourceSpec(), group_help, required=True
)
def GetRevisionResourceArgSpec(group_help):
"""Gets a resource presentation spec for a config manager revision.
Args:
group_help: string, the help text for the entire arg group.
Returns:
ResourcePresentationSpec for a config manager revision resource argument.
"""
name = 'REVISION'
return presentation_specs.ResourcePresentationSpec(
name, GetRevisionResourceSpec(), group_help, required=True
)
def GetPreviewResourceArgSpec(
group_help, required=True, flag_name_overrides=None
):
"""Gets a resource presentation spec for a config manager preview.
Args:
group_help: string, the help text for the entire arg group.
required:
flag_name_overrides:
Returns:
ResourcePresentationSpec for a config manager preview resource argument.
"""
name = 'PREVIEW'
return presentation_specs.ResourcePresentationSpec(
name,
GetPreviewResourceSpec(),
group_help,
required=required,
flag_name_overrides=flag_name_overrides,
)
def GetLocationResourceArgSpec(group_help):
"""Gets a resource presentation spec for a config manager preview.
Args:
group_help: string, the help text for the entire arg group.
Returns:
ResourcePresentationSpec for a config manager preview resource argument.
"""
name = '--location'
return presentation_specs.ResourcePresentationSpec(
name,
GetLocationResourceSpec(),
group_help,
required=True,
)

View File

@@ -0,0 +1,143 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
project:
name: project
plural_name: projects
collection: config.projects
request_id_field: projectId
attributes:
- &project
parameter_name: projectsId
attribute_name: project
help: projects TBD
property: core/project
disable_auto_completers: false
location:
name: location
plural_name: locations
collection: config.projects.locations
request_id_field: locationId
attributes:
- *project
- &location
parameter_name: locationsId
attribute_name: location
help: locations TBD
property: infra-manager/location
disable_auto_completers: false
deployment:
name: deployment
plural_name: deployments
collection: config.projects.locations.deployments
request_id_field: deploymentId
attributes:
- *project
- *location
- &deployment
parameter_name: deploymentsId
attribute_name: deployment
help: deployments TBD
disable_auto_completers: false
revision:
name: revision
plural_name: revisions
collection: config.projects.locations.deployments.revisions
request_id_field: revisionId
attributes:
- *project
- *location
- *deployment
- &revision
parameter_name: revisionsId
attribute_name: revision
help: revisions TBD
disable_auto_completers: false
resource:
name: resource
plural_name: resources
collection: config.projects.locations.deployments.revisions.resources
request_id_field: resourceId
attributes:
- *project
- *location
- *deployment
- *revision
- &resource
parameter_name: resourcesId
attribute_name: resource
help: resources TBD
disable_auto_completers: false
preview:
name: preview
plural_name: previews
collection: config.projects.locations.previews
request_id_field: previewId
attributes:
- *project
- *location
- &preview
parameter_name: previewsId
attribute_name: preview
help: preview TBD
disable_auto_completers: false
terraform_version:
name: terraformVersion
plural_name: terraformVersions
collection: config.projects.locations.terraformVersions
request_id_field: terraformVersionsId
attributes:
- *project
- *location
- &terraform_version
parameter_name: terraformVersionsId
attribute_name: terraform_version
help: terraform version TBD
disable_auto_completers: false
resource_change:
name: resourceChange
plural_name: resourceChanges
collection: config.projects.locations.previews.resourceChanges
request_id_field: resourceChangeId
attributes:
- *project
- *location
- *preview
- &resource_change
parameter_name: resourceChangesId
attribute_name: resource_change
help: resource change TBD
disable_auto_completers: false
resource_drift:
name: resourceDrift
plural_name: resourceDrifts
collection: config.projects.locations.previews.resourceDrifts
request_id_field: resourceDriftId
attributes:
- *project
- *location
- *preview
- &resource_drift
parameter_name: resourceDriftsId
attribute_name: resource_drift
help: resource drift TBD
disable_auto_completers: false
automigrationconfig:
name: autoMigrationConfig
plural_name: autoMigrationConfigs
collection: config.projects.locations.autoMigrationConfig
attributes:
- *project
- *location
disable_auto_completers: false

View File

@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
"""Support library to handle the staging bucket."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.storage import storage_api
from googlecloudsdk.api_lib.storage import storage_util
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
# The object name to use for our staging GCS storage. This is supposed to be
# identifiable as infra-manager generated, which will assist with cleanup.
STAGING_DIR = 'im_source_staging'
# This function is very similar to the one made for Cloud Build.
def GetDefaultStagingBucket():
"""Returns the default bucket stage files.
Returns:
A string representing the GCS bucket name.
"""
safe_project = (
properties.VALUES.core.project.Get(required=True)
.replace(':', '_')
.replace('.', '_')
# The string 'google' is not allowed in bucket names.
.replace('google', 'elgoog')
)
return safe_project + '_infra_manager_staging'
def DefaultGCSStagingDir(deployment_short_name, location):
"""Get default staging directory.
Args:
deployment_short_name: short name of the deployment.
location: location of the deployment.
Returns:
A default staging directory string.
"""
gcs_source_bucket_name = GetDefaultStagingBucket()
gcs_source_staging_dir = 'gs://{0}/{1}/{2}/{3}'.format(
gcs_source_bucket_name, STAGING_DIR, location, deployment_short_name
)
return gcs_source_staging_dir
def DeleteStagingGCSFolder(gcs_client, object_uri):
"""Deletes object if the object_uri is a staging path or else skips deletion.
Args:
gcs_client: a storage_api.StorageClient instance for interacting with GCS.
object_uri: a gcs object path in format gs://path/to/gcs/object.
Raises:
NotFoundError: If the bucket or folder does not exist.
"""
staging_dir_prefix = 'gs://{0}/{1}'.format(
GetDefaultStagingBucket(), STAGING_DIR
)
if not object_uri.startswith(staging_dir_prefix):
return
gcs_staging_dir_ref = resources.REGISTRY.Parse(
object_uri, collection='storage.objects'
)
bucket_ref = storage_util.BucketReference(gcs_staging_dir_ref.bucket)
try:
items = gcs_client.ListBucket(bucket_ref, gcs_staging_dir_ref.object)
for item in items:
object_ref = storage_util.ObjectReference.FromName(
gcs_staging_dir_ref.bucket, item.name
)
gcs_client.DeleteObject(object_ref)
except storage_api.BucketNotFoundError:
# if staging bucket does not exist, do nothing
pass

View File

@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
"""Parser for tfvar files."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.command_lib.infra_manager import errors
from googlecloudsdk.core.util import files
import hcl2
import six
def ParseTFvarFile(filename):
"""Parses a `tfvar` file and returns a dictionary of configuration values.
Args:
filename: The path to the `tfvar` file.
Returns:
A dictionary of configuration values.
"""
try:
f = files.ReadFileContents(filename)
config = hcl2.loads(f)
return config
except Exception as e:
raise errors.InvalidDataError(
"Error encountered while parsing " + filename + ": " + six.text_type(e)
)