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,69 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command group for Artifact Registry container images."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
class Images(base.Group):
"""Manage Artifact Registry container images.
To list images under the current project, repository, and location:
$ {command} list
To list images under repository `my-repo`, project `my-project`, in
`us-central1`:
$ {command} list us-central1-docker.pkg.dev/my-project/my-repo
To list images with tags, under repository `my-repo`, project `my-project`
across all locations:
$ {command} list docker.pkg.dev/my-project/my-repo --include-tags
To list all images under image `busy-box`, in repository `my-repo`, project
`my-project` across all locations:
$ {command} list docker.pkg.dev/my-project/my-repo/busy-box
To delete image `busy-box` in `us-west1` and all of its digests and tags:
$ {command} delete
us-west1-docker.pkg.dev/my-project/my-repository/busy-box
To delete image digest `abcxyz` under image `busy-box`:
$ {command} delete
us-west1-docker.pkg.dev/my-project/my-repository/busy-box@sha256:abcxyz
To delete image digest `abcxyz` under image `busy-box` while there're some
other tags associate with the digest:
$ {command} delete
us-west1-docker.pkg.dev/my-project/my-repository/busy-box@sha256:abcxyz
--delete-tags
To delete an image digest and its only tag `my-tag` under image `busy-box`:
$ {command} delete
us-west1-docker.pkg.dev/my-project/my-repository/busy-box:my-tag
"""
category = base.CI_CD_CATEGORY

View File

@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Delete an Artifact Registry container image."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.artifacts import docker_util
from googlecloudsdk.command_lib.artifacts import flags
from googlecloudsdk.core import log
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class Delete(base.Command):
"""Delete an Artifact Registry container image.
A valid container image has the format of
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE
A valid container image that can be referenced by tag or digest, has the
format of
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE:tag
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE@sha256:digest
This command can fail for the following reasons:
* Trying to delete an image by digest when the image is still tagged. Add
--delete-tags to delete the digest and the tags.
* Trying to delete an image by tag when the image has other tags. Add
--delete-tags to delete all tags.
* A valid repository format was not provided.
* The specified image does not exist.
* The active account does not have permission to delete images.
"""
detailed_help = {
'DESCRIPTION':
'{description}',
'EXAMPLES':
"""\
To delete image `busy-box` in `us-west1` and all of its digests and tags:
$ {command} us-west1-docker.pkg.dev/my-project/my-repository/busy-box
To delete image digest `abcxyz` under image `busy-box`:
$ {command} us-west1-docker.pkg.dev/my-project/my-repository/busy-box@sha256:abcxyz
To delete image digest `abcxyz` under image `busy-box` while there're other tags associate with the digest:
$ {command} us-west1-docker.pkg.dev/my-project/my-repository/busy-box@sha256:abcxyz --delete-tags
To delete an image digest and its only tag `my-tag` under image `busy-box`:
$ {command} us-west1-docker.pkg.dev/my-project/my-repository/busy-box:my-tag
""",
}
@staticmethod
def Args(parser):
base.ASYNC_FLAG.AddToParser(parser)
flags.GetDeleteTagsFlag().AddToParser(parser)
flags.GetImageRequiredArg().AddToParser(parser)
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
DeleteVersion operation.
"""
op = docker_util.DeleteDockerImage(args)
if args.async_:
log.status.Print(
'Delete request issued.\nCheck operation [{}] for status.'.format(
op.name))
else:
log.status.Print('Delete request issued.')
docker_util.WaitForOperation(
op, 'Waiting for operation [{}] to complete'.format(op.name))

View File

@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Delete an Artifact Registry container image."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.artifacts import docker_util
from googlecloudsdk.command_lib.artifacts import flags
@base.DefaultUniverseOnly
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Describe(base.DescribeCommand):
"""Describe an Artifact Registry container image.
Reference an image by tag or digest using the format:
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE:tag
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE@sha256:digest
This command can fail for the following reasons:
* The repository format is invalid.
* The specified image does not exist.
* The active account does not have permission to run the command
(`roles/artifactregistry.reader`, `roles/containeranalysis.admin` and
`roles/serviceusage.serviceUsageViewer`).
"""
detailed_help = {
"DESCRIPTION": "{description}",
"EXAMPLES": """\
To describe an image digest `abcxyz` under image `busy-box`:
$ {command} us-west1-docker.pkg.dev/my-project/my-repository/busy-box@sha256:abcxyz
To describe an image `busy-box` with tag `my-tag`:
$ {command} us-west1-docker.pkg.dev/my-project/my-repository/busy-box:my-tag
""",
}
@staticmethod
def Args(parser):
parser.display_info.AddFormat("yaml")
flags.GetImageRequiredArg().AddToParser(parser)
flags.GetShowAllMetadataFlag().AddToParser(parser)
flags.GetMetadataFilterFlag().AddToParser(parser)
flags.GetShowBuildDetailsFlag().AddToParser(parser)
flags.GetShowPackageVulnerabilityFlag().AddToParser(parser)
flags.GetShowImageBasisFlag().AddToParser(parser)
flags.GetShowDeploymentFlag().AddToParser(parser)
flags.GetShowProvenanceFlag().AddToParser(parser)
flags.GetShowSbomReferencesFlag().AddToParser(parser)
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Raises:
InvalidImageNameError: If the user specified an invalid image name.
Returns:
Some value that we want to have printed later.
"""
return docker_util.DescribeDockerImage(args)

