Skip to content

Commit ec69bb8

Browse files
author
indusridhar
committed
Rollback cli
1 parent 29c0e50 commit ec69bb8

File tree

8 files changed

+410
-2
lines changed

8 files changed

+410
-2
lines changed

src/aks-preview/HISTORY.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ If there is no rush to release a new version, please just add a description of t
99

1010
To release a new version, please select a new version number (usually plus 1 to last patch version, X.Y.Z -> Major.Minor.Patch, more details in `\doc <https://semver.org/>`_), and then add a new section named as the new version number in this file, the content should include the new modifications and everything from the *Pending* section. Finally, update the `VERSION` variable in `setup.py` with this new version number.
1111

12+
18.0.0b45
13+
+++++++
14+
* `az aks nodepool get-rollback-versions`: Add new command to get available rollback versions for a nodepool.
15+
* `az aks nodepool rollback`: Add new command to rollback a nodepool to a previously used configuration (N-1).
16+
1217
Pending
1318
+++++++
1419
* `az aks update`: Add new parameter `--kms-infrastructure-encryption` to enable KMS infrastructure encryption on an existing cluster.

src/aks-preview/azext_aks_preview/_format.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,22 @@ def aks_agentpool_list_table_format(results):
153153
return [_aks_agentpool_table_format(r) for r in results]
154154

155155

156+
def aks_agentpool_rollback_versions_table_format(results):
157+
"""Format rollback versions for display with "-o table"."""
158+
if not results:
159+
return []
160+
161+
def _format_rollback_version(result):
162+
parsed = compile_jmes("""{
163+
kubernetesVersion: orchestrator_version,
164+
nodeImageVersion: node_image_version,
165+
timestamp: timestamp
166+
}""")
167+
return parsed.search(result, Options(dict_cls=OrderedDict))
168+
169+
return [_format_rollback_version(r) for r in results]
170+
171+
156172
def aks_list_table_format(results):
157173
""""Format a list of managed clusters as summary results for display with "-o table"."""
158174
return [_aks_table_format(r) for r in results]

src/aks-preview/azext_aks_preview/_help.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,6 +2346,48 @@
23462346
crafted: true
23472347
"""
23482348

2349+
helps['aks nodepool get-rollback-versions'] = """
2350+
type: command
2351+
short-summary: Get the available rollback versions for an agent pool of the managed Kubernetes cluster.
2352+
long-summary: |
2353+
Get the list of historically used Kubernetes and node image versions that can be used for rollback operations.
2354+
examples:
2355+
- name: Get the available rollback versions for an agent pool.
2356+
text: az aks nodepool get-rollback-versions --resource-group MyResourceGroup --cluster-name MyManagedCluster --nodepool-name MyNodePool
2357+
crafted: true
2358+
"""
2359+
2360+
helps['aks nodepool rollback'] = """
2361+
type: command
2362+
short-summary: Rollback an agent pool to a previously used configuration.
2363+
long-summary: |
2364+
Rollback an agent pool to a previously used Kubernetes version or node image version.
2365+
If no specific versions are provided, the nodepool will be rolled back to the most recently used configuration.
2366+
parameters:
2367+
- name: --kubernetes-version
2368+
short-summary: Target Kubernetes version for rollback.
2369+
long-summary: If not specified, uses the most recent available Kubernetes version.
2370+
- name: --node-image-version
2371+
short-summary: Target node image version for rollback.
2372+
long-summary: If not specified, uses the most recent available node image version.
2373+
- name: --aks-custom-headers
2374+
short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2.
2375+
- name: --if-match
2376+
short-summary: The revision of the resource being updated. This should match the current revision.
2377+
- name: --if-none-match
2378+
short-summary: Set to '*' to allow a new resource to be created, but to prevent updating an existing resource.
2379+
examples:
2380+
- name: Rollback a nodepool to the most recent configuration.
2381+
text: az aks nodepool rollback --resource-group MyResourceGroup --cluster-name MyManagedCluster --nodepool-name MyNodePool
2382+
crafted: true
2383+
- name: Rollback a nodepool to a specific Kubernetes version.
2384+
text: az aks nodepool rollback --resource-group MyResourceGroup --cluster-name MyManagedCluster --nodepool-name MyNodePool --kubernetes-version 1.28.5
2385+
crafted: true
2386+
- name: Rollback a nodepool to specific Kubernetes and node image versions.
2387+
text: az aks nodepool rollback --resource-group MyResourceGroup --cluster-name MyManagedCluster --nodepool-name MyNodePool --kubernetes-version 1.28.5 --node-image-version AKSUbuntu-1804gen2containerd-2024.01.15
2388+
crafted: true
2389+
"""
2390+
23492391
helps['aks nodepool stop'] = """
23502392
type: command
23512393
short-summary: Stop running agent pool in the managed Kubernetes cluster.

src/aks-preview/azext_aks_preview/_params.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,6 +2030,22 @@ def load_arguments(self, _):
20302030
with self.argument_context("aks nodepool manual-scale delete") as c:
20312031
c.argument("current_vm_sizes", is_preview=True)
20322032

