Skip to content

Commit

Permalink
refactor: federation improvements + template increment. (#363)
Browse files Browse the repository at this point in the history
  • Loading branch information
digimaun authored Sep 17, 2024
1 parent d21e54d commit aa3ec27
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 23 deletions.
2 changes: 1 addition & 1 deletion azext_edge/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import os

VERSION = "0.7.0a8"
VERSION = "0.7.0a9"
EXTENSION_NAME = "azure-iot-ops"
EXTENSION_ROOT = os.path.dirname(os.path.abspath(__file__))
USER_AGENT = "IotOperationsCliExtension/{}".format(VERSION)
2 changes: 0 additions & 2 deletions azext_edge/edge/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,6 @@ def load_iotops_help():
] = """
type: command
short-summary: Remove a user-assigned managed identity from the instance.
long-summary: |
This operation includes removing federation of the identity.
examples:
- name: Remove the desired user-assigned managed identity from the instance.
Expand Down
2 changes: 2 additions & 0 deletions azext_edge/edge/commands_edge.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,15 @@ def instance_identity_assign(
mi_user_assigned: str,
federated_credential_name: Optional[str] = None,
usage_type: IdentityUsageType = IdentityUsageType.dataflow.value,
use_self_hosted_issuer: Optional[bool] = None,
**kwargs,
) -> dict:
return Instances(cmd).add_mi_user_assigned(
name=instance_name,
resource_group_name=resource_group_name,
mi_user_assigned=mi_user_assigned,
federated_credential_name=federated_credential_name,
use_self_hosted_issuer=use_self_hosted_issuer,
usage_type=usage_type,
**kwargs,
)
Expand Down
2 changes: 2 additions & 0 deletions azext_edge/edge/commands_secretsync.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def secretsync_enable(
keyvault_resource_id: str,
spc_name: Optional[str] = None,
skip_role_assignments: Optional[bool] = None,
use_self_hosted_issuer: Optional[bool] = None,
**kwargs,
) -> dict:
return Instances(cmd).enable_secretsync(
Expand All @@ -30,6 +31,7 @@ def secretsync_enable(
keyvault_resource_id=keyvault_resource_id,
spc_name=spc_name,
skip_role_assignments=skip_role_assignments,
use_self_hosted_issuer=use_self_hosted_issuer,
**kwargs,
)

Expand Down
6 changes: 6 additions & 0 deletions azext_edge/edge/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ def load_iotops_arguments(self, _):
options_list=["--fc"],
help="The federated credential name.",
)
context.argument(
"use_self_hosted_issuer",
options_list=["--self-hosted-issuer"],
arg_type=get_three_state_flag(),
help="Use the self-hosted oidc issuer for federation.",
)

with self.argument_context("iot ops identity") as context:
context.argument(
Expand Down
50 changes: 32 additions & 18 deletions azext_edge/edge/providers/orchestration/resources/instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,22 @@ def remove_mi_user_assigned(
mi_resource_id_container = parse_resource_id(mi_user_assigned)
instance = self.show(name=name, resource_group_name=resource_group_name)

cluster_resource = self.get_resource_map(instance).connected_cluster.resource
custom_location = self._get_associated_cl(instance)
namespace = custom_location["properties"]["namespace"]
oidc_issuer = self._ensure_oidc_issuer(cluster_resource)

cred_subject = get_cred_subject(namespace=namespace, service_account_name=SERVICE_ACCOUNT_DATAFLOW)
if not federated_credential_name:
federated_credential_name = get_fc_name(
cluster_name=cluster_resource["name"],
oidc_issuer=oidc_issuer,
subject=cred_subject,
)
self.unfederate_msi(mi_resource_id_container, federated_credential_name)
# TODO - @digimaun
# cluster_resource = self.get_resource_map(instance).connected_cluster.resource
# custom_location = self._get_associated_cl(instance)
# namespace = custom_location["properties"]["namespace"]
# oidc_issuer = self._ensure_oidc_issuer(cluster_resource)

# cred_subject = get_cred_subject(namespace=namespace, service_account_name=SERVICE_ACCOUNT_DATAFLOW)
# if not federated_credential_name:
# federated_credential_name = get_fc_name(
# cluster_name=cluster_resource["name"],
# oidc_issuer=oidc_issuer,
# subject=cred_subject,
# )
# TODO - @digimaun
if federated_credential_name:
self.unfederate_msi(mi_resource_id_container, federated_credential_name)

identity: dict = instance.get("identity", {})
if not identity:
Expand All @@ -190,6 +193,7 @@ def add_mi_user_assigned(
resource_group_name: str,
mi_user_assigned: str,
federated_credential_name: Optional[str] = None,
use_self_hosted_issuer: Optional[bool] = None,
**kwargs,
):
"""
Expand All @@ -199,7 +203,7 @@ def add_mi_user_assigned(
mi_resource_id_container = parse_resource_id(mi_user_assigned)
instance = self.show(name=name, resource_group_name=resource_group_name)
cluster_resource = self.get_resource_map(instance).connected_cluster.resource
oidc_issuer = self._ensure_oidc_issuer(cluster_resource)
oidc_issuer = self._ensure_oidc_issuer(cluster_resource, use_self_hosted_issuer)
custom_location = self._get_associated_cl(instance)
namespace = custom_location["properties"]["namespace"]
cred_subject = get_cred_subject(namespace=namespace, service_account_name=SERVICE_ACCOUNT_DATAFLOW)
Expand Down Expand Up @@ -234,6 +238,7 @@ def enable_secretsync(
federated_credential_name: Optional[str] = None,
spc_name: Optional[str] = None,
skip_role_assignments: bool = False,
use_self_hosted_issuer: Optional[bool] = None,
**kwargs,
):
mi_resource_id_container = parse_resource_id(mi_user_assigned)
Expand All @@ -242,6 +247,8 @@ def enable_secretsync(
keyvault: dict = self.resource_client.resources.get_by_id(
resource_id=keyvault_resource_id_container.resource_id, api_version=KEYVAULT_CLOUD_API_VERSION
)
# TODO - @digimaun
self.msi_mgmt_client._config.subscription_id = mi_resource_id_container.subscription_id
mi_user_assigned: dict = self.msi_mgmt_client.user_assigned_identities.get(
resource_group_name=mi_resource_id_container.resource_group_name,
resource_name=mi_resource_id_container.resource_name,
Expand All @@ -258,7 +265,7 @@ def enable_secretsync(
custom_location = self._get_associated_cl(instance)
namespace = custom_location["properties"]["namespace"]
cred_subject = get_cred_subject(namespace=namespace, service_account_name=SERVICE_ACCOUNT_SECRETSYNC)
oidc_issuer = self._ensure_oidc_issuer(cluster_resource)
oidc_issuer = self._ensure_oidc_issuer(cluster_resource, use_self_hosted_issuer)

cl_resources = resource_map.connected_cluster.get_aio_resources(custom_location_id=custom_location["id"])
secretsync_spc = self._find_existing_spc(cl_resources)
Expand Down Expand Up @@ -371,7 +378,7 @@ def _attempt_keyvault_role_assignments(self, keyvault: dict, mi_user_assigned: d
scope=keyvault["id"],
)

def _ensure_oidc_issuer(self, cluster_resource: dict) -> str:
def _ensure_oidc_issuer(self, cluster_resource: dict, use_self_hosted_issuer: Optional[bool] = None) -> str:
enabled_oidc = cluster_resource["properties"].get("oidcIssuerProfile", {}).get("enabled", False)
enabled_wlif = (
cluster_resource["properties"].get("securityProfile", {}).get("workloadIdentity", {}).get("enabled", False)
Expand All @@ -396,9 +403,10 @@ def _ensure_oidc_issuer(self, cluster_resource: dict) -> str:
raise ValidationError(error)

oidc_issuer_profile: dict = cluster_resource["properties"]["oidcIssuerProfile"]
issuer_url = oidc_issuer_profile.get("issuerUrl") or oidc_issuer_profile.get("selfHostedIssuerUrl")
issuer_key = "selfHostedIssuerUrl" if use_self_hosted_issuer else "issuerUrl"
issuer_url = oidc_issuer_profile.get(issuer_key)
if not issuer_url:
raise ValidationError("No issuer Url is available. Check cluster config.")
raise ValidationError(f"No {issuer_key} is available. Check cluster config.")
return issuer_url

def federate_msi(
Expand All @@ -418,6 +426,8 @@ def federate_msi(
"No new federated credential will be created."
)
return
# TODO - @digimaun
self.msi_mgmt_client._config.subscription_id = mi_resource_id_container.subscription_id
self.msi_mgmt_client.federated_identity_credentials.create_or_update(
resource_group_name=mi_resource_id_container.resource_group_name,
resource_name=mi_resource_id_container.resource_name,
Expand All @@ -436,6 +446,8 @@ def unfederate_msi(
mi_resource_id_container: ResourceIdContainer,
federated_credential_name: str,
):
# TODO - @digimaun
self.msi_mgmt_client._config.subscription_id = mi_resource_id_container.subscription_id
self.msi_mgmt_client.federated_identity_credentials.delete(
resource_group_name=mi_resource_id_container.resource_group_name,
resource_name=mi_resource_id_container.resource_name,
Expand All @@ -445,6 +457,8 @@ def unfederate_msi(
def _find_federated_cred(
self, mi_resource_id_container: ResourceIdContainer, issuer_url: str, subject: str
) -> Optional[dict]:
# TODO - @digimaun
self.msi_mgmt_client._config.subscription_id = mi_resource_id_container.subscription_id
cred_iteratable = self.msi_mgmt_client.federated_identity_credentials.list(
resource_group_name=mi_resource_id_container.resource_group_name,
resource_name=mi_resource_id_container.resource_name,
Expand Down
4 changes: 2 additions & 2 deletions azext_edge/edge/providers/orchestration/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def copy(self) -> "TemplateBlueprint":
IOT_OPERATIONS_VERSION_MONIKER = "v0.7.0-preview"

M2_ENABLEMENT_TEMPLATE = TemplateBlueprint(
commit_id="0f5d0d234045e945ab7808c6aa2a44dc0ce77723",
commit_id="a3a65663793fc761928c736b5e7732c68c0591d6",
content={
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
Expand Down Expand Up @@ -218,7 +218,7 @@ def copy(self) -> "TemplateBlueprint":
"AIO_EXTENSION_SUFFIX": "[take(uniqueString(resourceId('Microsoft.Kubernetes/connectedClusters', parameters('clusterName'))), 5)]",
"VERSIONS": {
"platform": "0.7.6",
"aio": "0.7.13",
"aio": "0.7.21",
"secretSyncController": "0.6.4",
"edgeStorageAccelerator": "2.1.1-preview",
"openServiceMesh": "1.2.9",
Expand Down

0 comments on commit aa3ec27

Please sign in to comment.