Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
25 changes: 22 additions & 3 deletions python-clusters/attach-aks-cluster/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from dku_utils.cluster import make_overrides, get_subscription_id
from dku_azure.auth import get_credentials_from_connection_info, get_credentials_from_connection_infoV2
from dku_azure.utils import run_and_process_cloud_error
from dku_azure.utils import run_and_process_cloud_error, get_instance_metadata, get_subscription_id
from dku_azure.utils import run_and_process_cloud_error, get_instance_metadata, get_subscription_id, patch_kube_config_with_aad

class MyCluster(Cluster):
def __init__(self, cluster_id, cluster_name, config, plugin_config):
Expand All @@ -30,6 +30,13 @@ def _get_credentials(self):

def start(self):
credentials, subscription_id = self._get_credentials()
connection_info = self.config.get("connectionInfoV2",{"identityType":"default"})
identity_type = connection_info.get("identityType", "default")
identity_label = None
if identity_type == 'user-assigned':
identity_label = connection_info.get("userManagedIdentityId", "")
elif identity_type == 'service-principal':
identity_label = connection_info.get("clientId", "")

# Cluster name
cluster_name = self.config.get("cluster", None)
Expand All @@ -46,16 +53,28 @@ def start(self):

clusters_client = ContainerServiceClient(credentials, subscription_id)

# Retrieve the cluster to check whether or not the Azure AD with Azure RBAC is activated
def do_get():
return clusters_client.managed_clusters.get(resource_group, cluster_name)
get_cluster_result = run_and_process_cloud_error(do_get)
print("Amandine - managed: {}".format(get_cluster_result.aad_profile.managed))
patch_user_in_kubeconfig = get_cluster_result.aad_profile.managed

# Get kubeconfig
logging.info("Fetching kubeconfig for cluster %s in %s", cluster_name, resource_group)
def do_fetch():
return clusters_client.managed_clusters.list_cluster_admin_credentials(resource_group, cluster_name)
get_credentials_result = run_and_process_cloud_error(do_fetch)

kube_config_content = get_credentials_result.kubeconfigs[0].value.decode('utf8')
kube_config_path = os.path.join(os.getcwd(), 'kube_config')
if patch_user_in_kubeconfig:
kube_config_yaml = patch_kube_config_with_aad(kube_config_content, identity_type, identity_label)
else:
kube_config_yaml = yaml.safe_load(kube_config_content)
with open(kube_config_path, 'w') as f:
f.write(kube_config_content)
overrides = make_overrides(self.config, yaml.safe_load(kube_config_content), kube_config_path)
yaml.dump(kube_config_yaml, f)
overrides = make_overrides(self.config, kube_config_yaml, kube_config_path)

# Get other cluster infos
def do_inspect():
Expand Down
14 changes: 11 additions & 3 deletions python-clusters/create-aks-cluster/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from dku_kube.nvidia_utils import add_gpu_driver_if_needed
from dku_azure.auth import get_credentials_from_connection_info, get_credentials_from_connection_infoV2
from dku_azure.clusters import ClusterBuilder
from dku_azure.utils import run_and_process_cloud_error, get_subnet_id, get_instance_metadata, get_subscription_id
from dku_azure.utils import run_and_process_cloud_error, get_subnet_id, get_instance_metadata, get_subscription_id, patch_kube_config_with_aad
from dku_azure.auth import AzureIdentityCredentialAdapter