2033+
with self.argument_context("aks nodepool get-rollback-versions") as c:
2034+
pass # Uses common nodepool parameters
2035+
2036+
with self.argument_context("aks nodepool rollback") as c:
2037+
c.argument(
2038+
"kubernetes_version",
2039+
help="Target Kubernetes version for rollback. If not specified, uses the most recent available version."
2040+
)
2041+
c.argument(
2042+
"node_image_version",
2043+
help="Target node image version for rollback. If not specified, uses the most recent available version."
2044+
)
2045+
c.argument("aks_custom_headers", nargs="*")
2046+
c.argument("if_match")
2047+
c.argument("if_none_match")
2048+
20332049
with self.argument_context("aks machine") as c:
20342050
c.argument("cluster_name", help="The cluster name.")
20352051
c.argument(

src/aks-preview/azext_aks_preview/commands.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
aks_addon_show_table_format,
2727
aks_agentpool_list_table_format,
2828
aks_agentpool_show_table_format,
29+
aks_agentpool_rollback_versions_table_format,
2930
aks_machine_list_table_format,
3031
aks_machine_show_table_format,
3132
aks_operation_show_table_format,
@@ -275,6 +276,12 @@ def load_command_table(self, _):
275276
g.custom_command("update", "aks_agentpool_update", supports_no_wait=True)
276277
g.custom_command("delete", "aks_agentpool_delete", supports_no_wait=True)
277278
g.custom_command("get-upgrades", "aks_agentpool_get_upgrade_profile")
279+
g.custom_command(
280+
"get-rollback-versions",
281+
"aks_agentpool_get_rollback_versions",
282+
table_transformer=aks_agentpool_rollback_versions_table_format
283+
)
284+
g.custom_command("rollback", "aks_agentpool_rollback", supports_no_wait=True)
278285
g.custom_command("stop", "aks_agentpool_stop", supports_no_wait=True)
279286
g.custom_command("start", "aks_agentpool_start", supports_no_wait=True)
280287
g.custom_command(

src/aks-preview/azext_aks_preview/custom.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,71 @@ def aks_agentpool_get_upgrade_profile(cmd, # pylint: disable=unused-argument
17771777
return client.get_upgrade_profile(resource_group_name, cluster_name, nodepool_name)
17781778

17791779

1780+
def aks_agentpool_get_rollback_versions(cmd, # pylint: disable=unused-argument
1781+
client,
1782+
resource_group_name,
1783+
cluster_name,
1784+
nodepool_name):
1785+
"""Get rollback versions for a nodepool."""
1786+
upgrade_profile = client.get_upgrade_profile(resource_group_name, cluster_name, nodepool_name)
1787+
return upgrade_profile.recently_used_versions
1788+
1789+
1790+
def aks_agentpool_rollback(cmd, # pylint: disable=unused-argument
1791+
client,
1792+
resource_group_name,
1793+
cluster_name,
1794+
nodepool_name,
1795+
kubernetes_version=None,
1796+
node_image_version=None,
1797+
aks_custom_headers=None,
1798+
if_match=None,
1799+
if_none_match=None,
1800+
no_wait=False):
1801+
"""Rollback a nodepool to N-1 (previously used configuration)."""
1802+
1803+
# Get the current agent pool
1804+
current_agentpool = client.get(resource_group_name, cluster_name, nodepool_name)
1805+
1806+
# Get upgrade profile to get recently used versions
1807+
upgrade_profile = client.get_upgrade_profile(resource_group_name, cluster_name, nodepool_name)
1808+
1809+
# Check if rollback versions are available
1810+
if not upgrade_profile.recently_used_versions:
1811+
raise CLIError("No rollback versions are available for this nodepool.")
1812+
1813+
# If no specific versions are provided, use the most recent (N-1) version
1814+
if not kubernetes_version and not node_image_version:
1815+
most_recent = upgrade_profile.recently_used_versions[0]
1816+
kubernetes_version = most_recent.orchestrator_version
1817+
node_image_version = most_recent.node_image_version
1818+
1819+
# Update the agent pool configuration with rollback versions
1820+
if kubernetes_version:
1821+
current_agentpool.orchestrator_version = kubernetes_version
1822+
if node_image_version:
1823+
current_agentpool.node_image_version = node_image_version
1824+
1825+
# Set custom headers if provided
1826+
headers = get_aks_custom_headers(aks_custom_headers)
1827+
if if_match:
1828+
headers['If-Match'] = if_match
1829+
if if_none_match:
1830+
headers['If-None-Match'] = if_none_match
1831+
1832+
# Perform the rollback by updating the agent pool
1833+
# Server-side will validate the versions
1834+
return sdk_no_wait(
1835+
no_wait,
1836+
client.begin_create_or_update,
1837+
resource_group_name,
1838+
cluster_name,
1839+
nodepool_name,
1840+
current_agentpool,
1841+
headers=headers if headers else None
1842+
)
1843+
1844+
17801845
def aks_agentpool_stop(cmd, # pylint: disable=unused-argument
17811846
client,
17821847
resource_group_name,

0 commit comments

Comments
 (0)