145 lines
5.6 KiB
Python
145 lines
5.6 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2014 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.
|
|
"""Resize cluster command."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from apitools.base.py import exceptions as apitools_exceptions
|
|
|
|
from googlecloudsdk.api_lib.container import util
|
|
from googlecloudsdk.calliope import actions
|
|
from googlecloudsdk.calliope import base
|
|
from googlecloudsdk.calliope import exceptions
|
|
from googlecloudsdk.command_lib.container import flags
|
|
from googlecloudsdk.core import log
|
|
from googlecloudsdk.core.console import console_attr
|
|
from googlecloudsdk.core.console import console_io
|
|
|
|
|
|
class Resize(base.Command):
|
|
"""Resizes an existing cluster for running containers."""
|
|
|
|
@staticmethod
|
|
def Args(parser):
|
|
"""Register flags for this command.
|
|
|
|
Args:
|
|
parser: An argparse.ArgumentParser-like object. It is mocked out in order
|
|
to capture some information, but behaves like an ArgumentParser.
|
|
"""
|
|
parser.add_argument('name', help='The name of this cluster.')
|
|
group = parser.add_mutually_exclusive_group(required=True)
|
|
group.add_argument(
|
|
'--size',
|
|
type=int,
|
|
dest='num_nodes',
|
|
action=actions.DeprecationAction('--size',
|
|
warn='The {flag_name} flag is now '
|
|
'deprecated. Please use `--num-nodes` '
|
|
'instead.'),
|
|
help='Target number of nodes in the cluster.')
|
|
group.add_argument(
|
|
'--num-nodes',
|
|
type=int,
|
|
help='Target number of nodes in the cluster.')
|
|
parser.add_argument('--node-pool', help='The node pool to resize.')
|
|
flags.AddAsyncFlag(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.
|
|
"""
|
|
adapter = self.context['api_adapter']
|
|
location_get = self.context['location_get']
|
|
location = location_get(args)
|
|
cluster_ref = adapter.ParseCluster(args.name, location)
|
|
cluster = None
|
|
cluster_name = args.name
|
|
pool_name = args.node_pool if args.node_pool else 'default-pool'
|
|
try:
|
|
# Attempt to get cluster for better prompts and to validate args.
|
|
# Error is a warning but not fatal. Should only exit with a failure on
|
|
# ResizeNodePool(...) below.
|
|
cluster = adapter.GetCluster(cluster_ref)
|
|
cluster_name = cluster.name
|
|
except (exceptions.HttpException, apitools_exceptions.HttpForbiddenError,
|
|
util.Error) as error:
|
|
log.warning(('Problem loading details of cluster to resize:\n\n{}\n\n'
|
|
'You can still attempt to resize the cluster.\n').format(
|
|
console_attr.SafeText(error)))
|
|
|
|
if cluster is not None:
|
|
pool_name = adapter.FindNodePool(cluster, args.node_pool).name
|
|
|
|
console_io.PromptContinue(
|
|
message=('Pool [{pool}] for [{cluster_name}] will be resized to '
|
|
'{new_size} node(s) in each zone it spans.').format(
|
|
pool=pool_name,
|
|
cluster_name=cluster_name,
|
|
new_size=args.num_nodes),
|
|
throw_if_unattended=True,
|
|
cancel_on_no=True)
|
|
|
|
op_ref = adapter.ResizeNodePool(cluster_ref, pool_name, args.num_nodes)
|
|
|
|
if not args.async_:
|
|
adapter.WaitForOperation(op_ref,
|
|
'Resizing {0}'.format(cluster_ref.clusterId))
|
|
log.UpdatedResource(cluster_ref)
|
|
|
|
|
|
Resize.detailed_help = {
|
|
'brief':
|
|
'Resizes an existing cluster for running containers.',
|
|
'DESCRIPTION':
|
|
"""
|
|
Resize an existing cluster to a provided size.
|
|
|
|
If you have multiple node pools, you must specify which node pool to resize by
|
|
using the --node-pool flag. You are not required to use the flag if you have
|
|
a single node pool.
|
|
|
|
When increasing the size of a container cluster, the new instances are created
|
|
with the same configuration as the existing instances.
|
|
Existing pods are not moved onto the new instances,
|
|
but new pods (such as those created by resizing a replication controller)
|
|
will be scheduled onto the new instances.
|
|
|
|
When decreasing a cluster, the nodes are drained. As a result, the pods running
|
|
on these nodes are gracefully terminated. If your pods are being managed by a
|
|
workload controller, the controller will attempt to reschedule them onto the
|
|
remaining instances. If your pods are not managed by a workload controller,
|
|
they will not be restarted.
|
|
Note that when resizing down, instances running pods and instances without pods
|
|
are not differentiated. Resize will pick instances to remove at random.
|
|
|
|
When you resize a node pool that spans multiple zones, the new size represents
|
|
the number of nodes in the node pool per zone. For example, if you have a node
|
|
pool of size 2 spanning two zones, the total node count is 4. If you resize the
|
|
node pool with `--num-nodes=4`, the total node count becomes 8.
|
|
""",
|
|
'EXAMPLES':
|
|
"""\
|
|
To resize the default node pool of an existing cluster, run:
|
|
|
|
$ {command} sample-cluster --num-nodes=2
|
|
""",
|
|
}
|