Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AKS] support --yes for az aks mesh upgrade commands. #7508

Merged
merged 20 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ To release a new version, please select a new version number (usually plus 1 to

Pending
+++++++

3.0.0b6
deveshdama marked this conversation as resolved.
Show resolved Hide resolved
+++++++
* support `--yes` for `az aks mesh upgrade rollback` and `az aks mesh upgrade complete` commands.
deveshdama marked this conversation as resolved.
Show resolved Hide resolved
* Minimise the roles needed to introduce for Elastic SAN for enabling Azure Container Storage with elasticSan storagepool type.

3.0.0b5
Expand Down
16 changes: 16 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,22 @@ def load_arguments(self, _):
"revision", validator=validate_azure_service_mesh_revision, required=True
)

with self.argument_context("aks mesh upgrade rollback") as c:
deveshdama marked this conversation as resolved.
Show resolved Hide resolved
c.argument(
"yes",
options_list=["--yes", "-y"],
help="Do not prompt for confirmation.",
action="store_true"
)

with self.argument_context("aks mesh upgrade complete") as c:
c.argument(
"yes",
options_list=["--yes", "-y"],
help="Do not prompt for confirmation.",
action="store_true"
)

with self.argument_context("aks approuting enable") as c:
c.argument("enable_kv", action="store_true")
c.argument("keyvault_id", options_list=["--attach-kv"])
Expand Down
11 changes: 8 additions & 3 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -3028,26 +3028,31 @@ def aks_mesh_upgrade_complete(
cmd,
client,
resource_group_name,
name):
name,
yes=False
):
return _aks_mesh_update(
cmd,
client,
resource_group_name,
name,
yes=yes,
mesh_upgrade_command=CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_COMPLETE)


def aks_mesh_upgrade_rollback(
cmd,
client,
resource_group_name,
name
name,
yes=False
):
return _aks_mesh_update(
cmd,
client,
resource_group_name,
name,
yes=yes,
mesh_upgrade_command=CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_ROLLBACK)


Expand All @@ -3070,6 +3075,7 @@ def _aks_mesh_update(
enable_egress_gateway=None,
disable_egress_gateway=None,
revision=None,
yes=False,
mesh_upgrade_command=None,
):
raw_parameters = locals()
Expand All @@ -3083,7 +3089,6 @@ def _aks_mesh_update(
raw_parameters=raw_parameters,
resource_type=CUSTOM_MGMT_AKS_PREVIEW,
)

try:
mc = aks_update_decorator.fetch_mc()
mc = aks_update_decorator.update_azure_service_mesh_profile(mc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2123,6 +2123,7 @@ def get_initial_service_mesh_profile(self) -> ServiceMeshProfile:

def _handle_upgrade_asm(self, new_profile: ServiceMeshProfile) -> Tuple[ServiceMeshProfile, bool]:
mesh_upgrade_command = self.raw_param.get("mesh_upgrade_command", None)
supress_confirmation = self.raw_param.get("yes", False)
updated = False

# deal with mesh upgrade commands
Expand Down Expand Up @@ -2152,9 +2153,10 @@ def _handle_upgrade_asm(self, new_profile: ServiceMeshProfile) -> Tuple[ServiceM
f"Please ensure all data plane workloads have been rolled over to revision {revision_to_keep} "
"so that they are still part of the mesh.\nAre you sure you want to proceed?"
)
if prompt_y_n(msg, default="y"):
new_profile.istio.revisions.remove(revision_to_remove)
updated = True
if not supress_confirmation and not prompt_y_n(msg, default="n"):
deveshdama marked this conversation as resolved.
Show resolved Hide resolved
raise DecoratorEarlyExitException()
new_profile.istio.revisions.remove(revision_to_remove)
updated = True
elif (
mesh_upgrade_command == CONST_AZURE_SERVICE_MESH_UPGRADE_COMMAND_START and
requested_revision is not None
Expand Down

Large diffs are not rendered by default.

148 changes: 144 additions & 4 deletions src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import os
import pty
import semver
import subprocess
import tempfile
import time
Expand Down Expand Up @@ -85,11 +86,31 @@ def _get_lts_version(self, location):
lts_versions = sorted(lts_versions, key=lambda x: list(map(int, x.split("."))), reverse=True)
return lts_versions[0] if lts_versions else None

def _sort_revisions(self, revisions):
def _convert_revision_to_semver(rev):
sr = rev.replace("asm-", "")
sv = sr.replace("-", ".", 1)
# Add a custom patch version of 0
sv += ".0"
return semver.VersionInfo.parse(sv)

sorted_revisions = sorted(revisions, key=_convert_revision_to_semver)
return sorted_revisions

def _get_asm_supported_revision(self, location):
revisions_cmd = f"aks mesh get-revisions -l {location}"
revisions = self.cmd(revisions_cmd).get_output_in_json()
assert len(revisions["meshRevisions"]) > 0
return revisions['meshRevisions'][0]['revision']
mesh_revisions_cmd = f"aks mesh get-revisions -l {location}"
mesh_revisions = self.cmd(mesh_revisions_cmd).get_output_in_json()
assert len(mesh_revisions["meshRevisions"]) > 0
revisions = [r["revision"] for r in mesh_revisions["meshRevisions"]]
sorted_revisons = self._sort_revisions(revisions)
return sorted_revisons[0]

def _get_asm_upgrade_version(self, resource_group, name):
get_upgrade_cmd = f"aks mesh get-upgrades --resource-group={resource_group} --name={name}"
res = self.cmd(get_upgrade_cmd).get_output_in_json()
assert "upgrades" in res and len(res["upgrades"]) > 0
sorted_upgrades = self._sort_revisions(res["upgrades"])
return sorted_upgrades[0]

@classmethod
def generate_ssh_keys(cls):
Expand Down Expand Up @@ -11920,6 +11941,125 @@ def test_aks_azure_service_mesh_with_egress_gateway(
],
)

@AllowLargeResponse()
@AKSCustomResourceGroupPreparer(
random_name_length=17, name_prefix="clitest", location="westus2"
)
def test_aks_azure_service_mesh_canary_upgrade(
self, resource_group, resource_group_location
):
"""This test case exercises canary upgrade with mesh upgrade command.

It creates a cluster, enables azure service mesh, fetches available upgrade revison, upgrades the cluster then disable it.
"""

# reset the count so in replay mode the random names will start with 0
self.test_resources_count = 0
# kwargs for string formatting
aks_name = self.create_random_name("cliakstest", 16)
installed_revision = self._get_asm_supported_revision(resource_group_location)
deveshdama marked this conversation as resolved.
Show resolved Hide resolved
self.kwargs.update(
{
"resource_group": resource_group,
"name": aks_name,
"location": resource_group_location,
"ssh_key_value": self.generate_ssh_keys(),
"revision": installed_revision,
}
)

# create cluster with --enable-azure-service-mesh
create_cmd = (
"aks create --resource-group={resource_group} --name={name} --location={location} "
"--aks-custom-headers=AKSHTTPCustomFeatures=Microsoft.ContainerService/AzureServiceMeshPreview "
"--ssh-key-value={ssh_key_value} "
"--enable-azure-service-mesh --revision={revision} --output=json"
)
aks_cluster_create = self.cmd(
create_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("serviceMeshProfile.mode", "Istio"),
self.exists("serviceMeshProfile.istio.revisions")
],
).get_output_in_json()
cluster_create_revisions = aks_cluster_create["serviceMeshProfile"]["istio"]["revisions"]
assert len(cluster_create_revisions) == 1
assert installed_revision in cluster_create_revisions

