Skip to content

Commit 4c12ec3

Browse files
[connectedk8s] Update extension CLI to v1.10.6 (#8476)
1 parent c898278 commit 4c12ec3

File tree

5 files changed

+75
-131
lines changed

5 files changed

+75
-131
lines changed

src/connectedk8s/HISTORY.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
Release History
44
===============
55

6+
1.10.6
7+
++++++
8+
* Added support for downloading helm binaries from MCR.
9+
* Added warnings for custom location feature based on Service Principal Name or User permissions to retrieve OID.
10+
611
1.10.5
712
++++++
813
* Fixed bug impacting long-running operations of the az connectedk8s proxy command.

src/connectedk8s/azext_connectedk8s/_constants.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,13 @@
454454
"Failed to save cluster diagnostic checks job log"
455455
)
456456

457+
Manual_Custom_Location_Oid_Warning = """Important! Custom Location feature enablement can't be validated when using a manually provided OID. If the custom location feature is not enabled, you may encounter an error when creating the custom location.
458+
After creating the custom location, run `az customlocation show` and check that ProvisioningState is Succeeded. If ProvisoningState is Failed, then re-try this command with a valid custom location OID to enable the feature.
459+
For guidance, refer to: https://aka.ms/enable-customlocation"""
460+
461+
Custom_Location_Enable_Failed_warning = """Important! Custom Location feature wasn't enabled due to insufficient privileges on the Service Principal Name. If the custom location feature is not enabled, you will encounter an error when creating the custom location. Refer to: https://aka.ms/enable-cl-spn"""
462+
463+
457464
# Diagnostic Results Name
458465
Outbound_Connectivity_Check_Result_String = "Outbound Network Connectivity"
459466
Outbound_Connectivity_Check_Failed_For_Cluster_Connect = (
@@ -475,7 +482,7 @@
475482

476483
# URL constants
477484
CLIENT_PROXY_MCR_TARGET = "mcr.microsoft.com/azureconnectivity/proxy"
478-
HELM_STORAGE_URL = "https://k8connecthelm.azureedge.net"
485+
HELM_MCR_URL = "mcr.microsoft.com/azurearck8s/helm"
479486
HELM_VERSION = "v3.12.2"
480487
Download_And_Install_Kubectl_Fault_Type = "Failed to download and install kubectl"
481488
Azure_Access_Token_Variable = "AZURE_ACCESS_TOKEN"

src/connectedk8s/azext_connectedk8s/custom.py

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
import stat
1717
import tempfile
1818
import time
19-
import urllib.request
2019
from base64 import b64decode, b64encode
2120
from concurrent.futures import ThreadPoolExecutor
2221
from subprocess import DEVNULL, PIPE, Popen
2322
from typing import TYPE_CHECKING, Any, Iterable
2423

24+
import oras.client # type: ignore[import-untyped]
2525
import yaml
2626
from azure.cli.command_modules.role import graph_client_factory
2727
from azure.cli.core import get_default_cli, telemetry
@@ -968,7 +968,8 @@ def create_connectedk8s(
968968
raise CLIInternalError(
969969
"Timed out waiting for Agent State to reach terminal state."
970970
)
971-
971+
if cl_oid and enable_custom_locations and cl_oid == custom_locations_oid:
972+
logger.warning(consts.Manual_Custom_Location_Oid_Warning)
972973
return put_cc_response
973974

974975

@@ -1169,20 +1170,23 @@ def install_helm_client() -> str:
11691170
telemetry.add_extension_event(
11701171
"connectedk8s", {"Context.Default.AzureCLI.MachineType": machine_type}
11711172
)
1172-
11731173
# Set helm binary download & install locations
11741174
if operating_system == "windows":
1175-
download_location_string = f".azure\\helm\\{consts.HELM_VERSION}\\helm-{consts.HELM_VERSION}-{operating_system}-amd64.zip"
1175+
download_location_string = f".azure\\helm\\{consts.HELM_VERSION}"
1176+
download_file_name = f"helm-{consts.HELM_VERSION}-{operating_system}-amd64.zip"
11761177
install_location_string = (
11771178
f".azure\\helm\\{consts.HELM_VERSION}\\{operating_system}-amd64\\helm.exe"
11781179
)
1179-
requestUri = f"{consts.HELM_STORAGE_URL}/helmsigned/helm-{consts.HELM_VERSION}-{operating_system}-amd64.zip"
1180+
artifactTag = f"helm-{consts.HELM_VERSION}-{operating_system}-amd64"
11801181
elif operating_system == "linux" or operating_system == "darwin":
1181-
download_location_string = f".azure/helm/{consts.HELM_VERSION}/helm-{consts.HELM_VERSION}-{operating_system}-amd64.tar.gz"
1182+
download_location_string = f".azure/helm/{consts.HELM_VERSION}"
1183+
download_file_name = (
1184+
f"helm-{consts.HELM_VERSION}-{operating_system}-amd64.tar.gz"
1185+
)
11821186
install_location_string = (
11831187
f".azure/helm/{consts.HELM_VERSION}/{operating_system}-amd64/helm"
11841188
)
1185-
requestUri = f"{consts.HELM_STORAGE_URL}/helm/helm-{consts.HELM_VERSION}-{operating_system}-amd64.tar.gz"
1189+
artifactTag = f"helm-{consts.HELM_VERSION}-{operating_system}-amd64"
11861190
else:
11871191
telemetry.set_exception(
11881192
exception="Unsupported OS for installing helm client",
@@ -1215,11 +1219,15 @@ def install_helm_client() -> str:
12151219
logger.warning(
12161220
"Downloading helm client for first time. This can take few minutes..."
12171221
)
1222+
client = oras.client.OrasClient()
12181223
retry_count = 3
12191224
retry_delay = 5
12201225
for i in range(retry_count):
12211226
try:
1222-
response = urllib.request.urlopen(requestUri)
1227+
client.pull(
1228+
target=f"{consts.HELM_MCR_URL}:{artifactTag}",
1229+
outdir=download_location,
1230+
)
12231231
break
12241232
except Exception as e:
12251233
if i == retry_count - 1:
@@ -1236,34 +1244,21 @@ def install_helm_client() -> str:
12361244
)
12371245
time.sleep(retry_delay)
12381246

1239-
responseContent = response.read()
1240-
response.close()
1241-
1242-
# Creating the compressed helm binaries
1243-
try:
1244-
with open(download_location, "wb") as f:
1245-
f.write(responseContent)
1246-
except Exception as e:
1247-
telemetry.set_exception(
1248-
exception=e,
1249-
fault_type=consts.Create_HelmExe_Fault_Type,
1250-
summary="Unable to create helm executable",
1251-
)
1252-
reco_str = f"Please ensure that you delete the directory '{download_dir}' before trying again."
1253-
raise ClientRequestError(
1254-
"Failed to create helm executable." + str(e), recommendation=reco_str
1255-
)
12561247
# Extract the archive.
12571248
try:
1258-
shutil.unpack_archive(download_location, download_dir)
1249+
extract_dir = download_location
1250+
download_location = os.path.expanduser(
1251+
os.path.join(download_location, download_file_name)
1252+
)
1253+
shutil.unpack_archive(download_location, extract_dir)
12591254
os.chmod(install_location, os.stat(install_location).st_mode | stat.S_IXUSR)
12601255
except Exception as e:
12611256
telemetry.set_exception(
12621257
exception=e,
12631258
fault_type=consts.Extract_HelmExe_Fault_Type,
12641259
summary="Unable to extract helm executable",
12651260
)
1266-
reco_str = f"Please ensure that you delete the directory '{download_dir}' before trying again."
1261+
reco_str = f"Please ensure that you delete the directory '{extract_dir}' before trying again."
12671262
raise ClientRequestError(
12681263
"Failed to extract helm executable." + str(e), recommendation=reco_str
12691264
)
@@ -2839,16 +2834,17 @@ def enable_features(
28392834
if custom_token_passed is True
28402835
else get_subscription_id(cmd.cli_ctx)
28412836
)
2842-
enable_cl, custom_locations_oid = check_cl_registration_and_get_oid(
2837+
final_enable_cl, custom_locations_oid = check_cl_registration_and_get_oid(
28432838
cmd, cl_oid, subscription_id
28442839
)
2845-
if not enable_cluster_connect and enable_cl:
2840+
if not enable_cluster_connect and final_enable_cl:
28462841
enable_cluster_connect = True
28472842
logger.warning(
28482843
"Enabling 'custom-locations' feature will enable 'cluster-connect' feature too."
28492844
)
2850-
if not enable_cl:
2845+
if not final_enable_cl:
28512846
features.remove("custom-locations")
2847+
logger.warning(consts.Custom_Location_Enable_Failed_warning)
28522848
if len(features) == 0:
28532849
raise ClientRequestError("Failed to enable 'custom-locations' feature.")
28542850

@@ -2972,7 +2968,7 @@ def enable_features(
29722968
cmd_helm_upgrade.extend(
29732969
["--set", "systemDefaultValues.clusterconnect-agent.enabled=true"]
29742970
)
2975-
if enable_cl:
2971+
if final_enable_cl:
29762972
cmd_helm_upgrade.extend(
29772973
["--set", "systemDefaultValues.customLocations.enabled=true"]
29782974
)
@@ -3000,7 +2996,8 @@ def enable_features(
30002996
raise CLIInternalError(
30012997
str.format(consts.Error_enabling_Features, helm_upgrade_error_message)
30022998
)
3003-
2999+
if cl_oid and final_enable_cl and cl_oid == custom_locations_oid:
3000+
logger.warning(consts.Manual_Custom_Location_Oid_Warning)
30043001
return str.format(
30053002
consts.Successfully_Enabled_Features, features, connected_cluster.name
30063003
)
@@ -3822,8 +3819,7 @@ def check_cl_registration_and_get_oid(
38223819
cmd: CLICommmand, cl_oid: str | None, subscription_id: str | None
38233820
) -> tuple[bool, str]:
38243821
print(
3825-
f"Step: {utils.get_utctimestring()}: Checking Microsoft.ExtendedLocation RP Registration state for this Subscription, and get OID, "
3826-
"if registered "
3822+
f"Step: {utils.get_utctimestring()}: Checking Custom Location(Microsoft.ExtendedLocation) RP Registration state for this Subscription, and attempt to get the Custom Location Object ID (OID),if registered"
38273823
)
38283824
enable_custom_locations = True
38293825
custom_locations_oid = ""
@@ -3847,8 +3843,8 @@ def check_cl_registration_and_get_oid(
38473843
except Exception as e:
38483844
enable_custom_locations = False
38493845
warn_msg = (
3850-
"Unable to fetch registration state of 'Microsoft.ExtendedLocation'. Failed to enable "
3851-
"'custom-locations' feature. This is fine if not required. Proceeding with helm install."
3846+
"The custom location feature was not enabled because the custom location OID could not be retrieved. Please refer to: https://aka.ms/enable-customlocation "
3847+
"Proceeding with helm install..."
38523848
)
38533849
logger.warning(warn_msg)
38543850
telemetry.set_exception(
@@ -3900,19 +3896,21 @@ def get_custom_locations_oid(cmd: CLICommmand, cl_oid: str | None) -> str:
39003896
return cl_oid
39013897
except Exception as e:
39023898
# Encountered exeption while fetching OID, log error
3903-
log_string = "Unable to fetch the Object ID of the Azure AD application used by Azure Arc service. "
3899+
log_string = "Unable to fetch the Custom Location OID with permissions set on this account. The account does not have sufficient permissions to fetch or validate the OID."
3900+
39043901
telemetry.set_exception(
39053902
exception=e,
39063903
fault_type=consts.Custom_Locations_OID_Fetch_Fault_Type_Exception,
39073904
summary="Unable to fetch oid for custom locations app.",
39083905
)
39093906
# If Cl OID was input, use that
39103907
if cl_oid:
3911-
log_string += "Proceeding with the Object ID provided to enable the 'custom-locations' feature."
3908+
log_string += "\nProceeding with using the OID manually provided to enable the 'custom-locations' feature without validation."
3909+
log_string += "\nIf the manual OID is invalid, custom location may not be properly enabled."
39123910
logger.warning(log_string)
39133911
return cl_oid
39143912
# If no Cl OID was input, log a Warning and return empty for OID
3915-
log_string += "Unable to enable the 'custom-locations' feature. " + str(e)
3913+
log_string += "\nException encountered: " + str(e)
39163914
logger.warning(log_string)
39173915
return ""
39183916

0 commit comments

Comments
 (0)