Skip to content

Commit

Permalink
{AKS} Refactor 2nd part of the create sub-command in aks-preview modu…
Browse files Browse the repository at this point in the history
…le (#3964)

* refactor http_proxy_config & node_resource_group

* fix lint
  • Loading branch information
FumingZhang authored Oct 18, 2021
1 parent 363774c commit 7ad8f0d
Show file tree
Hide file tree
Showing 2 changed files with 240 additions and 1 deletion.
101 changes: 100 additions & 1 deletion src/aks-preview/azext_aks_preview/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
safe_list_get,
)
from azure.cli.core import AzCommandsLoader
from azure.cli.core.azclierror import InvalidArgumentValueError
from azure.cli.core.azclierror import (
CLIInternalError,
InvalidArgumentValueError,
)
from azure.cli.core.commands import AzCliCommand
from azure.cli.core.profiles import ResourceType
from azure.cli.core.util import get_file_json
Expand All @@ -31,6 +34,7 @@
ResourceReference = TypeVar("ResourceReference")
KubeletConfig = TypeVar("KubeletConfig")
LinuxOSConfig = TypeVar("LinuxOSConfig")
ManagedClusterHTTPProxyConfig = TypeVar("ManagedClusterHTTPProxyConfig")


# pylint: disable=too-many-instance-attributes,too-few-public-methods
Expand All @@ -48,6 +52,11 @@ def __init__(self, cmd: AzCommandsLoader, resource_type: ResourceType):
resource_type=self.resource_type,
operation_group="managed_clusters",
)
self.ManagedClusterHTTPProxyConfig = self.__cmd.get_models(
"ManagedClusterHTTPProxyConfig",
resource_type=self.resource_type,
operation_group="managed_clusters",
)


# pylint: disable=too-many-public-methods
Expand Down Expand Up @@ -229,6 +238,54 @@ def get_linux_os_config(self) -> Union[dict, LinuxOSConfig, None]:
# this parameter does not need validation
return linux_os_config

def get_http_proxy_config(self) -> Union[dict, ManagedClusterHTTPProxyConfig, None]:
"""Obtain the value of http_proxy_config.
:return: dict, ManagedClusterHTTPProxyConfig or None
"""
# read the original value passed by the command
http_proxy_config = None
http_proxy_config_file_path = self.raw_param.get("http_proxy_config")
# validate user input
if http_proxy_config_file_path:
if not os.path.isfile(http_proxy_config_file_path):
raise InvalidArgumentValueError(
"{} is not valid file, or not accessable.".format(
http_proxy_config_file_path
)
)
http_proxy_config = get_file_json(http_proxy_config_file_path)
if not isinstance(http_proxy_config, dict):
raise InvalidArgumentValueError(
"Error reading Http Proxy Config from {}. "
"Please see https://aka.ms/HttpProxyConfig for correct format.".format(
http_proxy_config_file_path
)
)

# try to read the property value corresponding to the parameter from the `mc` object
if self.mc and self.mc.http_proxy_config is not None:
http_proxy_config = self.mc.http_proxy_config

# this parameter does not need dynamic completion
# this parameter does not need validation
return http_proxy_config

def get_node_resource_group(self) -> Union[str, None]:
"""Obtain the value of node_resource_group.
:return: string or None
"""
# read the original value passed by the command
node_resource_group = self.raw_param.get("node_resource_group")
# try to read the property value corresponding to the parameter from the `mc` object
if self.mc and self.mc.node_resource_group is not None:
node_resource_group = self.mc.node_resource_group

# this parameter does not need dynamic completion
# this parameter does not need validation
return node_resource_group


class AKSPreviewCreateDecorator(AKSCreateDecorator):
# pylint: disable=super-init-not-called
Expand Down Expand Up @@ -279,6 +336,48 @@ def set_up_agent_pool_profiles(self, mc: ManagedCluster) -> ManagedCluster:
agent_pool_profile.linux_os_config = self.context.get_linux_os_config()
return mc

def set_up_http_proxy_config(self, mc: ManagedCluster) -> ManagedCluster:
"""Set up http proxy config for the ManagedCluster object.
:return: the ManagedCluster object
"""
if not isinstance(mc, self.models.ManagedCluster):
raise CLIInternalError(
"Unexpected mc object with type '{}'.".format(type(mc))
)

mc.http_proxy_config = self.context.get_http_proxy_config()
return mc

def set_up_node_resource_group(self, mc: ManagedCluster) -> ManagedCluster:
"""Set up node resource group for the ManagedCluster object.
:return: the ManagedCluster object
"""
if not isinstance(mc, self.models.ManagedCluster):
raise CLIInternalError(
"Unexpected mc object with type '{}'.".format(type(mc))
)

mc.node_resource_group = self.context.get_node_resource_group()
return mc

def construct_preview_mc_profile(self) -> ManagedCluster:
"""The overall controller used to construct the preview ManagedCluster profile.
The completely constructed ManagedCluster object will later be passed as a parameter to the underlying SDK
(mgmt-containerservice) to send the actual request.
:return: the ManagedCluster object
"""
# construct the default ManagedCluster profile
mc = self.construct_default_mc_profile()
# set up http proxy config
mc = self.set_up_http_proxy_config(mc)
# set up node resource group
mc = self.set_up_node_resource_group(mc)
return mc


class AKSPreviewUpdateDecorator(AKSUpdateDecorator):
# pylint: disable=super-init-not-called
Expand Down
140 changes: 140 additions & 0 deletions src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ def test_models(self):