View File

@@ -0,0 +1,23 @@
- release_tracks: [BETA, GA]
help_text:
brief: Get an On-Demand Scanning operation.
description: |
Get an On-Demand Scanning operation.
examples: |
The following command gets an On-Demand Scanning operation.
$ {command} projects/my-project/locations/europe/operations/ddf40882-0d55-4214-a619-c1c36df5040c
command_type: DESCRIBE
request:
collection: ondemandscanning.projects.locations.operations
BETA:
api_version: v1beta1
GA:
api_version: v1
arguments:
resource:
help_text: The scan operation to get.
spec: !REF googlecloudsdk.command_lib.container.images.resources:operation
is_positional: true

View File

@@ -0,0 +1,158 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""List Artifact Registry container images."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import heapq
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.artifacts import containeranalysis_util as ca_util
from googlecloudsdk.command_lib.artifacts import docker_util
from googlecloudsdk.command_lib.artifacts import flags
from googlecloudsdk.command_lib.artifacts import format_util
from googlecloudsdk.core import log
DEFAULT_LIST_FORMAT = """\
table(
package:label=IMAGE,
version:label=DIGEST,
createTime.date(tz=LOCAL),
updateTime.date(tz=LOCAL),
metadata.imageSizeBytes:label=SIZE,
{}
)""".format(format_util.CONTAINER_ANALYSIS_METADATA_FORMAT)
EXTENDED_LIST_FORMAT = """\
table(
package:label=IMAGE,
version:label=DIGEST,
tags.list(),
createTime.date(tz=LOCAL),
updateTime.date(tz=LOCAL),
metadata.imageSizeBytes:label=SIZE,
{}
)""".format(format_util.CONTAINER_ANALYSIS_METADATA_FORMAT)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
@base.UniverseCompatible
class List(base.ListCommand):
"""List Artifact Registry container images.
List all Artifact Registry container images in the specified repository or
image path.
A valid Docker repository has the format of
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID
A valid image has the format of
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE_PATH
To specify the maximum number of images to list, use the --limit flag.
"""
detailed_help = {
'DESCRIPTION':
'{description}',
'EXAMPLES':
"""\
To list images under the current project, repository, and location:
$ {command}
To list images with tags under the current project, repository, and location:
$ {command} --include-tags
To list images under repository `my-repo`, project `my-project`, in `us-central1`:
$ {command} us-central1-docker.pkg.dev/my-project/my-repo
The following command lists a maximum of five images:
$ {command} docker.pkg.dev/my-project/my-repo --limit=5
""",
}
@staticmethod
def Args(parser):
flags.GetIncludeTagsFlag().AddToParser(parser)
base.URI_FLAG.RemoveFromParser(parser)
flags.GetImagePathOptionalArg().AddToParser(parser)
flags.GetShowOccurrencesFlag().AddToParser(parser)
flags.GetShowOccurrencesFromFlag().AddToParser(parser)
flags.GetOccurrenceFilterFlag().AddToParser(parser)
def Run(self, args):
"""This is what gets called when the user runs this command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
A list of Docker images.
"""
if _IncludeMetadata(args):
log.status.Print(
"Note: The '--format' flag can be used to change the output format."
)
else:
if args.include_tags:
args.GetDisplayInfo().AddFormat(EXTENDED_LIST_FORMAT)
else:
args.GetDisplayInfo().AddFormat(DEFAULT_LIST_FORMAT)
# Retrieve images.
repo_or_image = docker_util.ParseDockerImagePath(args.IMAGE_PATH)
images = docker_util.GetDockerImages(repo_or_image, args)
# Retrieve containeranalysis metadata for images.
most_recent_images = []
if _IncludeMetadata(args):
if args.show_occurrences_from:
images = heapq.nlargest(
args.show_occurrences_from,
images,
key=lambda img: img['createTime'])
most_recent_images = [
'{}@{}'.format(img['package'], img['version'])
for img in images
]
metadata = ca_util.GetContainerAnalysisMetadataForImages(
repo_or_image, args.occurrence_filter, most_recent_images)
for image in images:
image_path = 'https://{}@{}'.format(image['package'], image['version'])
img_metadata = metadata[image_path].ImagesListView()
image.update(img_metadata)
return images
def _IncludeMetadata(args):
default_occ_filter = (
'kind="BUILD" OR kind="IMAGE" OR kind="DISCOVERY" OR'
' kind="SBOM_REFERENCE"'
)
return args.show_occurrences or (
# Assume the user wants to see occurrences if they explicitly filter.
args.occurrence_filter and args.occurrence_filter != default_occ_filter
)

