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,61 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The command group for the shell CLI."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import textwrap
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA)
@base.DefaultUniverseOnly
class CloudShell(base.Group):
"""Manage Google Cloud Shell."""
category = base.MANAGEMENT_TOOLS_CATEGORY
detailed_help = {
'DESCRIPTION':
"""\
Interact with and connect to your Cloud Shell environment.
More information on Cloud Shell can be found at
https://cloud.google.com/shell/docs/.
""",
'NOTES':
textwrap.dedent("""\
The previous *gcloud alpha shell* command to launch an interactive
shell was renamed to *gcloud alpha interactive*.
"""),
}
@staticmethod
def Args(parser):
pass
def Filter(self, context, args):
# TODO(b/190528585): Determine if command group works with project number
base.RequireProjectID(args)
del context, args
# Intentionally disable the user project override. Cloud Shell is inteded
# to be able to be used without first creating a GCP project.
# Additionally, Cloud Shell is a free product with per user quota, so
# enabling the API on gcloud will not cost gcloud money.
base.DisableUserProjectQuota()

View File

@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""cloud-shell get-mount-command command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from argcomplete.completers import FilesCompleter
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.cloud_shell import util
from googlecloudsdk.core import log
from googlecloudsdk.core.util import platforms
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA)
class GetMountCommand(base.Command):
"""Prints a command to mount the Cloud Shell home directory via sshfs."""
detailed_help = {
'DESCRIPTION':
"""\
*{command}* starts your Cloud Shell if it is not already running, then
prints out a command that allows you to mount the Cloud Shell home
directory onto your local file system using *sshfs*. You must install
and run sshfs yourself.
After mounting the Cloud Shell home directory, any changes you make
under the mount point on your local file system will be reflected in
Cloud Shell and vice-versa.
""",
'EXAMPLES':
"""\
To print a command that mounts a remote directory onto your local file
system, run:
$ {command} REMOTE-DIR
""",
}
@staticmethod
def Args(parser):
util.ParseCommonArgs(parser)
parser.add_argument(
'mount_dir',
completer=FilesCompleter,
help="""\
Local directory onto which the Cloud Shell home directory should be
mounted.
""")
def Run(self, args):
if platforms.OperatingSystem.IsWindows():
raise util.UnsupportedPlatform(
'get-mount-command is not currently supported on Windows')
else:
connection_info = util.PrepareEnvironment(args)
log.Print('sshfs {user}@{host}: {mount_dir} -p {port} '
'-oIdentityFile={key_file} -oStrictHostKeyChecking=no'.format(
user=connection_info.user,
host=connection_info.host,
mount_dir=args.mount_dir,
port=connection_info.port,
key_file=connection_info.key,
))

View File

