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

[connectedk8s] Update extension CLI to v1.10.6 #8477

Draft
wants to merge 35 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c5748fb
add null check for empty kube-config in connectedk8s proxy scenario
Nov 22, 2024
24168df
Tidying - ruff and type annotations fix (#25)
dimbleby Nov 22, 2024
0154caf
initial commit move utils
JorgeDaboub Dec 4, 2024
3957d55
enable at token refresh
JorgeDaboub Dec 4, 2024
8f3c46b
clean up
JorgeDaboub Dec 4, 2024
b664f00
fix lint errors
JorgeDaboub Dec 4, 2024
77a0482
fix lint errors
JorgeDaboub Dec 5, 2024
cbd32b1
Add Kubectl Check (#29)
JorgeDaboub Dec 10, 2024
3bef318
Pull Arc-Proxy from MAR (#28)
JorgeDaboub Jan 9, 2025
a957a46
initial
atchutbarli Jan 30, 2025
ea257b9
final message
atchutbarli Jan 31, 2025
e08ab00
multiline
atchutbarli Jan 31, 2025
bd7ebb4
add telemetry for error
atchutbarli Dec 3, 2024
8d27137
spaces
atchutbarli Dec 4, 2024
e12a9c8
tests
atchutbarli Jan 29, 2025
9035d70
typo
atchutbarli Jan 29, 2025
bc9c7cb
indent
atchutbarli Jan 29, 2025
3d41b0f
Update k8s-custom-pipelines.yml
atchutbarli Jan 30, 2025
673d580
format
atchutbarli Jan 30, 2025
a6b383f
tests
atchutbarli Jan 30, 2025
e685cfb
formatting
atchutbarli Jan 30, 2025
e046cf7
format
atchutbarli Jan 30, 2025
440c32e
add test
atchutbarli Jan 30, 2025
1821d64
format
atchutbarli Jan 31, 2025
939847f
update connectedk8s cli version and release notes (#31)
bavneetsingh16 Feb 5, 2025
6dcc8c4
features
atchutbarli Feb 7, 2025
796064d
format
atchutbarli Feb 10, 2025
7defeb2
format
atchutbarli Feb 10, 2025
4ef443c
singlequote
atchutbarli Feb 11, 2025
f3bcdbb
warnings
atchutbarli Feb 11, 2025
d0d8b3b
change helm package download path to mcr (#32)
bavneetsingh16 Feb 13, 2025
ef98f54
update connectedk8s cli version and release notes
Feb 14, 2025
bf82be9
update release notes
Feb 14, 2025
51ef990
update description in release notes
Feb 14, 2025
3831cda
remove custom test files
Feb 14, 2025
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
5 changes: 5 additions & 0 deletions src/connectedk8s/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
Release History
===============

1.10.6
++++++
* Added support for downloading helm binaries from MCR.
* Added warnings for custom location feature based on Service Principal Name or User permissions to retrieve OID.

1.10.5
++++++
* Fixed bug impacting long-running operations of the az connectedk8s proxy command.
Expand Down
9 changes: 8 additions & 1 deletion src/connectedk8s/azext_connectedk8s/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,13 @@
"Failed to save cluster diagnostic checks job log"
)

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.
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.
For guidance, refer to: https://aka.ms/enable-customlocation"""

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"""


# Diagnostic Results Name
Outbound_Connectivity_Check_Result_String = "Outbound Network Connectivity"
Outbound_Connectivity_Check_Failed_For_Cluster_Connect = (
Expand All @@ -475,7 +482,7 @@

# URL constants
CLIENT_PROXY_MCR_TARGET = "mcr.microsoft.com/azureconnectivity/proxy"
HELM_STORAGE_URL = "https://k8connecthelm.azureedge.net"
HELM_MCR_URL = "mcr.microsoft.com/azurearck8s/helm"
HELM_VERSION = "v3.12.2"
Download_And_Install_Kubectl_Fault_Type = "Failed to download and install kubectl"
Azure_Access_Token_Variable = "AZURE_ACCESS_TOKEN"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
CredentialResults,
)

from azext_connectedk8s.vendored_sdks.preview_2024_07_01.models import (
CredentialResults,
)

logger = get_logger(__name__)


Expand Down
76 changes: 37 additions & 39 deletions src/connectedk8s/azext_connectedk8s/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
import stat
import tempfile
import time
import urllib.request
from base64 import b64decode, b64encode
from concurrent.futures import ThreadPoolExecutor
from subprocess import DEVNULL, PIPE, Popen
from typing import TYPE_CHECKING, Any, Iterable

import oras.client # type: ignore[import-untyped]
import yaml
from azure.cli.command_modules.role import graph_client_factory
from azure.cli.core import get_default_cli, telemetry
Expand Down Expand Up @@ -968,7 +968,8 @@ def create_connectedk8s(
raise CLIInternalError(
"Timed out waiting for Agent State to reach terminal state."
)

if cl_oid and enable_custom_locations and cl_oid == custom_locations_oid:
logger.warning(consts.Manual_Custom_Location_Oid_Warning)
return put_cc_response


Expand Down Expand Up @@ -1169,20 +1170,23 @@ def install_helm_client() -> str:
telemetry.add_extension_event(
"connectedk8s", {"Context.Default.AzureCLI.MachineType": machine_type}
)

# Set helm binary download & install locations
if operating_system == "windows":
download_location_string = f".azure\\helm\\{consts.HELM_VERSION}\\helm-{consts.HELM_VERSION}-{operating_system}-amd64.zip"
download_location_string = f".azure\\helm\\{consts.HELM_VERSION}"
download_file_name = f"helm-{consts.HELM_VERSION}-{operating_system}-amd64.zip"
install_location_string = (
f".azure\\helm\\{consts.HELM_VERSION}\\{operating_system}-amd64\\helm.exe"
)
requestUri = f"{consts.HELM_STORAGE_URL}/helmsigned/helm-{consts.HELM_VERSION}-{operating_system}-amd64.zip"
artifactTag = f"helm-{consts.HELM_VERSION}-{operating_system}-amd64"
elif operating_system == "linux" or operating_system == "darwin":
download_location_string = f".azure/helm/{consts.HELM_VERSION}/helm-{consts.HELM_VERSION}-{operating_system}-amd64.tar.gz"
download_location_string = f".azure/helm/{consts.HELM_VERSION}"
download_file_name = (
f"helm-{consts.HELM_VERSION}-{operating_system}-amd64.tar.gz"
)
install_location_string = (
f".azure/helm/{consts.HELM_VERSION}/{operating_system}-amd64/helm"
)
requestUri = f"{consts.HELM_STORAGE_URL}/helm/helm-{consts.HELM_VERSION}-{operating_system}-amd64.tar.gz"
artifactTag = f"helm-{consts.HELM_VERSION}-{operating_system}-amd64"
else:
telemetry.set_exception(
exception="Unsupported OS for installing helm client",
Expand Down Expand Up @@ -1215,11 +1219,15 @@ def install_helm_client() -> str:
logger.warning(
"Downloading helm client for first time. This can take few minutes..."
)
client = oras.client.OrasClient()
retry_count = 3
retry_delay = 5
for i in range(retry_count):
try:
response = urllib.request.urlopen(requestUri)
client.pull(
target=f"{consts.HELM_MCR_URL}:{artifactTag}",
outdir=download_location,
)
break
except Exception as e:
if i == retry_count - 1:
Expand All @@ -1236,34 +1244,21 @@ def install_helm_client() -> str:
)
time.sleep(retry_delay)

responseContent = response.read()
response.close()

# Creating the compressed helm binaries
try:
with open(download_location, "wb") as f:
f.write(responseContent)
except Exception as e:
telemetry.set_exception(
exception=e,
fault_type=consts.Create_HelmExe_Fault_Type,
summary="Unable to create helm executable",
)
reco_str = f"Please ensure that you delete the directory '{download_dir}' before trying again."
raise ClientRequestError(
"Failed to create helm executable." + str(e), recommendation=reco_str
)
# Extract the archive.
try:
shutil.unpack_archive(download_location, download_dir)
extract_dir = download_location
download_location = os.path.expanduser(
os.path.join(download_location, download_file_name)
)
shutil.unpack_archive(download_location, extract_dir)
os.chmod(install_location, os.stat(install_location).st_mode | stat.S_IXUSR)
except Exception as e:
telemetry.set_exception(
exception=e,
fault_type=consts.Extract_HelmExe_Fault_Type,
summary="Unable to extract helm executable",
)
reco_str = f"Please ensure that you delete the directory '{download_dir}' before trying again."
reco_str = f"Please ensure that you delete the directory '{extract_dir}' before trying again."
raise ClientRequestError(
"Failed to extract helm executable." + str(e), recommendation=reco_str
)
Expand Down Expand Up @@ -2839,16 +2834,17 @@ def enable_features(
if custom_token_passed is True
else get_subscription_id(cmd.cli_ctx)
)
enable_cl, custom_locations_oid = check_cl_registration_and_get_oid(
final_enable_cl, custom_locations_oid = check_cl_registration_and_get_oid(
cmd, cl_oid, subscription_id
)
if not enable_cluster_connect and enable_cl:
if not enable_cluster_connect and final_enable_cl:
enable_cluster_connect = True
logger.warning(
"Enabling 'custom-locations' feature will enable 'cluster-connect' feature too."
)
if not enable_cl:
if not final_enable_cl:
features.remove("custom-locations")
logger.warning(consts.Custom_Location_Enable_Failed_warning)
if len(features) == 0:
raise ClientRequestError("Failed to enable 'custom-locations' feature.")

Expand Down Expand Up @@ -2972,7 +2968,7 @@ def enable_features(
cmd_helm_upgrade.extend(
["--set", "systemDefaultValues.clusterconnect-agent.enabled=true"]
)
if enable_cl:
if final_enable_cl:
cmd_helm_upgrade.extend(
["--set", "systemDefaultValues.customLocations.enabled=true"]
)
Expand Down Expand Up @@ -3000,7 +2996,8 @@ def enable_features(
raise CLIInternalError(
str.format(consts.Error_enabling_Features, helm_upgrade_error_message)
)

if cl_oid and final_enable_cl and cl_oid == custom_locations_oid:
logger.warning(consts.Manual_Custom_Location_Oid_Warning)
return str.format(
consts.Successfully_Enabled_Features, features, connected_cluster.name
)
Expand Down Expand Up @@ -3822,8 +3819,7 @@ def check_cl_registration_and_get_oid(
cmd: CLICommmand, cl_oid: str | None, subscription_id: str | None
) -> tuple[bool, str]:
print(
f"Step: {utils.get_utctimestring()}: Checking Microsoft.ExtendedLocation RP Registration state for this Subscription, and get OID, "
"if registered "
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"
)
enable_custom_locations = True
custom_locations_oid = ""
Expand All @@ -3847,8 +3843,8 @@ def check_cl_registration_and_get_oid(
except Exception as e:
enable_custom_locations = False
warn_msg = (
"Unable to fetch registration state of 'Microsoft.ExtendedLocation'. Failed to enable "
"'custom-locations' feature. This is fine if not required. Proceeding with helm install."
"The custom location feature was not enabled because the custom location OID could not be retrieved. Please refer to: https://aka.ms/enable-customlocation "
"Proceeding with helm install..."
)
logger.warning(warn_msg)
telemetry.set_exception(
Expand Down Expand Up @@ -3900,19 +3896,21 @@ def get_custom_locations_oid(cmd: CLICommmand, cl_oid: str | None) -> str:
return cl_oid
except Exception as e:
# Encountered exeption while fetching OID, log error
log_string = "Unable to fetch the Object ID of the Azure AD application used by Azure Arc service. "
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."

telemetry.set_exception(
exception=e,
fault_type=consts.Custom_Locations_OID_Fetch_Fault_Type_Exception,
summary="Unable to fetch oid for custom locations app.",
)
# If Cl OID was input, use that
if cl_oid:
log_string += "Proceeding with the Object ID provided to enable the 'custom-locations' feature."
log_string += "\nProceeding with using the OID manually provided to enable the 'custom-locations' feature without validation."
log_string += "\nIf the manual OID is invalid, custom location may not be properly enabled."
logger.warning(log_string)
return cl_oid
# If no Cl OID was input, log a Warning and return empty for OID
log_string += "Unable to enable the 'custom-locations' feature. " + str(e)
log_string += "\nException encountered: " + str(e)
logger.warning(log_string)
return ""

Expand Down
Loading
Loading