# get upgrades
upgrade_revision = self._get_asm_upgrade_version(resource_group, "{name}")
self.kwargs.update(
{
"upgrade_revision": upgrade_revision,
}
)
# upgrade start
upgrade_start_cmd = (
"aks mesh upgrade start --revision {upgrade_revision} --resource-group={resource_group} --name={name}"
)
aks_cluster_upgrade_start = self.cmd(
upgrade_start_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("serviceMeshProfile.mode", "Istio"),
],
).get_output_in_json()
upgrade_start_revisions = aks_cluster_upgrade_start["serviceMeshProfile"]["istio"]["revisions"]
print(upgrade_start_revisions)
assert len(upgrade_start_revisions) == 2
assert installed_revision in upgrade_start_revisions and upgrade_revision in upgrade_start_revisions

# upgrade rollback
upgrade_rollback_cmd = (
"aks mesh upgrade rollback --resource-group={resource_group} --name={name} --yes"
)
aks_cluster_upgrade_rollback = self.cmd(
upgrade_rollback_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("serviceMeshProfile.mode", "Istio"),
],
).get_output_in_json()
upgrade_rollback_revisions = aks_cluster_upgrade_rollback["serviceMeshProfile"]["istio"]["revisions"]
assert len(upgrade_rollback_revisions) == 1
assert installed_revision in upgrade_rollback_revisions

# upgrade start again
self.cmd(
upgrade_start_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("serviceMeshProfile.mode", "Istio"),
],
)

# upgrade complete
upgrade_complete_cmd = (
"aks mesh upgrade complete --resource-group={resource_group} --name={name} --yes"
deveshdama marked this conversation as resolved.
Show resolved Hide resolved
)
aks_cluster_upgrade_complete = self.cmd(
upgrade_complete_cmd,
checks=[
self.check("provisioningState", "Succeeded"),
self.check("serviceMeshProfile.mode", "Istio"),
],
).get_output_in_json()
upgrade_complete_revisions = aks_cluster_upgrade_complete["serviceMeshProfile"]["istio"]["revisions"]
assert len(upgrade_complete_revisions) == 1
assert upgrade_revision in upgrade_complete_revisions

# delete the cluster
delete_cmd = (
"aks delete --resource-group={resource_group} --name={name} --yes --no-wait"
)
self.cmd(
delete_cmd,
checks=[
self.is_empty(),
],
)

@AllowLargeResponse()
@AKSCustomResourceGroupPreparer(
random_name_length=17, name_prefix="clitest", location="westus2"
Expand Down
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 = "3.0.0b5"
VERSION = "3.0.0b6"
deveshdama marked this conversation as resolved.
Show resolved Hide resolved

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