Skip to content

Commit

Permalink
{AKS} az aks stop: add warning when private link cluster is stopped (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
levimm committed Dec 1, 2023
1 parent 27e5e38 commit 93fee25
Show file tree
Hide file tree
Showing 11 changed files with 2,912 additions and 741 deletions.
4 changes: 4 additions & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ To release a new version, please select a new version number (usually plus 1 to
Pending
+++++++

0.5.173
+++++++
* Add warning when stopping a private link cluster.

0.5.172
+++++++
* Fix for regression issue with `az aks create --enable-addon` command for enabling App Routing
Expand Down
10 changes: 10 additions & 0 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,16 @@
short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2
"""

helps['aks stop'] = """
type: command
short-summary: Stop a managed cluster.
long-summary: This can only be performed on Azure Virtual Machine Scale set backed clusters. Stopping a
cluster stops the control plane and agent nodes entirely, while maintaining all object and
cluster state. A cluster does not accrue charges while it is stopped. See `stopping a
cluster <https://docs.microsoft.com/azure/aks/start-stop-cluster>`_ for more details about
stopping a cluster.
"""

helps['aks upgrade'] = """
type: command
short-summary: Upgrade a managed Kubernetes cluster to a newer version.
Expand Down
7 changes: 7 additions & 0 deletions src/aks-preview/azext_aks_preview/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,13 @@ def get_cluster_snapshot(cli_ctx, subscription_id, resource_group_name, snapshot
return snapshot


def check_is_private_link_cluster(mc: ManagedCluster) -> bool:
"""Check `mc` object to determine whether private link cluster is enabled.
:return: bool
"""
return check_is_private_cluster(mc) and not check_is_apiserver_vnet_integration_cluster(mc)


def check_is_private_cluster(mc: ManagedCluster) -> bool:
"""Check `mc` object to determine whether private cluster is enabled.
:return: bool
Expand Down
2 changes: 1 addition & 1 deletion src/aks-preview/azext_aks_preview/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def load_command_table(self, _):
g.custom_command('rotate-certs', 'aks_rotate_certs', supports_no_wait=True,
confirmation='Kubernetes will be unavailable during certificate rotation process.\n' +
'Are you sure you want to perform this operation?')
g.command('stop', 'begin_stop', supports_no_wait=True)
g.custom_command('stop', 'aks_stop', supports_no_wait=True)
g.command('start', 'begin_start', supports_no_wait=True)
g.wait_command('wait')
g.custom_command('get-versions', 'aks_get_versions', table_transformer=aks_versions_table_format)
Expand Down
11 changes: 11 additions & 0 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_ROLLBACK,
)
from azext_aks_preview._helpers import (
check_is_private_link_cluster,
get_cluster_snapshot_by_snapshot_id,
get_nodepool_snapshot_by_snapshot_id,
print_or_merge_credentials,
Expand Down Expand Up @@ -821,6 +822,16 @@ def aks_show(cmd, client, resource_group_name, name, aks_custom_headers=None):
return _remove_nulls([mc])[0]


def aks_stop(cmd, client, resource_group_name, name, no_wait=False):
instance = client.get(resource_group_name, name)
# print warning when stopping a private cluster
if check_is_private_link_cluster(instance):
logger.warning('Your private cluster apiserver IP might get changed when it\'s stopped and started.\n'
'Any user provisioned private endpoints linked to this private cluster will need to be deleted and created again. '
'Any user managed DNS record also needs to be updated with the new IP.')
return sdk_no_wait(no_wait, client.begin_stop, resource_group_name, name)


# pylint: disable=unused-argument
def aks_list(cmd, client, resource_group_name=None):
if resource_group_name:
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,27 @@ def test_aks_stop_and_start(self, resource_group, resource_group_location):
start_cmd = 'aks start --resource-group={resource_group} --name={name}'
self.cmd(start_cmd)

@AllowLargeResponse()
@AKSCustomResourceGroupPreparer(random_name_length=17, name_prefix='clitest', location='westus2')
def test_aks_stop_and_start_private_cluster(self, resource_group, resource_group_location):
aks_name = self.create_random_name('cliakstest', 16)
self.kwargs.update({
'resource_group': resource_group,
'name': aks_name,
'ssh_key_value': self.generate_ssh_keys()
})

create_cmd = 'aks create --resource-group={resource_group} --name={name} --ssh-key-value={ssh_key_value} --enable-private-cluster'
self.cmd(create_cmd, checks=[
self.check('provisioningState', 'Succeeded'),
])

stop_cmd = 'aks stop --resource-group={resource_group} --name={name}'
self.cmd(stop_cmd)

start_cmd = 'aks start --resource-group={resource_group} --name={name}'
self.cmd(start_cmd)

@AllowLargeResponse()
@AKSCustomResourceGroupPreparer(random_name_length=17, name_prefix='clitest', location='centraluseuap')
def test_aks_abort(self, resource_group, resource_group_location):
Expand Down
54 changes: 54 additions & 0 deletions src/aks-preview/azext_aks_preview/tests/latest/test_custom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
import unittest
from unittest.mock import Mock, patch

from azext_aks_preview.__init__ import register_aks_preview_resource_type
from azext_aks_preview._client_factory import CUSTOM_MGMT_AKS_PREVIEW
from azext_aks_preview.managed_cluster_decorator import (
AKSPreviewManagedClusterModels,
)
from azext_aks_preview.custom import (
aks_stop,
)
from azext_aks_preview.tests.latest.mocks import MockCLI, MockClient, MockCmd


class TestCustomCommand(unittest.TestCase):
def setUp(self):
# manually register CUSTOM_MGMT_AKS_PREVIEW
register_aks_preview_resource_type()
self.cli_ctx = MockCLI()
self.cmd = MockCmd(self.cli_ctx)
self.models = AKSPreviewManagedClusterModels(self.cmd, CUSTOM_MGMT_AKS_PREVIEW)
self.client = MockClient()

def test_aks_stop(self):
# public cluster: call begin_stop
mc_1 = self.models.ManagedCluster(location="test_location")
self.client.get = Mock(
return_value=mc_1
)
self.client.begin_stop = Mock(
return_value=None
)
self.assertEqual(aks_stop(self.cmd, self.client, "rg", "name"), None)

# private cluster: call begin_stop
mc_3 = self.models.ManagedCluster(location="test_location")
api_server_access_profile = self.models.ManagedClusterAPIServerAccessProfile()
api_server_access_profile.enable_private_cluster = True
mc_3.api_server_access_profile = api_server_access_profile
self.client.get = Mock(
return_value=mc_3
)
self.client.begin_stop = Mock(
return_value=None
)
self.assertEqual(aks_stop(self.cmd, self.client, "rg", "name", False), None)


if __name__ == '__main__':
unittest.main()
32 changes: 32 additions & 0 deletions src/aks-preview/azext_aks_preview/tests/latest/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,24 @@

from azext_aks_preview._helpers import (
_fuzzy_match,
check_is_private_link_cluster,
get_cluster_snapshot,
get_cluster_snapshot_by_snapshot_id,
get_nodepool_snapshot,
get_nodepool_snapshot_by_snapshot_id,
)
from azext_aks_preview.__init__ import register_aks_preview_resource_type
from azext_aks_preview._client_factory import CUSTOM_MGMT_AKS_PREVIEW
from azext_aks_preview.managed_cluster_decorator import (
AKSPreviewManagedClusterModels,
)
from azure.cli.core.azclierror import (
BadRequestError,
InvalidArgumentValueError,
ResourceNotFoundError,
)
from azure.core.exceptions import AzureError, HttpResponseError
from azext_aks_preview.tests.latest.mocks import MockCLI, MockCmd


class TestFuzzyMatch(unittest.TestCase):
Expand Down Expand Up @@ -110,6 +117,31 @@ def test_get_cluster_snapshot(self):
), self.assertRaises(BadRequestError):
get_cluster_snapshot("mock_cli_ctx", "test_sub", "mock_rg", "mock_snapshot_name")

class CheckManagedClusterTestCase(unittest.TestCase):
def setUp(self):
# manually register CUSTOM_MGMT_AKS_PREVIEW
register_aks_preview_resource_type()
self.cli_ctx = MockCLI()
self.cmd = MockCmd(self.cli_ctx)
# store all the models used by nat gateway
self.models = AKSPreviewManagedClusterModels(self.cmd, CUSTOM_MGMT_AKS_PREVIEW)

def test_check_is_private_link_cluster(self):
mc_1 = self.models.ManagedCluster(location="test_location")
self.assertEqual(check_is_private_link_cluster(mc_1), False)

mc_2 = self.models.ManagedCluster(location="test_location")
api_server_access_profile = self.models.ManagedClusterAPIServerAccessProfile()
api_server_access_profile.enable_private_cluster = True
api_server_access_profile.enable_vnet_integration = True
self.assertEqual(check_is_private_link_cluster(mc_2), False)

mc_3 = self.models.ManagedCluster(location="test_location")
api_server_access_profile = self.models.ManagedClusterAPIServerAccessProfile()
api_server_access_profile.enable_private_cluster = True
mc_3.api_server_access_profile = api_server_access_profile
self.assertEqual(check_is_private_link_cluster(mc_3), True)


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion src/aks-preview/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from setuptools import setup, find_packages

VERSION = "0.5.172"
VERSION = "0.5.173"

CLASSIFIERS = [
"Development Status :: 4 - Beta",
Expand Down

0 comments on commit 93fee25

Please sign in to comment.