@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""cloud-shell scp command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.cloud_shell import util
from googlecloudsdk.command_lib.util.ssh import ssh
from googlecloudsdk.core import log
import six
FILE_TYPE = arg_parsers.RegexpValidator(
r'^(cloudshell|localhost):.*$', 'must start with cloudshell: or localhost:')
def ToFileReference(path, remote):
if path.startswith('cloudshell:'):
return ssh.FileReference.FromPath(
path.replace('cloudshell', six.text_type(remote), 1))
elif path.startswith('localhost:'):
return ssh.FileReference.FromPath(path.replace('localhost:', '', 1))
else:
raise Exception('invalid path: ' + path)
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA,
base.ReleaseTrack.ALPHA)
class Scp(base.Command):
"""Copies files between Cloud Shell and the local machine."""
detailed_help = {
'DESCRIPTION':
"""\
*{command}* copies files between your Cloud Shell instance and your
local machine using the scp command.
""",
'EXAMPLES':
"""\
To denote a file in Cloud Shell, prefix the file name with the string
"cloudshell:" (e.g. _cloudshell:_~/_FILE_). To denote a local file,
prefix the file name with the string "localhost:" (e.g.
_localhost:_~/_FILE_). For example, to copy a remote directory to your
local machine, run:
$ {command} cloudshell:~/REMOTE-DIR localhost:~/LOCAL-DIR
In the above example, *_~/REMOTE-DIR_* from your Cloud Shell instance is
copied into the ~/_LOCAL-DIR_ directory.
Conversely, files from your local computer can be copied into Cloud
Shell:
$ {command} localhost:~/LOCAL-FILE-1 localhost:~/LOCAL-FILE-2 \
cloudshell:~/REMOTE-DIR
Under the covers, *scp(1)* or pscp (on Windows) is used to facilitate
the transfer.
""",
}
@staticmethod
def Args(parser):
util.ParseCommonArgs(parser)
parser.add_argument(
'sources',
help='Specifies the files to copy.',
type=FILE_TYPE,
metavar='(cloudshell|localhost):SRC',
nargs='+')
parser.add_argument(
'destination',
help='Specifies a destination for the source files.',
type=FILE_TYPE,
metavar='(cloudshell|localhost):DEST')
parser.add_argument(
'--dry-run',
help="""\
If provided, prints the command that would be run to standard out
instead of executing it.
""",
action='store_true')
parser.add_argument(
'--recurse',
help='Upload directories recursively.',
action='store_true')
parser.add_argument(
'--scp-flag',
help='Extra flag to be sent to scp. This flag may be repeated.',
action='append')
def Run(self, args):
connection_info = util.PrepareEnvironment(args)
remote = ssh.Remote(host=connection_info.host, user=connection_info.user)
command = ssh.SCPCommand(
sources=[ToFileReference(src, remote) for src in args.sources],
destination=ToFileReference(args.destination, remote),
recursive=args.recurse,
compress=False,
port=str(connection_info.port),
identity_file=connection_info.key,
extra_flags=args.scp_flag,
options={'StrictHostKeyChecking': 'no'},
)
if args.dry_run:
log.Print(' '.join(command.Build(connection_info.ssh_env)))
else:
command.Run(connection_info.ssh_env)

View File

