def GetCluster(self, cluster_ref): """Get a running cluster. Args: cluster_ref: cluster Resource to describe. Returns: Cluster message. Raises: Error: if cluster cannot be found. """ try: return self.client.projects_zones_clusters.Get(cluster_ref.Request()) except apitools_exceptions.HttpError as error: api_error = util.GetError(error) if api_error.code != 404: raise api_error # Cluster couldn't be found, maybe user got zone wrong? try: clusters = self.ListClusters(cluster_ref.projectId).clusters except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error)) for cluster in clusters: if cluster.name == cluster_ref.clusterId: # User likely got zone wrong. raise util.Error(WRONG_ZONE_ERROR_MSG.format( error=api_error, name=cluster_ref.clusterId, wrong_zone=self.Zone(cluster_ref), zone=cluster.zone)) # Couldn't find a cluster with that name. raise util.Error(NO_SUCH_CLUSTER_ERROR_MSG.format( error=api_error, name=cluster_ref.clusterId, project=cluster_ref.projectId))
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] cluster_refs = [] for name in args.names: cluster_refs.append(adapter.ParseCluster(name)) console_io.PromptContinue( message=util.ConstructList( 'The following clusters will be deleted.', ['[{name}] in [{zone}]'.format(name=ref.clusterId, zone=adapter.Zone(ref)) for ref in cluster_refs]), throw_if_unattended=True, cancel_on_no=True) operations = [] errors = [] # Issue all deletes first for cluster_ref in cluster_refs: try: # Make sure it exists (will raise appropriate error if not) adapter.GetCluster(cluster_ref) op_ref = adapter.DeleteCluster(cluster_ref) operations.append((op_ref, cluster_ref)) except exceptions.HttpError as error: errors.append(util.GetError(error)) except util.Error as error: errors.append(error) if not flags.GetAsyncValueFromAsyncAndWaitFlags(args.async, args.wait): # Poll each operation for completion for operation_ref, cluster_ref in operations: try: adapter.WaitForOperation( operation_ref, 'Deleting cluster {0}'.format(cluster_ref.clusterId), timeout_s=args.timeout) # Purge cached config files util.ClusterConfig.Purge(cluster_ref.clusterId, adapter.Zone(cluster_ref), cluster_ref.projectId) if properties.VALUES.container.cluster.Get() == cluster_ref.clusterId: properties.PersistProperty( properties.VALUES.container.cluster, None) log.DeletedResource(cluster_ref) except exceptions.HttpError as error: errors.append(util.GetError(error)) except util.Error as error: errors.append(error)
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] cluster_ref = adapter.ParseCluster(args.name) # Make sure it exists (will raise appropriate error if not) adapter.GetCluster(cluster_ref) options = api_adapter.UpdateClusterOptions( monitoring_service=args.monitoring_service, disable_addons=args.disable_addons) try: op_ref = adapter.UpdateCluster(cluster_ref, options) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error)) if args.wait: adapter.WaitForOperation( op_ref, 'Updating {0}'.format(cluster_ref.clusterId)) log.UpdatedResource(cluster_ref)
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] location_get = self.context['location_get'] location = location_get(args) op_ref = adapter.ParseOperation(args.operation_id, location) try: op = adapter.GetOperation(op_ref) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error)) console_io.PromptContinue( message='Are you sure you want to cancel operation {0}?'.format( op.name), throw_if_unattended=True, cancel_on_no=True) try: adapter.CancelOperation(op_ref) log.status.Print( CANCEL_OPERATION_MESSAGE.format(args.operation_id, args.operation_id)) return adapter.GetOperation(op_ref) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(error)
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] cluster_ref = adapter.ParseCluster(args.name) # Make sure it exists (will raise appropriate error if not) cluster = adapter.GetCluster(cluster_ref) options = api_adapter.UpdateClusterOptions( version=args.cluster_version, update_master=args.master, update_nodes=(not args.master), node_pool=args.node_pool, image_family=args.image_family) if options.version: new_version = options.version else: new_version = 'latest' if args.master: node_message = 'Master' current_version = cluster.currentMasterVersion else: node_message = 'All {node_count} nodes'.format( node_count=cluster.currentNodeCount) current_version = cluster.currentNodeVersion console_io.PromptContinue( message= '{node_message} of cluster [{cluster_name}] will be upgraded ' 'from version [{current_version}] to version [{new_version}]. ' 'This operation is long-running and will block other operations ' 'on the cluster (including delete) until it has run to completion.' .format(node_message=node_message, cluster_name=cluster.name, current_version=current_version, new_version=new_version), throw_if_unattended=True, cancel_on_no=True) try: op_ref = adapter.UpdateCluster(cluster_ref, options) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error)) if args.wait: adapter.WaitForOperation( op_ref, 'Upgrading {0}'.format(cluster_ref.clusterId)) log.UpdatedResource(cluster_ref)
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] project = properties.VALUES.core.project.Get(required=True) zone = None if args.zone: zone = adapter.registry.Parse(args.zone, collection='compute.zones').zone def sort_key(cluster): return (cluster.zone, cluster.name) try: clusters = adapter.ListClusters(project, zone) clusters.clusters = sorted(clusters.clusters, key=sort_key) if clusters.missingZones: log.warning( 'The following zones did not respond: {0}. List results may be ' 'incomplete.'.format(', '.join(clusters.missingZones))) upgrade_available = False support_ending = False unsupported = False self._upgrade_hint = '' vv = VersionVerifier() for c in clusters.clusters: ver_status = vv.Compare(c.currentMasterVersion, c.currentNodeVersion) if ver_status == VersionVerifier.UPGRADE_AVAILABLE: c.currentNodeVersion += ' *' upgrade_available = True elif ver_status == VersionVerifier.SUPPORT_ENDING: c.currentNodeVersion += ' **' support_ending = True elif ver_status == VersionVerifier.UNSUPPORTED: c.currentNodeVersion += ' ***' unsupported = True if upgrade_available: self._upgrade_hint += UpgradeHelpText.UPGRADE_AVAILABLE if support_ending: self._upgrade_hint += UpgradeHelpText.SUPPORT_ENDING if unsupported: self._upgrade_hint += UpgradeHelpText.UNSUPPORTED if self._upgrade_hint: self._upgrade_hint += UpgradeHelpText.UPGRADE_COMMAND.format( name='NAME') return clusters.clusters except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error))
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: Cluster message for the successfully created node pool. Raises: util.Error, if creation failed. """ adapter = self.context['api_adapter'] if not args.scopes: args.scopes = [] try: if not args.scopes: args.scopes = [] pool_ref = adapter.ParseNodePool(args.name) options = self.ParseCreateNodePoolOptions(args) operation_ref = adapter.CreateNodePool(pool_ref, options) adapter.WaitForOperation(operation_ref, 'Creating node pool {0}'.format( pool_ref.nodePoolId), timeout_s=args.timeout) pool = adapter.GetNodePool(pool_ref) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error)) log.CreatedResource(pool_ref) return pool
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: Cluster message for the successfully created cluster. Raises: util.Error, if creation failed. """ util.CheckKubectlInstalled() if not args.password: args.password = ''.join( random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16)) adapter = self.context['api_adapter'] if not args.scopes: args.scopes = [] cluster_ref = adapter.ParseCluster(args.name) options = self.ParseCreateOptions(args) try: operation_ref = adapter.CreateCluster(cluster_ref, options) if not args.wait: return adapter.GetCluster(cluster_ref) adapter.WaitForOperation(operation_ref, 'Creating cluster {0}'.format( cluster_ref.clusterId), timeout_s=args.timeout) cluster = adapter.GetCluster(cluster_ref) except apitools_base.HttpError as error: raise exceptions.HttpException(util.GetError(error)) log.CreatedResource(cluster_ref) # Persist cluster config current_context = kconfig.Kubeconfig.Default().current_context c_config = util.ClusterConfig.Persist(cluster, cluster_ref.projectId, self.cli) if not c_config.has_certs: # Purge config so we retry the cert fetch on next kubectl command util.ClusterConfig.Purge(cluster.name, cluster.zone, cluster_ref.projectId) # reset current context if current_context: kubeconfig = kconfig.Kubeconfig.Default() kubeconfig.SetCurrentContext(current_context) kubeconfig.SaveToFile() raise util.Error( NO_CERTS_ERROR_FMT.format( command=' '.join(args.command_path[:-1] + ['get-credentials', cluster.name]))) return cluster
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: Cluster message for the successfully created cluster. Raises: util.Error, if creation failed. """ util.CheckKubectlInstalled() if not args.password: args.password = ''.join( random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16)) adapter = self.context['api_adapter'] if not args.scopes: args.scopes = [] cluster_ref = adapter.ParseCluster(args.name) options = self.ParseCreateOptions(args) operation = None try: operation_ref = adapter.CreateCluster(cluster_ref, options) if not args.wait: return adapter.GetCluster(cluster_ref) operation = adapter.WaitForOperation(operation_ref, 'Creating cluster {0}'.format( cluster_ref.clusterId), timeout_s=args.timeout) cluster = adapter.GetCluster(cluster_ref) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error)) log.CreatedResource(cluster_ref) if operation.detail: # Non-empty detail on a DONE create operation should be surfaced as # a warning to end user. log.warning(operation.detail) try: util.ClusterConfig.Persist(cluster, cluster_ref.projectId) except kconfig.MissingEnvVarError as error: log.warning(error.message) return cluster
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] cluster_ref = adapter.ParseCluster(args.name) # Make sure it exists (will raise appropriate error if not) adapter.GetCluster(cluster_ref) # locations will be None if additional-zones was specified, an empty list # if it was specified with no argument, or a populated list if zones were # provided. We want to distinguish between the case where it isn't # specified (and thus shouldn't be passed on to the API) and the case where # it's specified as wanting no additional zones, in which case we must pass # the cluster's primary zone to the API. # TODO(b/29578401): Remove the hasattr once the flag is GA. locations = None if hasattr(args, 'additional_zones') and args.additional_zones is not None: locations = sorted([cluster_ref.zone] + args.additional_zones) options = api_adapter.UpdateClusterOptions( monitoring_service=args.monitoring_service, disable_addons=args.disable_addons, enable_autoscaling=args.enable_autoscaling, min_nodes=args.min_nodes, max_nodes=args.max_nodes, node_pool=args.node_pool, locations=locations) try: op_ref = adapter.UpdateCluster(cluster_ref, options) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error)) if not flags.GetAsyncValueFromAsyncAndWaitFlags( args. async, args.wait): adapter.WaitForOperation( op_ref, 'Updating {0}'.format(cluster_ref.clusterId)) log.UpdatedResource(cluster_ref)
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] try: return adapter.GetOperation(adapter.ParseOperation(args.operation_id)) except apitools_base.HttpError as error: raise exceptions.HttpException(util.GetError(error))
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] project = properties.VALUES.core.project.Get(required=True) cluster = properties.VALUES.container.cluster.Get(required=True) zone = properties.VALUES.compute.zone.Get(required=True) try: return adapter.ListNodePools(project, zone, cluster) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error))
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] project = properties.VALUES.core.project.Get(required=True) zone = None if args.zone: zone = adapter.registry.Parse(args.zone, collection='compute.zones').zone try: return adapter.ListClusters(project, zone) except apitools_base.HttpError as error: raise exceptions.HttpException(util.GetError(error))
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] pool_ref = adapter.ParseNodePool(args.name) console_io.PromptContinue(message=( 'The following node pool will be deleted.\n' '[{name}] in cluster [{clusterId}] in zone [{zone}]').format( name=pool_ref.nodePoolId, clusterId=pool_ref.clusterId, zone=adapter.Zone(pool_ref)), throw_if_unattended=True, cancel_on_no=True) try: # Make sure it exists (will raise appropriate error if not) adapter.GetNodePool(pool_ref) op_ref = adapter.DeleteNodePool(pool_ref) if args.wait: adapter.WaitForOperation(op_ref, 'Deleting node pool {0}'.format( pool_ref.nodePoolId), timeout_s=args.timeout) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error)) log.DeletedResource(pool_ref) return op_ref
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: Some value that we want to have printed later. """ adapter = self.context['api_adapter'] operation_ref = adapter.ParseOperation(args.operation_id) try: # Try fetching it first to ensure we have permissions and the op exists. adapter.GetOperation(operation_ref) return adapter.WaitForOperation( operation_ref, 'Waiting for {0} to complete'.format(operation_ref.operationId)) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error))
class Create(base.Command): """Create a cluster for running containers.""" @staticmethod def Args(parser): _Args(parser) flags.AddClusterAutoscalingFlags(parser, suppressed=True) flags.AddLocalSSDFlag(parser, suppressed=True) def ParseCreateOptions(self, args): if not args.scopes: args.scopes = [] cluster_ipv4_cidr = args.cluster_ipv4_cidr return api_adapter.CreateClusterOptions( node_machine_type=args.machine_type, scopes=args.scopes, enable_cloud_endpoints=args.enable_cloud_endpoints, num_nodes=args.num_nodes, additional_zones=args.additional_zones, user=args.username, password=args.password, cluster_version=args.cluster_version, network=args.network, subnetwork=args.subnetwork, cluster_ipv4_cidr=cluster_ipv4_cidr, node_disk_size_gb=args.disk_size, enable_cloud_logging=args.enable_cloud_logging, enable_cloud_monitoring=args.enable_cloud_monitoring, disable_addons=args.disable_addons, local_ssd_count=args.local_ssd_count, tags=args.tags, enable_autoscaling=args.enable_autoscaling, max_nodes=args.max_nodes, min_nodes=args.min_nodes, image_type=args.image_type, max_nodes_per_pool=args.max_nodes_per_pool) def Collection(self): return 'container.projects.zones.clusters' def Format(self, args): return self.ListFormat(args) 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: Cluster message for the successfully created cluster. Raises: util.Error, if creation failed. """ util.CheckKubectlInstalled() if not args.password: args.password = ''.join( random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16)) adapter = self.context['api_adapter'] if not args.scopes: args.scopes = [] cluster_ref = adapter.ParseCluster(args.name) options = self.ParseCreateOptions(args) operation = None try: operation_ref = adapter.CreateCluster(cluster_ref, options) if flags.GetAsyncValueFromAsyncAndWaitFlags( args. async, args.wait): return adapter.GetCluster(cluster_ref) operation = adapter.WaitForOperation(operation_ref, 'Creating cluster {0}'.format( cluster_ref.clusterId), timeout_s=args.timeout) cluster = adapter.GetCluster(cluster_ref) except apitools_exceptions.HttpError as error: raise exceptions.HttpException(util.GetError(error))