class MyCluster(Cluster):
Expand Down Expand Up @@ -43,6 +43,13 @@ def start(self):
Build the create cluster request.
"""
credentials, subscription_id, managed_identity_id = self._get_credentials()
connection_info = self.config.get("connectionInfoV2",{"identityType":"default"})
identity_type = connection_info.get("identityType", "default")
identity_label = None
if identity_type == 'user-assigned':
identity_label = connection_info.get("userManagedIdentityId", "")
elif identity_type == 'service-principal':
identity_label = connection_info.get("clientId", "")

# Fetch metadata about the instance
metadata = get_instance_metadata()
Expand Down Expand Up @@ -385,12 +392,13 @@ def do_fetch():
kube_config_content = get_credentials_result.kubeconfigs[0].value.decode("utf8")
logging.info("Writing kubeconfig file...")
kube_config_path = os.path.join(os.getcwd(), "kube_config")
kube_config_yaml = patch_kube_config_with_aad(kube_config_content, identity_type, identity_label)
with open(kube_config_path, 'w') as f:
f.write(kube_config_content)
yaml.dump(kube_config_yaml, f)

overrides = make_overrides(
self.config,
yaml.safe_load(kube_config_content),
kube_config_yaml,
kube_config_path,
acr_name = None if _is_none_or_blank(acr_attachment) else acr_attachment["name"],
)
Expand Down
3 changes: 2 additions & 1 deletion python-lib/dku_azure/clusters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dku_azure.utils import get_instance_metadata, get_vm_resource_id, get_host_network, get_subnet_id
from azure.mgmt.containerservice.models import ManagedClusterAgentPoolProfile, ManagedClusterAPIServerAccessProfile, ManagedClusterServicePrincipalProfile
from azure.mgmt.containerservice.models import ContainerServiceNetworkProfile, ManagedCluster, ManagedClusterIdentity
from azure.mgmt.containerservice.models import ContainerServiceNetworkProfile, ManagedCluster, ManagedClusterAADProfile
from dku_utils.access import _default_if_blank, _merge_objects, _print_as_json

import logging, copy, json
Expand Down Expand Up @@ -147,6 +147,7 @@ def build(self):
cluster_params["node_resource_group"] = self.node_resource_group
cluster_params["service_principal_profile"] = self.cluster_sp
cluster_params["identity"] = self.identity
cluster_params["aad_profile"] = ManagedClusterAADProfile(managed=True, enable_azure_rbac=True)
cluster_params["identity_profile"] = self.identity_profile
cluster_params["kubernetes_version"] = self.cluster_version
cluster_params["agent_pool_profiles"] = self.node_pools
Expand Down
44 changes: 43 additions & 1 deletion python-lib/dku_azure/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import requests
import json
import yaml
import logging

from msrestazure.azure_exceptions import CloudError
Expand Down Expand Up @@ -88,3 +88,45 @@ def get_host_network(credentials=None, resource_group=None, connection_info=None
logging.info("VNET: {}".format(vnet))
logging.info("SUBNET ID: {}".format(subnet_id))
return vnet, subnet_id

def patch_kube_config_with_aad(kube_config_string, authentication_mode, identity_label):
kube_config = yaml.safe_load(kube_config_string)

kubelogin_command_options = ['get-token', '--login', 'msi', '--server-id', '6dae42f8-4368-4678-94ff-3960e28e3630']

additional_options = []
if authentication_mode == 'service-principal':
additional_options = ['--identity-resource-id', identity_label]
elif authentication_mode == 'user-assigned':
if identity_label.startswith("/"):
additional_options = ['--identity-resource-id', identity_label]
else:
additional_options = ['--client-id', identity_label]

kubelogin_command_options = kubelogin_command_options + additional_options

kube_config_user = {
'name': kube_config['contexts'][0]['context']['user'],
'user': {
'exec': {
'apiVersion': 'client.authentication.k8s.io/v1beta1',
'command': 'kubelogin',
'args': kubelogin_command_options
}
}
}

kube_config['users'] = [kube_config_user]

return kube_config

# determine which is the authentication mode
# depending on the authentication mode, the derivation command kubelogin options will be different
#
# SERVICE-PRINCIPAL
# kubelogin get-token -l msi --server-id 6dae42f8-4368-4678-94ff-3960e28e3630 --identity-resource-id /subscriptions/8c59bf15-b4a9-4398-a354-d2a4e7d60e2a/resourcegroups/jcasoli-fm/providers/Microsoft.ManagedIdentity/userAssignedIdentities/dss-id-jcasoli
# USER-ASSIGNED
# kubelogin get-token -l msi --server-id 6dae42f8-4368-4678-94ff-3960e28e3630 --client-id de4cab2c-359c-4970-8032-89bee12a7d31
# DEFAULT
# kubelogin get-token -l msi --server-id 6dae42f8-4368-4678-94ff-3960e28e3630