@@ -0,0 +1,223 @@
# -*- coding: utf-8 -*- #
# Copyright 2018 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""cloud-shell ssh command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import datetime
import threading
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.cloud_shell import util
from googlecloudsdk.command_lib.util.ssh import ssh
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
import six
@base.ReleaseTracks(base.ReleaseTrack.GA, base.ReleaseTrack.BETA)
class Ssh(base.Command):
"""Allows you to establish an interactive SSH session with Cloud Shell."""
detailed_help = {
'DESCRIPTION':
"""\
*{command}* lets you remotely log in to Cloud Shell. If your Cloud Shell
is not currently running, this will cause it to be started before
establishing the SSH session.
""",
'EXAMPLES':
"""\
To SSH into your Cloud Shell, run:
$ {command}
To run a remote command in your Cloud Shell, run:
$ {command} --command=ls
""",
}
@staticmethod
def Args(parser):
util.ParseCommonArgs(parser)
parser.add_argument(
'--command',
help="""\
A command to run in Cloud Shell.
Runs the command in Cloud Shell and then exits.
""")
parser.add_argument(
'--dry-run',
help="""\
If provided, prints the command that would be run to standard out
instead of executing it.
""",
action='store_true')
parser.add_argument(
'--ssh-flag',
help='Additional flags to be passed to *ssh(1)*.',
action='append')
parser.add_argument(
'--authorize-session',
help="""\
If provided, sends OAuth credentials to the current Cloud Shell session
on behalf of the user. When this completes, the session will be
authorized to run various Google Cloud command-line tools without
requiring the user to manually authenticate.
""",
action='store_true')
def Run(self, args):
if not args.authorize_session:
log.Print('Automatic authentication with GCP CLI tools in Cloud Shell is '
'disabled. To enable, please rerun command with '
'`--authorize-session` flag.')
command_list = args.command.split(' ') if args.command else ['bash -l']
project = properties.VALUES.core.project.Get()
connection_info = util.PrepareEnvironment(args)
if args.authorize_session:
util.AuthorizeEnvironment()
command = ssh.SSHCommand(
remote=ssh.Remote(host=connection_info.host, user=connection_info.user),
port=six.text_type(connection_info.port),
identity_file=connection_info.key,
remote_command=(['DEVSHELL_PROJECT_ID=' + project] if project else []) +
command_list,
extra_flags=args.ssh_flag,
tty=not args.command,
options={'StrictHostKeyChecking': 'no'},
)
if args.dry_run:
elems = command.Build(connection_info.ssh_env)
log.Print(' '.join([six.moves.shlex_quote(elem) for elem in elems]))
elif args.authorize_session:
self.done = threading.Event()
thread = threading.Thread(target=self.Reauthorize, args=())
thread.daemon = True
thread.start()
command.Run(connection_info.ssh_env)
self.done.set()
else:
command.Run(connection_info.ssh_env)
def Reauthorize(self):
while not self.done.is_set():
self.done.wait(
(util.MIN_CREDS_EXPIRY - datetime.timedelta(minutes=2)).seconds)
if not self.done.is_set():
util.AuthorizeEnvironment()
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class SshAlpha(base.Command):
"""Allows you to establish an interactive SSH session with Cloud Shell."""
detailed_help = {
'DESCRIPTION':
"""\
*{command}* lets you remotely log in to Cloud Shell. If your Cloud Shell
is not currently running, this will cause it to be started before
establishing the SSH session.
""",
'EXAMPLES':
"""\
To SSH into your Cloud Shell, run:
$ {command}
To run a remote command in your Cloud Shell, run:
$ {command} --command=ls
""",
}
@staticmethod
def Args(parser):
util.ParseCommonArgs(parser)
util.AddSshArgFlag(parser)
parser.add_argument(
'--command',
help="""\
A command to run in Cloud Shell.
Runs the command in Cloud Shell and then exits.
""")
parser.add_argument(
'--dry-run',
help="""\
If provided, prints the command that would be run to standard out
instead of executing it.
""",
action='store_true')
parser.add_argument(
'--ssh-flag',
help='Additional flags to be passed to *ssh(1)*.',
action='append')
parser.add_argument(
'--authorize-session',
help="""\
If provided, sends OAuth credentials to the current Cloud Shell session
on behalf of the user. When this completes, the session will be
authorized to run various Google Cloud command-line tools without
requiring the user to manually authenticate.
""",
action='store_true')
def Run(self, args):
if not args.authorize_session:
log.Print(
'Automatic authentication with GCP CLI tools in Cloud Shell is '
'disabled. To enable, please rerun command with '
'`--authorize-session` flag.')
command_list = args.command.split(' ') if args.command else ['bash -l']
project = properties.VALUES.core.project.Get()
connection_info = util.PrepareEnvironment(args)
if args.authorize_session:
util.AuthorizeEnvironment()
command = ssh.SSHCommand(
remote=ssh.Remote(host=connection_info.host, user=connection_info.user),
port=six.text_type(connection_info.port),
identity_file=connection_info.key,
remote_command=(['DEVSHELL_PROJECT_ID=' + project]
if project else []) + command_list,
extra_flags=args.ssh_flag,
tty=not args.command,
options={'StrictHostKeyChecking': 'no'},
remainder=args.ssh_args if args.ssh_args else None
)
if args.dry_run:
elems = command.Build(connection_info.ssh_env)
log.Print(' '.join([six.moves.shlex_quote(elem) for elem in elems]))
elif args.authorize_session:
self.done = threading.Event()
thread = threading.Thread(target=self.Reauthorize, args=())
thread.daemon = True
thread.start()
command.Run(connection_info.ssh_env)
self.done.set()
else:
command.Run(connection_info.ssh_env)
def Reauthorize(self):
while not self.done.is_set():
self.done.wait(
(util.MIN_CREDS_EXPIRY - datetime.timedelta(minutes=2)).seconds)
if not self.done.is_set():
util.AuthorizeEnvironment()