View File

@@ -0,0 +1,32 @@
- release_tracks: [BETA, GA]
help_text:
brief: List On-Demand Scanning vulnerabilities.
description: |
List On-Demand Scanning vulnerabilities from a completed scan.
examples: |
The following command lists vulnerabilities from a completed On-Demand
Scanning scan.
$ {command} projects/my-project/locations/europe/scans/fff66882-0z55-4333-l619-z1z00df6040c
command_type: LIST
request:
collection: ondemandscanning.projects.locations.scans.vulnerabilities
BETA:
api_version: v1beta1
GA:
api_version: v1
arguments:
resource:
help_text: The scan resource to list vulnerabilites for.
spec: !REF googlecloudsdk.command_lib.container.images.resources:scan
is_positional: true
# This is needed because the request path ends with "/vulnerabilities" and
# doesn't match the Scan resource name, but they both refer to the same
# actual resource object (vulnerability occurrences).
override_resource_collection: true
# These aren't supported at this time.
exclude: ['filter', 'sort-by']

View File

@@ -0,0 +1,331 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Scan a container image using the On-Demand Scanning API."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import json
from googlecloudsdk.api_lib.ondemandscanning import util as api_util
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.artifacts import flags
from googlecloudsdk.command_lib.artifacts import ondemandscanning_util as ods_util
from googlecloudsdk.command_lib.util.anthos import binary_operations
from googlecloudsdk.command_lib.util.apis import arg_utils
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
from googlecloudsdk.core.console import progress_tracker
from googlecloudsdk.core.updater import local_state
from googlecloudsdk.core.updater import update_manager
from googlecloudsdk.core.util import platforms
import six
# Extract stage messages to constants for convenience.
SCAN_MESSAGE = 'Scanning container image'
EXTRACT_MESSAGE = ('Locally extracting packages and versions from {} '
'container image')
RPC_MESSAGE = 'Remotely initiating analysis of packages and versions'
POLL_MESSAGE = 'Waiting for analysis operation to complete'
# Error messages used to fill in for unknown error cases.
EXTRACTION_KILLED_ERROR_TEMPLATE = (
'Extraction failed: image extraction was either stopped or crashed '
'(possibly due to a lack of available memory) with exit code '
'{exit_code}')
UNKNOWN_EXTRACTION_ERROR_TEMPLATE = (
'Extraction failed: unknown error (exit code: {exit_code})')
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ScanBeta(base.Command):
"""Perform a vulnerability scan on a container image.
You can scan a container image in a Google Cloud registry (Artifact Registry
or Container Registry), or a local container image.
Reference an image by tag or digest using any of the formats:
Artifact Registry:
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE[:tag]
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE@sha256:digest
Container Registry:
[LOCATION.]gcr.io/PROJECT-ID/REPOSITORY-ID/IMAGE[:tag]
[LOCATION.]gcr.io/PROJECT-ID/REPOSITORY-ID/IMAGE@sha256:digest
Local:
IMAGE[:tag]
"""
detailed_help = {
'DESCRIPTION':
'{description}',
'EXAMPLES':
"""\
Start a scan of a container image stored in Artifact Registry:
$ {command} us-west1-docker.pkg.dev/my-project/my-repository/busy-box@sha256:abcxyz --remote
Start a scan of a container image stored in the Container Registry, and perform the analysis in Europe:
$ {command} eu.gcr.io/my-project/my-repository/my-image:latest --remote --location=europe
Start a scan of a container image stored locally, and perform the analysis in Asia:
$ {command} ubuntu:latest --location=asia
"""
}
@staticmethod
def Args(parser):
flags.GetResourceURIArg().AddToParser(parser)
flags.GetRemoteFlag().AddToParser(parser)
flags.GetOnDemandScanningFakeExtractionFlag().AddToParser(parser)
flags.GetOnDemandScanningLocationFlag().AddToParser(parser)
flags.GetAdditionalPackageTypesFlag().AddToParser(parser)
flags.GetExperimentalPackageTypesFlag().AddToParser(parser)
flags.GetSkipPackageTypesFlag().AddToParser(parser)
flags.GetVerboseErrorsFlag().AddToParser(parser)
base.ASYNC_FLAG.AddToParser(parser)
def Run(self, args):
"""Runs local extraction then calls ODS with the results.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
AnalyzePackages operation.
Raises:
UnsupportedOS: when the command is run on a Windows machine.
"""
if platforms.OperatingSystem.IsWindows():
raise ods_util.UnsupportedOS(
'On-Demand Scanning is not supported on Windows')
# Verify that the local-extract component is installed, and prompt the user
# to install it if it's not.
try:
# If the user has access to the gcloud components manager, this will
# prompt the user to install it. If they do not have access, it will
# instead print the command to install it using a package manager.
update_manager.UpdateManager.EnsureInstalledAndRestart(['local-extract'])
except update_manager.MissingRequiredComponentsError:
# Two possibilities with this error:
# 1. The user has access to the gcloud components manager but decided
# against intalling it.
# 2. The user does not have access to the gcloud components manager. A
# message was printed to the user with the command to install the
# component using their package manager (e.g. apt-get).
raise
except local_state.InvalidSDKRootError:
# This happens when gcloud is run locally, but not when distributed.
pass
# Construct the object which invokes the `local-extract` component. This
# might still fail if the binary is run locally.
cmd = Command()
# TODO(b/173619679): Validate RESOURCE_URI argument.
# Dynamically construct the stages based on the --async flag; when
# --async=true, we do not need a separate poll stage.
stages = [
progress_tracker.Stage(
EXTRACT_MESSAGE.format('remote' if args.remote else 'local'),
key='extract'),
progress_tracker.Stage(RPC_MESSAGE, key='rpc')
]
if not args.async_:
stages += [progress_tracker.Stage(POLL_MESSAGE, key='poll')]
messages = self.GetMessages()
with progress_tracker.StagedProgressTracker(
SCAN_MESSAGE, stages=stages) as tracker:
# Stage 1) Extract.
tracker.StartStage('extract')
operation_result = cmd(
resource_uri=args.RESOURCE_URI,
remote=args.remote,
fake_extraction=args.fake_extraction,
additional_package_types=args.additional_package_types,
experimental_package_types=args.experimental_package_types,
skip_package_types=args.skip_package_types,
verbose_errors=args.verbose_errors,
)
if operation_result.exit_code:
# Filter out any log messages on std err and only include any actual
# extraction errors.
extraction_error = None
if operation_result.stderr:
extraction_error = '\n'.join([
line for line in operation_result.stderr.splitlines()
if line.startswith('Extraction failed')
])
if not extraction_error:
if operation_result.exit_code < 0:
extraction_error = EXTRACTION_KILLED_ERROR_TEMPLATE.format(
exit_code=operation_result.exit_code,)
else:
extraction_error = UNKNOWN_EXTRACTION_ERROR_TEMPLATE.format(
exit_code=operation_result.exit_code,)
tracker.FailStage('extract',
ods_util.ExtractionFailedError(extraction_error))
return
# Parse stdout for the JSON-ified PackageData protos.
pkgs = []
for pkg in json.loads(operation_result.stdout):
pkg_data = messages.PackageData(
package=pkg['package'],
version=pkg['version'],
cpeUri=pkg['cpe_uri'],
)
if 'package_type' in pkg:
pkg_data.packageType = arg_utils.ChoiceToEnum(
pkg['package_type'],
messages.PackageData.PackageTypeValueValuesEnum)
if 'hash_digest' in pkg:
pkg_data.hashDigest = pkg['hash_digest']
pkgs += [pkg_data]
tracker.CompleteStage('extract')
# Stage 2) Make the RPC to the On-Demand Scanning API.
tracker.StartStage('rpc')
op = self.AnalyzePackages(args, pkgs)
tracker.CompleteStage('rpc')
# Stage 3) Poll the operation if requested.
response = None
if not args.async_:
tracker.StartStage('poll')
tracker.UpdateStage('poll', '[{}]'.format(op.name))
response = self.WaitForOperation(op)
tracker.CompleteStage('poll')
if args.async_:
log.status.Print('Check operation [{}] for status.'.format(op.name))
return op
return response
def AnalyzePackages(self, args, pkgs):
return api_util.AnalyzePackagesBeta(
properties.VALUES.core.project.Get(required=True),
args.location,
args.RESOURCE_URI,
pkgs)
def GetMessages(self):
return api_util.GetMessages('v1beta1')
def WaitForOperation(self, op):
return ods_util.WaitForOperation(op, 'v1beta1')
@base.ReleaseTracks(base.ReleaseTrack.GA)
class ScanGA(ScanBeta):
"""Perform a vulnerability scan on a container image.
You can scan a container image in a Google Cloud registry (Artifact Registry
or Container Registry), or a local container image.
Reference an image by tag or digest using any of the formats:
Artifact Registry:
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE[:tag]
LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY-ID/IMAGE@sha256:digest
Container Registry:
[LOCATION.]gcr.io/PROJECT-ID/REPOSITORY-ID/IMAGE[:tag]
[LOCATION.]gcr.io/PROJECT-ID/REPOSITORY-ID/IMAGE@sha256:digest
Local:
IMAGE[:tag]
"""
def AnalyzePackages(self, args, pkgs):
return api_util.AnalyzePackagesGA(
properties.VALUES.core.project.Get(required=True),
args.location,
args.RESOURCE_URI,
pkgs)
def GetMessages(self):
return api_util.GetMessages('v1')
def WaitForOperation(self, op):
return ods_util.WaitForOperation(op, 'v1')
class Command(binary_operations.BinaryBackedOperation):
"""Wrapper for call to the Go binary."""
def __init__(self, **kwargs):
super(Command, self).__init__(binary='local-extract', **kwargs)
def _ParseArgsForCommand(
self,
resource_uri,
remote,
fake_extraction,
additional_package_types,
experimental_package_types,
skip_package_types,
verbose_errors,
**kwargs
):
args = [
'--resource_uri=' + resource_uri,
'--remote=' + six.text_type(remote),
'--provide_fake_results=' + six.text_type(fake_extraction),
# Due to backwards compatibility issues between the gcloud command and
# the local-extract binary, provide a list of all flags to --undefok
# which were introduced after the first launch. In this way, new
# versions of the command can invoke old versions of the binary.
'--undefok='
+ ','.join([
'additional_package_types',
'skip_package_types',
'verbose_errors',
'use_scalibr',
]),
]
package_types = []
if additional_package_types:
package_types += additional_package_types
if experimental_package_types:
package_types += experimental_package_types
if package_types:
args.append('--additional_package_types=' +
six.text_type(','.join(package_types)))
if skip_package_types:
args.append(
'--skip_package_types=' + six.text_type(','.join(skip_package_types))
)
if verbose_errors:
args.append('--verbose_errors=' + six.text_type(verbose_errors))
args.append('--use_scalibr')
return args