Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions src/aks-preview/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ To release a new version, please select a new version number (usually plus 1 to
Pending
+++++++
* Fix `--localdns-config` parameter to handle null values in JSON configuration files gracefully, preventing crashes when DNS override sections are null.
* Add jwtauthenticator commands `az aks jwtauthenticator add/update/show/list/delete` to manage JWT authenticators for a managed cluster.

18.0.0b40
+++++++
Expand Down
4 changes: 4 additions & 0 deletions src/aks-preview/azext_aks_preview/_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,7 @@ def get_keyvault_client(cli_ctx, subscription_id=None):

def cf_load_balancers(cli_ctx, *_):
return get_container_service_client(cli_ctx).load_balancers


def cf_jwt_authenticators(cli_ctx, *_):
return get_container_service_client(cli_ctx).jwt_authenticators
49 changes: 49 additions & 0 deletions src/aks-preview/azext_aks_preview/_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,52 @@ def _get_extension_type_versions_table_row(result):
return OrderedDict([
('versions', result['properties']['version'])
])


def aks_jwtauthenticator_list_table_format(results):
"""Format a list of JWT authenticators as summary results for display with "-o table". """
return [_get_jwtauthenticator_table_row(result) for result in results]


def aks_jwtauthenticator_show_table_format(result):
"""Format a JWT authenticator as summary results for display with "-o table". """
return _get_jwtauthenticator_table_row(result)


def _get_jwtauthenticator_table_row(result):
"""Extract information from a JWT authenticator for table display."""
properties = result.get('properties', {})
provisioningState = properties.get('provisioningState', '')
issuer = properties.get('issuer', {})

issuer_url = issuer.get('url', '') if issuer else ''
audiences = issuer.get('audiences', []) if issuer else []
audience_list = ', '.join(audiences) if audiences else ''

claim_mappings = properties.get('claimMappings', {})
has_claim_mappings = 'No'
if claim_mappings:
has_username = bool(claim_mappings.get('username'))
has_groups = bool(claim_mappings.get('groups'))
has_uid = bool(claim_mappings.get('uid'))
has_extra = (claim_mappings.get('extra') and
isinstance(claim_mappings['extra'], list) and
len(claim_mappings['extra']) > 0)

if has_username or has_groups or has_uid or has_extra:
has_claim_mappings = 'Yes'

claim_rules = properties.get('claimValidationRules', [])
user_rules = properties.get('userValidationRules', [])
has_claim_rules = 'Yes' if claim_rules else 'No'
has_user_rules = 'Yes' if user_rules else 'No'

return OrderedDict([
('name', result.get('name', '')),
('provisioningState', provisioningState),
('issuerUrl', issuer_url),
('audiences', audience_list),
('hasClaimMappings', has_claim_mappings),
('hasClaimRules', has_claim_rules),
('hasUserRules', has_user_rules),
])
106 changes: 106 additions & 0 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -4082,3 +4082,109 @@
type: string
short-summary: Name of the identity binding to show.
"""

helps['aks jwtauthenticator'] = """
type: group
short-summary: Commands to manage JWT authenticators in Azure Kubernetes Service.
long-summary: JWT authenticators enable external JWT token validation for Kubernetes authentication.
For more information, see https://aka.ms/aks-external-issuers-docs.
"""

helps['aks jwtauthenticator add'] = """
type: command
short-summary: Add a JWT authenticator to a managed cluster.
long-summary: Adds a new JWT authenticator configuration to the managed cluster for external JWT validation.
The configuration will be applied to the kube-apiserver to enable JWT token authentication.
parameters:
- name: --cluster-name
type: string
short-summary: Name of the managed cluster.
- name: --name -n
type: string
short-summary: Name of the JWT authenticator (must be unique within the cluster).
- name: --config-file
type: string
short-summary: Path to JSON file containing the JWT authenticator configuration.
long-summary: The JSON file should contain the properties schema for one JWT authenticator.
For details on how to configure the properties of a JWT authenticator, please refer to the Kubernetes documentation
at https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-authentication-configuration.
Please note that not all fields available in the Kubernetes documentation are supported by AKS.
For troubleshooting, please see https://aka.ms/aks-external-issuers-docs.
- name: --aks-custom-headers
type: string
short-summary: Send custom headers. When specified, format should be Key1=Value1,Key2=Value2
examples:
- name: Add a JWT authenticator from a configuration file
text: az aks jwtauthenticator add -g MyResourceGroup --cluster-name MyCluster --name myjwt --config-file config.json
"""

helps['aks jwtauthenticator update'] = """
type: command
short-summary: Update a JWT authenticator in a managed cluster.
long-summary: Updates an existing JWT authenticator configuration. The entire configuration will be replaced
with the configuration from the provided file.
parameters:
- name: --cluster-name
type: string
short-summary: Name of the managed cluster.
- name: --name -n
type: string
short-summary: Name of the JWT authenticator to update.
- name: --config-file
type: string
short-summary: Path to JSON file containing the updated JWT authenticator configuration.
long-summary: The JSON file should contain the properties schema for one JWT authenticator.
For details on how to configure the properties of a JWT authenticator, please refer to the Kubernetes documentation
at https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-authentication-configuration.
Please note that not all fields available in the Kubernetes documentation are supported by AKS.
For troubleshooting, please see https://aka.ms/aks-external-issuers-docs.
- name: --aks-custom-headers
type: string
short-summary: Send custom headers. When specified, format should be Key1=Value1
examples:
- name: Update a JWT authenticator configuration
text: az aks jwtauthenticator update -g MyResourceGroup --cluster-name MyCluster --name myjwt --config-file updated-config.json
"""

helps['aks jwtauthenticator delete'] = """
type: command
short-summary: Delete a JWT authenticator from a managed cluster.
long-summary: Removes the JWT authenticator configuration from the managed cluster and updates the kube-apiserver.
parameters:
- name: --cluster-name
type: string
short-summary: Name of the managed cluster.
- name: --name -n
type: string
short-summary: Name of the JWT authenticator to delete.
examples:
- name: Delete a JWT authenticator
text: az aks jwtauthenticator delete -g MyResourceGroup --cluster-name MyCluster --name myjwt
"""

helps['aks jwtauthenticator list'] = """
type: command
short-summary: List all JWT authenticators in a managed cluster.
parameters:
- name: --cluster-name
type: string
short-summary: Name of the managed cluster.
examples:
- name: List all JWT authenticators in a cluster
text: az aks jwtauthenticator list -g MyResourceGroup --cluster-name MyCluster
"""

helps['aks jwtauthenticator show'] = """
type: command
short-summary: Show details of a JWT authenticator in a managed cluster.
parameters:
- name: --cluster-name
type: string
short-summary: Name of the managed cluster.
- name: --name -n
type: string
short-summary: Name of the JWT authenticator to show.
examples:
- name: Show a specific JWT authenticator configuration
text: az aks jwtauthenticator show -g MyResourceGroup --cluster-name MyCluster --name myjwt
"""
21 changes: 21 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2927,6 +2927,27 @@ def load_arguments(self, _):
action="store_true",
)

# JWT Authenticator commands
with self.argument_context("aks jwtauthenticator") as c:
c.argument("cluster_name", help="The cluster name.")
c.argument(
"aks_custom_headers",
help="Send custom headers. When specified, format should be Key1=Value1,Key2=Value2.",
)

for scope in ['aks jwtauthenticator add',
'aks jwtauthenticator update',
'aks jwtauthenticator delete',
'aks jwtauthenticator show']:
with self.argument_context(scope) as c:
c.argument('name', options_list=['--name', '-n'], required=True, help='Name of the JWT authenticator.')

for scope in ['aks jwtauthenticator add',
'aks jwtauthenticator update']:
with self.argument_context(scope) as c:
c.argument('config_file', options_list=['--config-file'], type=file_type, completer=FilesCompleter(),
help='Path to the JSON configuration file containing JWT authenticator properties.')


def _get_default_install_location(exe_name):
system = platform.system()
Expand Down
39 changes: 39 additions & 0 deletions src/aks-preview/azext_aks_preview/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
cf_operations,
cf_load_balancers,
cf_identity_bindings,
cf_jwt_authenticators,
)

from azext_aks_preview._format import (
Expand Down Expand Up @@ -46,6 +47,8 @@
aks_extension_type_show_table_format,
aks_extension_type_versions_list_table_format,
aks_extension_type_version_show_table_format,
aks_jwtauthenticator_list_table_format,
aks_jwtauthenticator_show_table_format,
)

from knack.log import get_logger
Expand Down Expand Up @@ -141,6 +144,12 @@ def load_command_table(self, _):
client_factory=cf_mc_snapshots,
)

jwt_authenticators_sdk = CliCommandType(
operations_tmpl="azext_aks_preview.vendored_sdks.azure_mgmt_preview_aks."
"operations._jwt_authenticators_operations#JWTAuthenticatorsOperations.{}",
client_factory=cf_jwt_authenticators,
)

# AKS managed cluster commands
with self.command_group(
"aks",
Expand Down Expand Up @@ -517,3 +526,33 @@ def load_command_table(self, _):
g.custom_command("delete", "aks_identity_binding_delete")
g.custom_show_command("show", "aks_identity_binding_show")
g.custom_command("list", "aks_identity_binding_list")

# AKS jwt authenticator commands
with self.command_group(
"aks jwtauthenticator", jwt_authenticators_sdk, client_factory=cf_jwt_authenticators,
) as g:
g.custom_command(
"add",
"aks_jwtauthenticator_add",
supports_no_wait=True
)
g.custom_command(
"update",
"aks_jwtauthenticator_update",
supports_no_wait=True
)
g.custom_command(
"delete",
"aks_jwtauthenticator_delete",
supports_no_wait=True, confirmation=True
)
g.custom_command(
"list",
"aks_jwtauthenticator_list",
table_transformer=aks_jwtauthenticator_list_table_format
)
g.custom_show_command(
"show",
"aks_jwtauthenticator_show",
table_transformer=aks_jwtauthenticator_show_table_format
)
88 changes: 88 additions & 0 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@
from azext_aks_preview.machine import (
add_machine,
)
from azext_aks_preview.jwtauthenticator import (
aks_jwtauthenticator_add_internal,
aks_jwtauthenticator_update_internal,
)
from azure.cli.command_modules.acs._helpers import (
get_user_assigned_identity_by_resource_id
)
Expand Down Expand Up @@ -4501,3 +4505,87 @@ def aks_bastion(cmd, client, resource_group_name, name, bastion=None, port=None,
aks_identity_binding_delete = aks_ib_cmd_delete
aks_identity_binding_show = aks_ib_cmd_show
aks_identity_binding_list = aks_ib_cmd_list


# JWT Authenticator commands
def aks_jwtauthenticator_add(
cmd,
client,
resource_group_name,
cluster_name,
name,
config_file,
aks_custom_headers=None,
no_wait=False
):
headers = get_aks_custom_headers(aks_custom_headers)
existingJWTAuthenticator = None
try:
existingJWTAuthenticator = client.get(resource_group_name, cluster_name, name, headers=headers)
except ResourceNotFoundError:
pass

if existingJWTAuthenticator:
raise ClientRequestError(
f"JWT Authenticator '{name}' already exists. Please use 'az aks jwtauthenticator update' to update it."
)

raw_parameters = locals()
return aks_jwtauthenticator_add_internal(
cmd,
client,
raw_parameters,
headers,
no_wait,
)


def aks_jwtauthenticator_update(
cmd,
client,
resource_group_name,
cluster_name,
name,
config_file,
aks_custom_headers=None,
no_wait=False
):
headers = get_aks_custom_headers(aks_custom_headers)
raw_parameters = locals()
return aks_jwtauthenticator_update_internal(
cmd,
client,
raw_parameters,
headers,
no_wait,
)


def aks_jwtauthenticator_delete(
cmd,
client,
resource_group_name,
cluster_name,
name,
aks_custom_headers=None,
no_wait=False
):
headers = get_aks_custom_headers(aks_custom_headers)
return sdk_no_wait(
no_wait,
client.begin_delete,
resource_group_name,
cluster_name,
name,
headers=headers,
)


def aks_jwtauthenticator_list(cmd, client, resource_group_name, cluster_name, aks_custom_headers=None):
headers = get_aks_custom_headers(aks_custom_headers)
return client.list_by_managed_cluster(resource_group_name, cluster_name, headers=headers)


def aks_jwtauthenticator_show(cmd, client, resource_group_name, cluster_name, name, aks_custom_headers=None):
headers = get_aks_custom_headers(aks_custom_headers)
return client.get(resource_group_name, cluster_name, name, headers=headers)
Loading
Loading