Skip to content

Commit 9df2ace

Browse files
committed
Simulate a failed agent upgrade scenario to test the error message display.
1 parent b3112a8 commit 9df2ace

5 files changed

Lines changed: 243 additions & 9 deletions

File tree

src/connectedk8s/HISTORY.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ Release History
55

66
1.10.8
77
++++++
8-
* Add checks for the Graytown bundle feature flag in the 'connectedk8s connect' and 'connectedk8s update' commands.
9-
* Display a more detailed error message from the agent-update-validator in the 'connectedk8s upgrade' command.
8+
* Add checks for the bundling feature flag in the 'connectedk8s connect' and 'connectedk8s update' commands.
9+
* Display a more detailed error message when the 'connectedk8s upgrade' command fails with the bundling feature enabled.
1010

1111
1.10.7
1212
++++++
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"systemDefaultValues": {
3+
"agent-update-validator": {
4+
"config_dp_endpoint_override": "http://fake-dp-server-service.graytowntest.svc.cluster.local:80"
5+
}
6+
}
7+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: clusterconfig.azure.com/v1beta1
2+
kind: ExtensionConfig
3+
metadata:
4+
name: fake-ext-config
5+
namespace: azure-arc
6+
spec:
7+
dependentBundles:
8+
- appdevaddons
9+
extensionType: microsoft.graytown.testextension
10+
isDependentOnBundle: true
11+
parameter:
12+
releaseTrain: Preview
13+
repoUrl: https://graytownacr.azurecr.io/helm/graytowntest
14+
scope: cluster
15+
version: 1.302.0
16+
status:
17+
syncStatus:
18+
isSyncedWithAzure: true
19+
lastSyncTime: '2025-06-23T21:14:39.000Z'

src/connectedk8s/azext_connectedk8s/tests/latest/test_connectedk8s_scenario.py

Lines changed: 147 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
import stat
1313
import subprocess
1414
import time
15+
from datetime import datetime
1516
from subprocess import PIPE, Popen
1617

