File: //snap/google-cloud-cli/current/lib/googlecloudsdk/command_lib/anthos/flags.py
# -*- coding: utf-8 -*- #
# Copyright 2019 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 line flags for Anthos commands."""
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.core.util import files
_MERGE_STRATEGIES = {
'resource-merge': ('perform a structural comparison of the '
'original/updated Resources, and merge the changes '
'into the local package.'),
'fast-forward': ('fail without updating if the local package was modified'
' since it was fetched.'),
'alpha-git-patch': ("use 'git format-patch' and 'git am' to apply a patch "
'of the changes between the source version and '
'destination version. Requires the local package to '
'have been committed to a local git repo.'),
'force-delete-replace': ('This will wipe all local changes to the package. '
'Deletes the contents of local package from '
'PACKAGE_DIR and replace them with the remote '),
}
def GetFlagOrPositional(name, positional=False, **kwargs):
"""Return argument called name as either flag or positional."""
dest = name.replace('-', '_').upper()
if positional:
flag = dest
kwargs.pop('required', None)
else:
flag = '--{}'.format(name.replace('_', '-').lower())
if not positional:
kwargs['dest'] = dest
return base.Argument(flag, **kwargs)
def GetRepoURIFlag(positional=True,
required=True,
help_override=None,
metavar=None):
"""Get REPO_URI flag."""
help_txt = help_override or """\
Git repository URI containing 1 or more packages as where:
* REPO_URI - URI of a git repository containing 1 or more packages as
subdirectories. In most cases the .git suffix should be specified to
delimit the REPO_URI from the PKG_PATH, but this is not required for
widely recognized repo prefixes. If REPO_URI cannot be parsed then
an error will be printed an asking for '.git' to be specified
as part of the argument. e.g. https://github.com/kubernetes/examples.git
* PKG_PATH (optional) - Path to Git subdirectory containing Anthos package files.
Uses '/' as the path separator (regardless of OS). e.g. staging/cockroachdb.
Defaults to the root directory.
* GIT_REF (optional)- A git tag, branch, ref or commit for the remote version of the
package to fetch. Defaults to the repository default branch e.g. @main
"""
if not metavar:
metavar = 'REPO_URI[.git]/[PKG_PATH][@GIT_REF]'
return GetFlagOrPositional(
name='repo_uri',
positional=positional,
required=required,
help=help_txt,
metavar=metavar)
def GetPackagePathFlag(metavar=None):
return GetFlagOrPositional(
name='package_path',
positional=False,
required=False,
help="""\
Path to remote subdirectory containing Kubernetes Resource configuration
files or directories.
Defaults to the root directory.
Uses '/' as the path separator (regardless of OS).
e.g. staging/cockroachdb
""",
metavar=metavar)
def GetLocalDirFlag(positional=True,
required=True,
help_override=None,
metavar=None):
"""Get Local Package directory flag."""
help_txt = help_override or """\
The local directory to fetch the package to.
e.g. ./my-cockroachdb-copy
* If the directory does NOT exist: create the specified directory
and write the package contents to it
* If the directory DOES exist: create a NEW directory under the
specified one, defaulting the name to the Base of REPO/PKG_PATH
* If the directory DOES exist and already contains a directory with
the same name of the one that would be created: fail
"""
return GetFlagOrPositional(
name='LOCAL_DIR',
positional=positional,
required=required,
type=ExpandLocalDirAndVersion,
help=help_txt,
metavar=metavar)
def GetFilePatternFlag():
return GetFlagOrPositional(
name='pattern',
positional=False,
required=False,
help="""\
Pattern to use for writing files. May contain the following formatting
verbs %n: metadata.name, %s: metadata.namespace, %k: kind
(default "%n_%k.yaml")
""")
def GetStrategyFlag():
return base.Argument(
'--strategy',
required=False,
choices=_MERGE_STRATEGIES,
help='Controls how changes to the local package are handled.')
def GetDryRunFlag(help_override=None):
help_txt = help_override or ('If true and command fails print the '
'underlying command that was executed and '
'its exit status.')
return base.Argument(
'--dry-run', action='store_true', required=False, help=help_txt)
def GetDescriptionFlag():
return base.Argument(
'--description', required=False, help='Description of the Package.')
def GetNameFlag():
return base.Argument('--name', required=False, help='Name of the package.')
def GetTagsFlag():
return base.Argument(
'--tags',
required=False,
type=arg_parsers.ArgDict(),
metavar='TAG=VALUE',
help='Tags for the package.')
def GetInfoUrlFlag():
return base.Argument(
'--info-url',
required=False,
help='Url with more info about the package.')
def ExpandLocalDirAndVersion(directory):
"""Expand HOME relative (~) directory with optional git_ref.
Args:
directory: str, directory path in the format PATH[/][@git_ref].
Returns:
str, expanded full directory path with git_ref (if provided)
"""
path = directory.split('@') if directory else ''
full_dir = files.ExpandHomeDir(path[0])
if len(path) == 2:
full_dir += '@' + path[1]
return full_dir
# Anthos Auth
def GetClusterFlag(positional=False,
required=False,
help_override=None,
metavar=None):
"""Anthos operation cluster name flag."""
help_txt = help_override or ('Cluster to authenticate against. If no cluster '
'is specified, the command will print a list '
'of available options.')
return GetFlagOrPositional(
name='CLUSTER',
positional=positional,
required=required,
help=help_txt,
metavar=metavar)
def GetLoginConfigFlag():
return base.Argument(
'--login-config',
required=False,
help='Specifies the configuration yaml '
'file for login. Can be a file path or a URL.')
def GetLoginConfigCertFlag():
return base.Argument(
'--login-config-cert',
required=False,
type=ExpandLocalDirAndVersion,
help='Specifies the CA certificate file to be added to trusted pool '
'for making HTTPS connections to a `--login-config` URL.')
def GetUserFlag():
return base.Argument(
'--user',
required=False,
help='If configuring multiple user accounts in the same kubecconfig '
'file, you can specify a user to differentiate between them.')
def GetSetPreferredAuthenticationFlag():
return base.Argument(
'--set-preferred-auth',
required=False,
action='store_true',
help='If set, forces update of preferred '
'authentication for given cluster')
def GetServerFlag():
return base.Argument(
'--server',
required=False,
help=(
'Specifies the URL of API server of the cluster to authenticate'
' against.'
),
)
def GetOutputDirFlag(positional=False,
required=False,
help_override=None,
metavar='OUTPUT-DIR',
default=None):
"""Anthos operation local output directory flag."""
help_txt = help_override or ('The output directory of the cluster resources.'
' If empty will export files to ./CLUSTER_NAME')
return GetFlagOrPositional(
name='OUTPUT_DIRECTORY',
positional=positional,
required=required,
type=ExpandLocalDirAndVersion,
help=help_txt,
default=default,
metavar=metavar)
def GetLocationFlag():
"""Anthos location flag."""
return base.Argument(
'--location',
required=False,
help='Specifies the Google Cloud location to use. If not'
'specified will use the current compute/zone property.')
def GetMergeFromFlag():
"""Anthos create-login-config Merge-From flag."""
return base.Argument(
'--merge-from',
required=False,
help='Specifies the file path of an existing login '
'configuration file to merge with.')
def GetConfigOutputFileFlag():
"""Anthos create-login-config output flag."""
return base.Argument(
'--output',
required=False,
type=ExpandLocalDirAndVersion,
help='Destination to write login configuration file. '
'Defaults to "kubectl-anthos-config.yaml".')
# Anthos auth token flags.
def GetTypeFlag():
"""Anthos auth token type flag, specifies the type of token to be created."""
return base.ChoiceArgument(
'--type',
required=True,
choices=['aws', 'oidc'],
help_str='Type of token to be created.')
def GetAwsStsRegionFlag():
"""Anthos auth token aws-sts-region flag, specifies the region for AWS STS endpoint for creating AWS token."""
return base.Argument(
'--aws-sts-region', required=False, help='Region for AWS STS endpoint.')
def GetTokenClusterFlag():
"""Anthos auth token cluster flag, specifies cluster name for creating AWS token."""
return base.Argument(
'--cluster',
required=False,
help='Name of the cluster for which token is created.')
def GetIdTokenFlag():
"""Anthos auth token id-token flag, specifies the ID Token received from identity provider after authorization flow."""
return base.Argument(
'--id-token',
required=False,
help='ID Token received from identity provider after authorization flow.')
def GetAccessTokenFlag():
"""Anthos auth token access-token flag, specifies the Access Token received from identity provider after authorization flow."""
return base.Argument(
'--access-token',
required=False,
help=(
'Access Token received from identity provider after authorization'
' flow.'
),
)
def GetAccessTokenExpiryFlag():
"""Anthos auth token access-token-expiry flag, specifies the Expiration time of access token received from identity provider after authorization flow."""
return base.Argument(
'--access-token-expiry',
required=False,
help=(
'Expiration time of access token received from identity provider'
' after authorization flow. The expected format is the number of'
' seconds elapsed since January 1, 1970 UTC.'
),
)
def GetRefreshTokenFlag():
"""Anthos auth token refresh-token flag, specifies the Refresh Token received from identity provider after authorization flow."""
return base.Argument(
'--refresh-token',
required=False,
help=(
'Refresh Token received from identity provider after authorization'
' flow.'
),
)
def GetClientIdFlag():
"""Anthos auth token client-id flag, specifies the ClientID is the id for OIDC client application."""
return base.Argument(
'--client-id',
required=False,
help='ClientID is the id for OIDC client application.')
def GetClientSecretFlag():
"""Anthos auth token client-secret flag, specifies the Client Secret is the shared secret between OIDC client application and OIDC provider."""
return base.Argument(
'--client-secret',
required=False,
help=(
'Client Secret is the shared secret between OIDC client application'
' and OIDC provider.'
),
)
def GetIdpCertificateAuthorityDataFlag():
"""Anthos auth token idp-certificate-authority-data flag, specifies the PEM-encoded certificate authority certificate for OIDC provider."""
return base.Argument(
'--idp-certificate-authority-data',
required=False,
help='PEM-encoded certificate authority certificate for OIDC provider.')
def GetIdpIssuerUrlFlag():
"""Anthos auth token idp-issuer-url flag, specifies the URI for the OIDC provider."""
return base.Argument(
'--idp-issuer-url',
required=False,
help=(
'URI for the OIDC provider. This URI should point to the level below'
' .well-known/openid-configuration.'
),
)
def GetKubeconfigPathFlag():
"""Anthos auth token kubeconfig-path flag, specifies the Path to the kubeconfig path that would be updated with ID and access token on expiry."""
return base.Argument(
'--kubeconfig-path',
required=False,
help=(
'Path to the kubeconfig path that would be updated with ID and access'
' token on expiry.'
),
)
def GetTokenUserFlag():
"""Anthos auth token user flag, specifies the User used in kubeconfig."""
return base.Argument(
'--user', required=False, help='User used in kubeconfig.'
)
def GetNoBrowserFlag():
"""Used to start authentication on a device without a browser in order to perform login on a second device with browser."""
return base.Argument(
'--no-browser',
action='store_true',
required=False,
help=(
'Option to indicate login completion on a second device with browser.'
'Used with `server` option.'
),
)
def GetRemoteBootstrapFlag():
"""Used to complete authentication that was started on a remote device without a browser, on the current device with a browser."""
return base.Argument(
'--remote-bootstrap',
required=False,
help=(
'Option to complete login that was started using `no-browser` option'
'on a remote device that does not have a browser.'
),
)