self.assertEqual(models.KubeletConfig, getattr(module, "KubeletConfig"))
self.assertEqual(models.LinuxOSConfig, getattr(module, "LinuxOSConfig"))
self.assertEqual(
models.ManagedClusterHTTPProxyConfig,
getattr(module, "ManagedClusterHTTPProxyConfig"),
)


class AKSPreviewContextTestCase(unittest.TestCase):
Expand Down Expand Up @@ -227,6 +231,69 @@ def test_get_linux_os_config(self):
with self.assertRaises(InvalidArgumentValueError):
ctx_3.get_linux_os_config()

def test_get_http_proxy_config(self):
# default
ctx_1 = AKSPreviewContext(
self.cmd,
{"http_proxy_config": None},
self.models,
decorator_mode=DecoratorMode.CREATE,
)
self.assertEqual(ctx_1.get_http_proxy_config(), None)
mc = self.models.ManagedCluster(
location="test_location",
http_proxy_config=self.models.ManagedClusterHTTPProxyConfig(
http_proxy="test_http_proxy"
),
)
ctx_1.attach_mc(mc)
self.assertEqual(
ctx_1.get_http_proxy_config(),
self.models.ManagedClusterHTTPProxyConfig(
http_proxy="test_http_proxy"
),
)

# custom value
ctx_2 = AKSPreviewContext(
self.cmd,
{"http_proxy_config": "fake-path"},
self.models,
decorator_mode=DecoratorMode.CREATE,
)
# fail on invalid file path
with self.assertRaises(InvalidArgumentValueError):
ctx_2.get_http_proxy_config()

# custom value
ctx_3 = AKSPreviewContext(
self.cmd,
{"http_proxy_config": _get_test_data_file("invalidconfig.json")},
self.models,
decorator_mode=DecoratorMode.CREATE,
)
# fail on invalid file path
with self.assertRaises(InvalidArgumentValueError):
ctx_3.get_http_proxy_config()

def test_get_node_resource_group(self):
# default
ctx_1 = AKSPreviewContext(
self.cmd,
{"node_resource_group": None},
self.models,
decorator_mode=DecoratorMode.CREATE,
)
self.assertEqual(ctx_1.get_node_resource_group(), None)
mc = self.models.ManagedCluster(
location="test_location",
node_resource_group="test_node_resource_group",
)
ctx_1.attach_mc(mc)
self.assertEqual(
ctx_1.get_node_resource_group(), "test_node_resource_group"
)


class AKSPreviewCreateDecoratorTestCase(unittest.TestCase):
def setUp(self):
Expand Down Expand Up @@ -400,6 +467,79 @@ def test_set_up_agent_pool_profiles(self):
ground_truth_mc_2.agent_pool_profiles = [agent_pool_profile_2]
self.assertEqual(dec_mc_2, ground_truth_mc_2)

def test_set_up_http_proxy_config(self):
# default value in `aks_create`
dec_1 = AKSPreviewCreateDecorator(
self.cmd,
self.client,
{
"http_proxy_config": None,
},
CUSTOM_MGMT_AKS_PREVIEW,
)
mc_1 = self.models.ManagedCluster(location="test_location")
# fail on passing the wrong mc object
with self.assertRaises(CLIInternalError):
dec_1.set_up_http_proxy_config(None)
dec_mc_1 = dec_1.set_up_http_proxy_config(mc_1)
ground_truth_mc_1 = self.models.ManagedCluster(location="test_location")
self.assertEqual(dec_mc_1, ground_truth_mc_1)

# custom value
dec_2 = AKSPreviewCreateDecorator(
self.cmd,
self.client,
{"http_proxy_config": _get_test_data_file("httpproxyconfig.json")},
CUSTOM_MGMT_AKS_PREVIEW,
)
mc_2 = self.models.ManagedCluster(location="test_location")
dec_mc_2 = dec_2.set_up_http_proxy_config(mc_2)
ground_truth_mc_2 = self.models.ManagedCluster(
location="test_location",
http_proxy_config={
"httpProxy": "http://myproxy.server.com:8080/",
"httpsProxy": "https://myproxy.server.com:8080/",
"noProxy": ["localhost", "127.0.0.1"],
},
)
self.assertEqual(dec_mc_2, ground_truth_mc_2)

def test_set_up_node_resource_group(self):
# default value in `aks_create`
dec_1 = AKSPreviewCreateDecorator(
self.cmd,
self.client,
{
"node_resource_group": None,
},
CUSTOM_MGMT_AKS_PREVIEW,
)
mc_1 = self.models.ManagedCluster(location="test_location")
# fail on passing the wrong mc object
with self.assertRaises(CLIInternalError):
dec_1.set_up_node_resource_group(None)
dec_mc_1 = dec_1.set_up_node_resource_group(mc_1)
ground_truth_mc_1 = self.models.ManagedCluster(location="test_location")
self.assertEqual(dec_mc_1, ground_truth_mc_1)

# custom value
dec_2 = AKSPreviewCreateDecorator(
self.cmd,
self.client,
{"node_resource_group": "test_node_resource_group"},
CUSTOM_MGMT_AKS_PREVIEW,
)
mc_2 = self.models.ManagedCluster(location="test_location")
dec_mc_2 = dec_2.set_up_node_resource_group(mc_2)
ground_truth_mc_2 = self.models.ManagedCluster(
location="test_location",
node_resource_group="test_node_resource_group",
)
self.assertEqual(dec_mc_2, ground_truth_mc_2)

def test_construct_preview_mc_profile(self):
pass


class AKSPreviewUpdateDecoratorTestCase(unittest.TestCase):
def setUp(self):
Expand Down

0 comments on commit 7ad8f0d

Please sign in to comment.