1718
import oras.client # type: ignore[import-untyped]
1819
import psutil
1920
import requests
21+
import yaml
2022
from azure.cli.core import get_default_cli
2123
from azure.cli.core.azclierror import (
2224
ArgumentUsageError,
@@ -343,7 +345,7 @@ def test_connect_withbundlefeatureflag(self, resource_group):
343345
with self.assertLogs(level="WARNING") as cm:
344346
self.cmd(
345347
"connectedk8s connect -g {rg} -n {name} -l {location} --disable-auto-upgrade --kube-config {kubeconfig} \
346-
--kube-context {managed_cluster_name}-admin --config extensionSets.versionManagedExtensions='preview' --yes",
348+
--kube-context {managed_cluster_name}-admin --config extensionSets.versionManagedExtensions='preview' --yes",
347349
checks=[
348350
self.check("resourceGroup", "{rg}"),
349351
self.check("name", "{name}"),
@@ -495,16 +497,16 @@ def test_update_withbundlefeatureflag(self, resource_group):
495497

496498
self.cmd(
497499
"k8s-extension create --cluster-name {name} --resource-group {rg} --cluster-type connectedClusters \
498-
--extension-type microsoft.iotoperations.platform --name azure-iot-operations-platform \
499-
--release-train preview --auto-upgrade-minor-version False --config installTrustManager=true \
500-
--config installCertManager=true --version 0.7.6 --release-namespace cert-manager --scope cluster"
500+
--extension-type microsoft.iotoperations.platform --name azure-iot-operations-platform \
501+
--release-train preview --auto-upgrade-minor-version False --config installTrustManager=true \
502+
--config installCertManager=true --version 0.7.6 --release-namespace cert-manager --scope cluster"
501503
)
502504

503505
self.cmd(
504506
"k8s-extension create --cluster-name {name} --resource-group {rg} --cluster-type connectedClusters \
505-
--extension-type microsoft.azure.secretstore --name azure-secret-store --auto-upgrade-minor-version False \
506-
--config rotationPollIntervalInSeconds=120 --config validatingAdmissionPolicies.applyPolicies=false \
507-
--scope cluster"
507+
--extension-type microsoft.azure.secretstore --name azure-secret-store --auto-upgrade-minor-version False \
508+
--config rotationPollIntervalInSeconds=120 --config validatingAdmissionPolicies.applyPolicies=false \
509+
--scope cluster"
508510
)
509511

510512
# With bundle extensions installed on the cluster, the bundle feature flag cannot be set to 'disabled'
@@ -521,6 +523,144 @@ def test_update_withbundlefeatureflag(self, resource_group):
521523
)
522524
self.assertEqual(configmap_bundle_feature_flag, "enabled")
523525

526+
@live_only()
527+
@ResourceGroupPreparer(
528+
name_prefix="conk8stest", location=CONFIG["location"], random_name_length=16
529+
)
530+
def test_upgrade_with_agentupdatevalidator(self, resource_group):
531+
managed_cluster_name = self.create_random_name(prefix="test-upgrade", length=24)
532+
kubeconfig = _get_test_data_file(managed_cluster_name + "-config.yaml")
533+
self.kwargs.update(
534+
{
535+
"rg": resource_group,
536+
"name": self.create_random_name(prefix="cc-", length=12),
537+
"kubeconfig": kubeconfig,
538+
"managed_cluster_name": managed_cluster_name,
539+
"location": CONFIG["location"],
540+
}
541+
)
542+
self.cmd("aks create -g {rg} -n {managed_cluster_name} --generate-ssh-keys")
543+
self.cmd(
544+
"aks get-credentials -g {rg} -n {managed_cluster_name} -f {kubeconfig} --admin"
545+
)
546+
547+
self.cmd(
548+
"connectedk8s connect -g {rg} -n {name} -l {location} --disable-auto-upgrade --kube-config {kubeconfig} \
549+
--kube-context {managed_cluster_name}-admin --config extensionSets.versionManagedExtensions='enabled'",
550+
checks=[
551+
self.check("resourceGroup", "{rg}"),
552+
self.check("name", "{name}"),
553+
self.check(
554+
"arcAgentryConfigurations[0].settings.versionManagedExtensions",
555+
"enabled",
556+
),
557+
],
558+
)
559+
560+
ns = "azure-arc"
561+
config_dir = os.path.join(
562+
os.path.dirname(__file__), "agent_update_validator_test_config"
563+
)
564+
arc_agent_values_path = os.path.join(config_dir, "ArcAgentryValues.json")
565+
fake_ext_config_path = os.path.join(config_dir, "fake_ext_config.yml")
566+
567+
with open(fake_ext_config_path) as file:
568+
data = yaml.safe_load(file)
569+
570+
# Update the lastSyncTime to the current time
571+
current_time = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.000Z")
572+
data["status"]["syncStatus"]["lastSyncTime"] = current_time
573+
574+
with open(fake_ext_config_path, "w") as file:
575+
yaml.dump(data, file, default_flow_style=False)
576+
577+
kubectl_client_location = install_kubectl_client()
578+
579+
# Create the fake extension config to simulate an extension that depends on the bundle
580+
subprocess.run(
581+
[
582+
kubectl_client_location,
583+
"apply",
584+
"-f",
585+
fake_ext_config_path,
586+
"--namespace",
587+
ns,
588+
"--kubeconfig",
589+
kubeconfig,
590+
"--context",
591+
f"{managed_cluster_name}-admin",
592+
]
593+
)
594+
595+
os.environ["HELMVALUESPATH"] = arc_agent_values_path
596+
597+
with self.assertRaisesRegex(
598+
CLIError, "Error: Failed to validate agent update.*?no such host"
599+
):
600+
self.cmd(
601+
"connectedk8s upgrade -g {rg} -n {name} --agent-version 1.26.0 --kube-config {kubeconfig} \
602+
--kube-context {managed_cluster_name}-admin",
603+
)
604+
605+
os.environ["HELMVALUESPATH"] = ""
606+
607+
# Remove the finalizers from the fake extension config to allow deletion
608+
subprocess.run(
609+
[
610+
kubectl_client_location,
611+
"patch",
612+
"extensionconfig",
613+
"fake-ext-config",
614+
"--namespace",
615+
ns,
616+
"--type=json",
617+
"-p",
618+
'[{"op": "remove", "path": "/metadata/finalizers"}]',
619+
"--kubeconfig",
620+
kubeconfig,
621+
"--context",
622+
f"{managed_cluster_name}-admin",
623+
]
624+
)
625+
626+
subprocess.Popen(
627+
[
628+
kubectl_client_location,
629+
"delete",
630+
"extensionconfig",
631+
"fake-ext-config",
632+
"--namespace",
633+
ns,
634+
"--kubeconfig",
635+
kubeconfig,
636+
"--context",
637+
f"{managed_cluster_name}-admin",
638+
]
639+
)
640+
641+
time.sleep(60)
642+
643+
cmd_output = subprocess.Popen(
644+
[
645+
kubectl_client_location,
646+
"get",
647+
"extensionconfig",
648+
"fake-ext-config",
649+
"--namespace",
650+
ns,
651+
"--kubeconfig",
652+
kubeconfig,
653+
"--context",
654+
f"{managed_cluster_name}-admin",
655+
],
656+
stdout=PIPE,
657+
stderr=PIPE,
658+
)
659+
_, error_get_ext_config = cmd_output.communicate()
660+
661+
# Should fail to get the extension config as it has been deleted
662+
assert cmd_output.returncode != 0
663+
524664
@live_only()
525665
@ResourceGroupPreparer(
526666
name_prefix="conk8stest", location=CONFIG["location"], random_name_length=16

testing/test/configurations/BundleFeatureFlag.Tests.ps1

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,74 @@ Describe 'Setting Bundle Feature Flag Scenario' {
149149
$n | Should -BeLessOrEqual $MAX_RETRY_ATTEMPTS
150150
}
151151

152+
It "Verify the error message when failing to upgrade the agent with bundle feature flag enabled" {
153+
az connectedk8s update -n $ENVCONFIG.arcClusterName -g $ENVCONFIG.resourceGroup --auto-upgrade false `
154+
--config extensionSets.versionManagedExtensions='enabled'
155+
$? | Should -BeTrue
156+
Start-Sleep -Seconds 10
157+
158+
# Loop and retry until the configuration installs
159+
$n = 0
160+
do
161+
{
162+
$output = az connectedk8s show -n $ENVCONFIG.arcClusterName -g $ENVCONFIG.resourceGroup
163+
$jsonOutput = [System.Text.Json.JsonDocument]::Parse($output)
164+
$provisioningState = ($output | ConvertFrom-Json).provisioningState
165+
$bundleFeatureFlag = $jsonOutput.RootElement.GetProperty("arcAgentryConfigurations")[0].GetProperty("settings").GetProperty("versionManagedExtensions").GetString()
166+
Write-Host "Provisioning State: $provisioningState"
167+
Write-Host "Bundle Feature Flag: $bundleFeatureFlag"
168+
if ($provisioningState -eq $SUCCEEDED -and $bundleFeatureFlag -eq "enabled")
169+
{
170+
break
171+
}
172+
Start-Sleep -Seconds 10
173+
$n += 1
174+
} while ($n -le $MAX_RETRY_ATTEMPTS)
175+
$n | Should -BeLessOrEqual $MAX_RETRY_ATTEMPTS
176+
177+
$ns = "azure-arc"
178+
$rootDir = Resolve-Path "$PSScriptRoot/../../../"
179+
180+
$configDir = Join-Path $rootDir "src/connectedk8s/azext_connectedk8s/tests/latest/agent_update_validator_test_config"
181+
$arcAgentValuesPath = Join-Path $configDir "ArcAgentryValues.json"
182+
$fakeExtConfigPath = Join-Path $configDir "fake_ext_config.yml"
183+
184+
$tmpDir = Join-Path $rootDir "testing/tmp"
185+
186+
if (-not (Test-Path $tmpDir)) {
187+
New-Item -ItemType Directory -Path $tmpDir | Out-Null
188+
}
189+
190+
# Update lastSyncTime in fake_ext_config.yml
191+
$updatedFakeExtConfigPath = Join-Path $tmpDir "fake_ext_config_updated.yml"
192+
$data = Get-Content $fakeExtConfigPath | ConvertFrom-Yaml
193+
$data.status.syncStatus.lastSyncTime = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ss.000Z")
194+
$data | ConvertTo-Yaml | Set-Content $updatedFakeExtConfigPath
195+
196+
# Create the fake extension config to simulate an extension that depends on the bundle
197+
kubectl apply -f $updatedFakeExtConfigPath --namespace $ns
198+
$? | Should -BeTrue
199+
200+
$ENV:HELMVALUESPATH = $arcAgentValuesPath
201+
202+
$output = & {
203+
az connectedk8s upgrade -n $ENVCONFIG.arcClusterName -g $ENVCONFIG.resourceGroup --agent-version "1.26.0" 2>&1 | Out-String
204+
}
205+
$output | Should -Match "Error: Failed to validate agent update.*no such host"
206+
207+
$env:HELMVALUESPATH = ""
208+
209+
# Remove the finalizers from the fake extension config to allow deletion
210+
kubectl patch extensionconfig fake-ext-config --namespace $ns --type=json -p '[{"op": "remove", "path": "/metadata/finalizers"}]'
211+
212+
Start-Process kubectl -ArgumentList "delete extensionconfig fake-ext-config --namespace $ns" -NoNewWindow
213+
214+
Start-Sleep -Seconds 60
215+
216+
kubectl get extensionconfig fake-ext-config --namespace $ns 2>&1
217+
$? | Should -BeFalse
218+
}
219+
152220
It "Delete the connected instance" {
153221
az connectedk8s delete -n $ENVCONFIG.arcClusterName -g $ENVCONFIG.resourceGroup --force -y
154222
$? | Should -BeTrue

0 commit comments

Comments
 (0)