Skip to content

Commit 77f787c

Browse files
committed
add namespace update code
1 parent 5bcf136 commit 77f787c

File tree

5 files changed

+264
-19
lines changed

5 files changed

+264
-19
lines changed

src/aks-preview/azext_aks_preview/_help.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1670,7 +1670,60 @@
16701670

16711671
helps['aks namespace add'] = """
16721672
type: command
1673-
short-summary: Add a namespace to the managed Kubernetes cluster.
1673+
short-summary: Add namespace to the managed Kubernetes cluster.
1674+
parameters:
1675+
- name: --name
1676+
type: string
1677+
short-summary: The name of the managed namespace.
1678+
- name: --cluster-name
1679+
type: string
1680+
short-summary: Name of the managed cluster.
1681+
- name: --tags
1682+
type: string
1683+
short-summary: The tags of the managed namespace.
1684+
- name: --labels
1685+
type: string
1686+
short-summary: Labels for the managed namespace.
1687+
- name: --annotations
1688+
type: string
1689+
short-summary: Annotations for the managed namespace.
1690+
- name: --cpu-request
1691+
type: string
1692+
short-summary: CPU request of the namespace.
1693+
- name: --cpu-limit
1694+
type: string
1695+
short-summary: CPU limit of the namespace.
1696+
- name: --memory-request
1697+
type: string
1698+
short-summary: Memory request of the namespace.
1699+
- name: --memory-limit
1700+
type: string
1701+
short-summary: Memory limit of the namespace.
1702+
- name: --ingress-rule
1703+
type: string
1704+
short-summary: Ingress policy rule for the network.
1705+
- name: --egress-rule
1706+
type: string
1707+
short-summary: Egress policy rule for the network.
1708+
- name: --adoption-policy
1709+
type: string
1710+
short-summary: Action if Kubernetes namespace with same name already exists.
1711+
- name: --delete-policy
1712+
type: string
1713+
short-summary: Delete options of a namespace
1714+
- name: --aks-custom-headers
1715+
type: string
1716+
short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2
1717+
examples:
1718+
- name: Create a namespace in an existing AKS cluster.
1719+
text: az aks namespace add -g MyResourceGroup --cluster-name MyClusterName --name NamespaceName --cpu-request 500m --cpu-limit 800m --memory-request 1Gi --memory-limit 2Gi --aks-custom-headers AKSHTTPCustomFeatures=Microsoft.ContainerService/ManagedNamespacePreview
1720+
- name: Create a namespace in an existing AKS cluster with labels, annotations and tags
1721+
text: az aks namespace add -g MyResourceGroup --cluster-name MyClusterName --name NamespaceName --labels x=y a=b --annotations c=d v=x --tags p=q y=t --cpu-request 500m --cpu-limit 800m --memory-request 1Gi --memory-limit 2Gi --aks-custom-headers AKSHTTPCustomFeatures=Microsoft.ContainerService/ManagedNamespacePreview
1722+
"""
1723+
1724+
helps['aks namespace update'] = """
1725+
type: command
1726+
short-summary: Update namespace on the managed Kubernetes cluster.
16741727
parameters:
16751728
- name: --name
16761729
type: string

src/aks-preview/azext_aks_preview/_params.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ def load_arguments(self, _):
14371437

14381438
for scope in [
14391439
"aks namespace add",
1440-
# "aks namespace update",
1440+
"aks namespace update",
14411441
]:
14421442
with self.argument_context(scope) as c:
14431443
c.argument("tags", tags_type, options_list=["--tags"], help="The tags to set to the managed namespace.")

src/aks-preview/azext_aks_preview/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def load_command_table(self, _):
244244
g.custom_command("add", "aks_namespace_add")
245245
# g.custom_command("list", "aks_namespace_list")
246246
# g.custom_show_command("show", "aks_namespace_show")
247-
# g.custom_command("update", "aks_namespace_update")
247+
g.custom_command("update", "aks_namespace_update")
248248
# g.custom_command("delete", "aks_namespace_delete")
249249
# g.custom_command("get-credentials", "aks_get_credentials")
250250

src/aks-preview/azext_aks_preview/custom.py

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
)
9696
from azext_aks_preview.managednamespace import (
9797
aks_managed_namespace_add,
98+
aks_managed_namespace_update,
9899
)
99100
from azure.cli.command_modules.acs._helpers import (
100101
get_user_assigned_identity_by_resource_id
@@ -247,10 +248,10 @@ def aks_namespace_add(
247248
labels=None,
248249
annotations=None,
249250
aks_custom_headers=None,
250-
ingress_rule=CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWSAMENAMESPACE,
251-
egress_rule=CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWALL,
252-
adoption_policy=CONST_NAMESPACE_ADOPTION_POLICY_NEVER,
253-
delete_policy=CONST_NAMESPACE_DELETE_POLICY_KEEP,
251+
ingress_rule=None,
252+
egress_rule=None,
253+
adoption_policy=None,
254+
delete_policy=None,
254255
):
255256
existedNamespace = None
256257
try:
@@ -259,17 +260,49 @@ def aks_namespace_add(
259260
pass
260261

261262
if existedNamespace:
262-
raise Exception( # pylint: disable=broad-exception-raised
263-
"Namespace " +
264-
name +
265-
" already existed, please use 'az aks namespace update' command to update!"
263+
raise CLIError(
264+
f"Namespace '{name}' already exists. Please use 'az aks namespace update' to update it."
266265
)
267266

268267
# DO NOT MOVE: get all the original parameters and save them as a dictionary
269268
raw_parameters = locals()
270269
headers = get_aks_custom_headers(aks_custom_headers)
271270
return aks_managed_namespace_add(cmd, client, raw_parameters, headers)
272271

272+
# pylint: disable=unused-argument
273+
def aks_namespace_update(
274+
cmd,
275+
client,
276+
resource_group_name,
277+
cluster_name,
278+
name,
279+
cpu_request=None,
280+
cpu_limit=None,
281+
memory_request=None,
282+
memory_limit=None,
283+
tags=None,
284+
labels=None,
285+
annotations=None,
286+
aks_custom_headers=None,
287+
ingress_rule=None,
288+
egress_rule=None,
289+
adoption_policy=None,
290+
delete_policy=None,
291+
):
292+
try:
293+
existedNamespace = client.get(resource_group_name, cluster_name, name)
294+
except ResourceNotFoundError:
295+
raise CLIError(
296+
f"Namespace '{name}' doesn't exist."
297+
"Please use 'aks namespace list' to get current list of managed namespaces"
298+
)
299+
300+
if existedNamespace:
301+
#DO NOT MOVE: get all the original parameters and save them as a dictionary
302+
raw_parameters = locals()
303+
headers = get_aks_custom_headers(aks_custom_headers)
304+
return aks_managed_namespace_update(cmd, client, raw_parameters, headers, existedNamespace)
305+
273306

274307
def aks_maintenanceconfiguration_list(
275308
cmd, # pylint: disable=unused-argument

src/aks-preview/azext_aks_preview/managednamespace.py

Lines changed: 167 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def aks_managed_namespace_add(cmd, client, raw_parameters, headers):
2626
resource_group_name = raw_parameters.get("resource_group_name")
2727
cluster_name = raw_parameters.get("cluster_name")
2828
namespace_name = raw_parameters.get("name")
29-
namespace_config = constructNamespace(cmd, raw_parameters)
29+
namespace_config = constructNamespace(cmd, raw_parameters, namespace_name)
3030

3131
return client.begin_create_or_update(
3232
resource_group_name=resource_group_name,
@@ -36,8 +36,7 @@ def aks_managed_namespace_add(cmd, client, raw_parameters, headers):
3636
headers=headers
3737
)
3838

39-
def constructNamespace(cmd, raw_parameters):
40-
namespace_name = raw_parameters.get("name")
39+
def constructNamespace(cmd, raw_parameters, namespace_name):
4140
tags = raw_parameters.get("tags", {})
4241
labels_raw = raw_parameters.get("labels")
4342
labels = parse_key_value_list(labels_raw)
@@ -66,7 +65,6 @@ def constructNamespace(cmd, raw_parameters):
6665
)
6766

6867
namespace_config = Namespace()
69-
print(namespace_config)
7068
namespace_config.name = namespace_name
7169
namespace_config.tags = tags
7270
namespace_config.properties = namespace_properties
@@ -99,8 +97,8 @@ def setResourceQuota(cmd, raw_parameters):
9997
return rq
10098

10199
def setNetworkPolicyRule(cmd, raw_parameters):
102-
ingress_rule = raw_parameters.get("ingress_rule", CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWSAMENAMESPACE)
103-
egress_rule = raw_parameters.get("egress_rule", CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWALL)
100+
ingress_rule = raw_parameters.get("ingress_rule") or CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWSAMENAMESPACE
101+
egress_rule = raw_parameters.get("egress_rule") or CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWALL
104102

105103
valid_network_policy_rules = {
106104
CONST_NAMESPACE_NETWORK_POLICY_RULE_DENYALL,
@@ -134,7 +132,7 @@ def setNetworkPolicyRule(cmd, raw_parameters):
134132
return np
135133

136134
def setAdoptionPolicy(cmd, raw_parameters):
137-
adoption_policy = raw_parameters.get("adoption_policy", CONST_NAMESPACE_ADOPTION_POLICY_NEVER)
135+
adoption_policy = raw_parameters.get("adoption_policy") or CONST_NAMESPACE_ADOPTION_POLICY_NEVER
138136

139137
valid_adoption_policy = {
140138
CONST_NAMESPACE_ADOPTION_POLICY_NEVER,
@@ -151,7 +149,7 @@ def setAdoptionPolicy(cmd, raw_parameters):
151149
return adoption_policy
152150

153151
def setDeletePolicy(cmd, raw_parameters):
154-
delete_policy = raw_parameters.get("delete_policy", CONST_NAMESPACE_DELETE_POLICY_KEEP)
152+
delete_policy = raw_parameters.get("delete_policy") or CONST_NAMESPACE_DELETE_POLICY_KEEP
155153

156154
valid_delete_policy = {
157155
CONST_NAMESPACE_DELETE_POLICY_KEEP,
@@ -176,3 +174,164 @@ def parse_key_value_list(pairs):
176174
key, value = pair.split("=", 1)
177175
result[key.strip()] = value.strip()
178176
return result
177+
178+
def aks_managed_namespace_update(cmd, client, raw_parameters, headers, existedNamespace):
179+
resource_group_name = raw_parameters.get("resource_group_name")
180+
cluster_name = raw_parameters.get("cluster_name")
181+
namespace_name = raw_parameters.get("name")
182+
namespace_config = updateNamespace(cmd, raw_parameters, existedNamespace)
183+
184+
return client.begin_create_or_update(
185+
resource_group_name=resource_group_name,
186+
resource_name=cluster_name,
187+
namespace_name=namespace_name,
188+
parameters=namespace_config,
189+
headers=headers
190+
)
191+
192+
def updateNamespace(cmd, raw_parameters, existedNamespace):
193+
tags = raw_parameters.get("tags", {})
194+
labels_raw = raw_parameters.get("labels")
195+
labels = parse_key_value_list(labels_raw)
196+
annotations_raw = raw_parameters.get("annotations")
197+
annotations = parse_key_value_list(annotations_raw)
198+
199+
NamespaceProperties = cmd.get_models(
200+
"NamespaceProperties",
201+
resource_type = CUSTOM_MGMT_AKS_PREVIEW,
202+
operation_group = "namespaces"
203+
)
204+
205+
namespace_properties = NamespaceProperties(
206+
labels = labels,
207+
annotations = annotations,
208+
default_resource_quota = updateResourceQuota(cmd, raw_parameters, existedNamespace),
209+
default_network_policy = updateNetworkPolicyRule(cmd, raw_parameters, existedNamespace),
210+
adoption_policy = updateAdoptionPolicy(cmd, raw_parameters, existedNamespace),
211+
delete_policy = updateDeletePolicy(cmd, raw_parameters, existedNamespace)
212+
)
213+
214+
Namespace = cmd.get_models(
215+
"Namespace",
216+
resource_type = CUSTOM_MGMT_AKS_PREVIEW,
217+
operation_group = "namespaces"
218+
)
219+
220+
namespace_config = Namespace()
221+
namespace_config.name = existedNamespace.name
222+
namespace_config.tags = tags
223+
namespace_config.properties = namespace_properties
224+
return namespace_config
225+
226+
def updateResourceQuota(cmd, raw_parameters, existedNamespace):
227+
cpu_request = raw_parameters.get("cpu_request")
228+
cpu_limit = raw_parameters.get("cpu_limit")
229+
memory_request = raw_parameters.get("memory_request")
230+
memory_limit = raw_parameters.get("memory_limit")
231+
232+
if cpu_request is None:
233+
cpu_request = existedNamespace.properties.default_resource_quota.cpu_request
234+
235+
if cpu_limit is None:
236+
cpu_limit = existedNamespace.properties.default_resource_quota.cpu_limit
237+
238+
if memory_request is None:
239+
memory_request = existedNamespace.properties.default_resource_quota.memory_request
240+
241+
if memory_limit is None:
242+
memory_limit = existedNamespace.properties.default_resource_quota.memory_limit
243+
244+
ResourceQuota = cmd.get_models(
245+
"ResourceQuota",
246+
resource_type = CUSTOM_MGMT_AKS_PREVIEW,
247+
operation_group = "namespaces"
248+
)
249+
250+
rq = ResourceQuota(
251+
cpu_request = cpu_request,
252+
cpu_limit = cpu_limit,
253+
memory_request = memory_request,
254+
memory_limit = memory_limit
255+
)
256+
257+
return rq
258+
259+
def updateNetworkPolicyRule(cmd, raw_parameters, existedNamespace):
260+
ingress_rule = raw_parameters.get("ingress_rule")
261+
egress_rule = raw_parameters.get("egress_rule")
262+
263+
valid_network_policy_rules = {
264+
CONST_NAMESPACE_NETWORK_POLICY_RULE_DENYALL,
265+
CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWSAMENAMESPACE,
266+
CONST_NAMESPACE_NETWORK_POLICY_RULE_ALLOWALL
267+
}
268+
269+
if ingress_rule not in valid_network_policy_rules:
270+
raise InvalidArgumentValueError(
271+
f"Invalid ingress_rule '{ingress_rule}'. Must be one of: "
272+
f"{', '.join(valid_network_policy_rules)}"
273+
)
274+
275+
if egress_rule not in valid_network_policy_rules:
276+
raise InvalidArgumentValueError(
277+
f"Invalid egress_rule '{egress_rule}'. Must be one of: "
278+
f"{', '.join(valid_network_policy_rules)}"
279+
)
280+
281+
if ingress_rule is None:
282+
ingress_rule = existedNamespace.properties.default_network_policy.ingress
283+
284+
if egress_rule is None:
285+
egress_rule = existedNamespace.properties.default_network_policy.egress
286+
287+
NetworkPolicies = cmd.get_models(
288+
"NetworkPolicies",
289+
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
290+
operation_group="namespaces"
291+
)
292+
293+
np = NetworkPolicies(
294+
ingress = ingress_rule,
295+
egress = egress_rule
296+
)
297+
298+
return np
299+
300+
def updateAdoptionPolicy(cmd, raw_parameters, existedNamespace):
301+
adoption_policy = raw_parameters.get("adoption_policy")
302+
303+
valid_adoption_policy = {
304+
CONST_NAMESPACE_ADOPTION_POLICY_NEVER,
305+
CONST_NAMESPACE_ADOPTION_POLICY_IFIDENTICAL,
306+
CONST_NAMESPACE_ADOPTION_POLICY_ALWAYS
307+
}
308+
309+
if adoption_policy not in valid_adoption_policy:
310+
raise InvalidArgumentValueError(
311+
f"Invalid adoption policy '{adoption_policy}'. Must be one of: "
312+
f"{', '.join(valid_adoption_policy)}"
313+
)
314+
315+
if adoption_policy is None:
316+
adoption_policy = existedNamespace.properties.adoption_policy
317+
318+
return adoption_policy
319+
320+
def updateDeletePolicy(cmd, raw_parameters, existedNamespace):
321+
delete_policy = raw_parameters.get("delete_policy")
322+
323+
valid_delete_policy = {
324+
CONST_NAMESPACE_DELETE_POLICY_KEEP,
325+
CONST_NAMESPACE_DELETE_POLICY_DELETE
326+
}
327+
328+
if delete_policy not in valid_delete_policy:
329+
raise InvalidArgumentValueError(
330+
f"Invalid delete policy '{delete_policy}'. Must be one of: "
331+
f"{', '.join(valid_delete_policy)}"
332+
)
333+
334+
if delete_policy is None:
335+
delete_policy = existedNamespace.properties.delete_policy
336+
337+
return delete_policy

0 commit comments

Comments
 (0)