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

Update ProvisionedClusters support #136

Closed
Closed
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
4 changes: 4 additions & 0 deletions src/k8s-extension/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Release History
===============

1.2.5
++++++++++++++++++
* Add support for Microsoft.HybridContainerService.ProvisionedClusters

1.2.4
++++++++++++++++++
* microsoft.azureml.kubernetes: Do not invoke `create_or_update` for already existed resources.
Expand Down
182 changes: 112 additions & 70 deletions src/k8s-extension/azext_k8s_extension/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,126 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azure.cli.core.commands.parameters import (
get_enum_type,
get_three_state_flag
)
from azure.cli.core.commands.parameters import get_enum_type, get_three_state_flag
from azure.cli.core.commands.validators import get_default_location_from_resource_group
from . import consts

from .action import (
AddConfigurationSettings,
AddConfigurationProtectedSettings
)
from .action import AddConfigurationSettings, AddConfigurationProtectedSettings


def load_arguments(self, _):
with self.argument_context(consts.EXTENSION_NAME) as c:
c.argument('location',
validator=get_default_location_from_resource_group)
c.argument('name',
options_list=['--name', '-n'],
help='Name of the extension instance')
c.argument('extension_type',
help='Name of the extension type.')
c.argument('cluster_name',
options_list=['--cluster-name', '-c'],
help='Name of the Kubernetes cluster')
c.argument('cluster_type',
arg_type=get_enum_type(['connectedClusters', 'managedClusters', 'appliances']),
options_list=['--cluster-type', '-t'],
help='Specify Arc clusters or AKS managed clusters or Arc appliances.')
c.argument('scope',
arg_type=get_enum_type(['cluster', 'namespace']),
help='Specify the extension scope.')
c.argument('auto_upgrade_minor_version',
arg_group="Version",
options_list=['--auto-upgrade-minor-version', '--auto-upgrade'],
arg_type=get_three_state_flag(),
help='Automatically upgrade minor version of the extension instance.')
c.argument('version',
arg_group="Version",
help='Specify the version to install for the extension instance if'
' --auto-upgrade-minor-version is not enabled.')
c.argument('release_train',
arg_group="Version",
help='Specify the release train for the extension type.')
c.argument('configuration_settings',
arg_group="Configuration",
options_list=['--configuration-settings', '--config-settings', '--config'],
action=AddConfigurationSettings,
nargs='+',
help='Configuration Settings as key=value pair. Repeat parameter for each setting')
c.argument('configuration_protected_settings',
arg_group="Configuration",
options_list=['--configuration-protected-settings', '--config-protected-settings', '--config-protected'],
action=AddConfigurationProtectedSettings,
nargs='+',
help='Configuration Protected Settings as key=value pair. Repeat parameter for each setting')
c.argument('configuration_settings_file',
arg_group="Configuration",
options_list=['--configuration-settings-file', '--config-settings-file', '--config-file'],
help='JSON file path for configuration-settings')
c.argument('configuration_protected_settings_file',
arg_group="Configuration",
options_list=['--configuration-protected-settings-file', '--config-protected-settings-file', '--config-protected-file'],
help='JSON file path for configuration-protected-settings')
c.argument('release_namespace',
help='Specify the namespace to install the extension release.')
c.argument('target_namespace',
help='Specify the target namespace to install to for the extension instance. This'
' parameter is required if extension scope is set to \'namespace\'')
c.argument("location", validator=get_default_location_from_resource_group)
c.argument(
"name", options_list=["--name", "-n"], help="Name of the extension instance"
)
c.argument("extension_type", help="Name of the extension type.")
c.argument(
"cluster_name",
options_list=["--cluster-name", "-c"],
help="Name of the Kubernetes cluster",
)
c.argument(
"cluster_type",
arg_type=get_enum_type(
[
"connectedClusters",
"managedClusters",
"appliances",
"provisionedClusters",
]
),
options_list=["--cluster-type", "-t"],
help="Specify Arc clusters or AKS managed clusters or Arc appliances.",
)
c.argument(
"cluster_resource_provider",
options_list=["--cluster-resource-provider", "--cluster-rp"],
help="Cluster Resource Provider name for this clusterType (Required for provisionedClusters)",
)
c.argument(
"scope",
arg_type=get_enum_type(["cluster", "namespace"]),
help="Specify the extension scope.",
)
c.argument(
"auto_upgrade_minor_version",
arg_group="Version",
options_list=["--auto-upgrade-minor-version", "--auto-upgrade"],
arg_type=get_three_state_flag(),
help="Automatically upgrade minor version of the extension instance.",
)
c.argument(
"version",
arg_group="Version",
help="Specify the version to install for the extension instance if"
" --auto-upgrade-minor-version is not enabled.",
)
c.argument(
"release_train",
arg_group="Version",
help="Specify the release train for the extension type.",
)
c.argument(
"configuration_settings",
arg_group="Configuration",
options_list=["--configuration-settings", "--config-settings", "--config"],
action=AddConfigurationSettings,
nargs="+",
help="Configuration Settings as key=value pair. Repeat parameter for each setting",
)
c.argument(
"configuration_protected_settings",
arg_group="Configuration",
options_list=[
"--configuration-protected-settings",
"--config-protected-settings",
"--config-protected",
],
action=AddConfigurationProtectedSettings,
nargs="+",
help="Configuration Protected Settings as key=value pair. Repeat parameter for each setting",
)
c.argument(
"configuration_settings_file",
arg_group="Configuration",
options_list=[
"--configuration-settings-file",
"--config-settings-file",
"--config-file",
],
help="JSON file path for configuration-settings",
)
c.argument(
"configuration_protected_settings_file",
arg_group="Configuration",
options_list=[
"--configuration-protected-settings-file",
"--config-protected-settings-file",
"--config-protected-file",
],
help="JSON file path for configuration-protected-settings",
)
c.argument(
"release_namespace",
help="Specify the namespace to install the extension release.",
)
c.argument(
"target_namespace",
help="Specify the target namespace to install to for the extension instance. This"
" parameter is required if extension scope is set to 'namespace'",
)

with self.argument_context(f"{consts.EXTENSION_NAME} update") as c:
c.argument('yes',
options_list=['--yes', '-y'],
help='Ignore confirmation prompts')
c.argument(
"yes", options_list=["--yes", "-y"], help="Ignore confirmation prompts"
)

with self.argument_context(f"{consts.EXTENSION_NAME} delete") as c:
c.argument('yes',
options_list=['--yes', '-y'],
help='Ignore confirmation prompts')
c.argument('force',
help='Specify whether to force delete the extension from the cluster.')
c.argument(
"yes", options_list=["--yes", "-y"], help="Ignore confirmation prompts"
)
c.argument(
"force",
help="Specify whether to force delete the extension from the cluster.",
)
9 changes: 6 additions & 3 deletions src/k8s-extension/azext_k8s_extension/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@
REGISTERED = "Registered"
DF_RM_HOSTNAME = "api-dogfood.resources.windows-int.net"

CONNECTED_CLUSTER_RP = "Microsoft.Kubernetes"
MANAGED_CLUSTER_RP = "Microsoft.ContainerService"
APPLIANCE_RP = "Microsoft.ResourceConnector"
CONNECTED_CLUSTER_RP = "microsoft.kubernetes"
MANAGED_CLUSTER_RP = "microsoft.containerservice"
APPLIANCE_RP = "microsoft.resourceconnector"
HYBRIDCONTAINERSERVICE_RP = "microsoft.hybridcontainerservice"

CONNECTED_CLUSTER_TYPE = "connectedclusters"
MANAGED_CLUSTER_TYPE = "managedclusters"
APPLIANCE_TYPE = "appliances"
PROVISIONED_CLUSTER_TYPE = "provisionedclusters"

CONNECTED_CLUSTER_API_VERSION = "2021-10-01"
MANAGED_CLUSTER_API_VERSION = "2021-10-01"
APPLIANCE_API_VERSION = "2021-10-31-preview"
HYBRIDCONTAINERSERVICE_API_VERSION = "2021-09-01-preview"
46 changes: 28 additions & 18 deletions src/k8s-extension/azext_k8s_extension/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,17 @@ def ExtensionFactory(extension_name):
return extension_map.get(extension_name, DefaultExtension)()


def show_k8s_extension(client, resource_group_name, cluster_name, name, cluster_type):
def show_k8s_extension(
client,
resource_group_name,
cluster_name,
name,
cluster_type,
cluster_resource_provider=None
):
"""Get an existing K8s Extension."""
# Determine ClusterRP
cluster_rp, _ = get_cluster_rp_api_version(cluster_type)
cluster_rp, _ = get_cluster_rp_api_version(cluster_rp=cluster_resource_provider, cluster_type=cluster_type)

try:
extension = client.get(
Expand Down Expand Up @@ -95,6 +102,7 @@ def create_k8s_extension(
name,
cluster_type,
extension_type,
cluster_resource_provider=None,
scope=None,
auto_upgrade_minor_version=None,
release_train=None,
Expand All @@ -110,7 +118,7 @@ def create_k8s_extension(
"""Create a new Extension Instance."""

extension_type_lower = extension_type.lower()
cluster_rp, _ = get_cluster_rp_api_version(cluster_type)
cluster_rp, _ = get_cluster_rp_api_version(cluster_rp=cluster_resource_provider, cluster_type=cluster_type)

# Configuration Settings & Configuration Protected Settings
if configuration_settings is not None and configuration_settings_file is not None:
Expand Down Expand Up @@ -166,6 +174,7 @@ def create_k8s_extension(
resource_group_name,
cluster_name,
name,
cluster_rp,
cluster_type,
extension_type_lower,
scope,
Expand All @@ -192,9 +201,10 @@ def create_k8s_extension(
# Create identity, if required
# We don't create the identity if we are in DF
if create_identity and not is_dogfood_cluster(cmd):
identity_object, location = __create_identity(
cmd, resource_group_name, cluster_name, cluster_type
)
identity_object, location = __create_identity(cmd=cmd, resource_group_name=resource_group_name,
cluster_name=cluster_name, cluster_type=cluster_type,
cluster_rp=cluster_rp
)
if identity_object is not None and location is not None:
extension_instance.identity, extension_instance.location = (
identity_object,
Expand All @@ -214,8 +224,8 @@ def create_k8s_extension(
)


def list_k8s_extension(client, resource_group_name, cluster_name, cluster_type):
cluster_rp, _ = get_cluster_rp_api_version(cluster_type)
def list_k8s_extension(client, resource_group_name, cluster_name, cluster_type, cluster_resource_provider=None):
cluster_rp, _ = get_cluster_rp_api_version(cluster_rp=cluster_resource_provider, cluster_type=cluster_type)
return client.list(resource_group_name, cluster_rp, cluster_type, cluster_name)


Expand All @@ -226,6 +236,7 @@ def update_k8s_extension(
cluster_name,
name,
cluster_type,
cluster_resource_provider=None,
auto_upgrade_minor_version=None,
release_train=None,
version=None,
Expand Down Expand Up @@ -253,22 +264,21 @@ def update_k8s_extension(
user_confirmation_factory(cmd, yes, msg)

# Determine ClusterRP
cluster_rp, _ = get_cluster_rp_api_version(cluster_type)
cluster_rp, _ = get_cluster_rp_api_version(cluster_rp=cluster_resource_provider, cluster_type=cluster_type)

# We need to determine the ExtensionType to call ExtensionFactory and create Extension class
extension = show_k8s_extension(
client, resource_group_name, cluster_name, name, cluster_type
client, resource_group_name, cluster_name, name, cluster_type, cluster_rp
)
extension_type_lower = extension.extension_type.lower()

config_settings = None
config_protected_settings = None
config_settings = {}
config_protected_settings = {}
# Get Configuration Settings from file
if configuration_settings_file is not None:
config_settings = read_config_settings_file(configuration_settings_file)

if configuration_settings is not None:
config_settings = {}
for dicts in configuration_settings:
for key, value in dicts.items():
config_settings[key] = value
Expand All @@ -280,7 +290,6 @@ def update_k8s_extension(
)

if configuration_protected_settings is not None:
config_protected_settings = {}
for dicts in configuration_protected_settings:
for key, value in dicts.items():
config_protected_settings[key] = value
Expand Down Expand Up @@ -320,13 +329,14 @@ def delete_k8s_extension(
cluster_name,
name,
cluster_type,
cluster_resource_provider=None,
no_wait=False,
yes=False,
force=False,
):
"""Delete an existing Kubernetes Extension."""
# Determine ClusterRP
cluster_rp, _ = get_cluster_rp_api_version(cluster_type)
cluster_rp, _ = get_cluster_rp_api_version(cluster_rp=cluster_resource_provider, cluster_type=cluster_type)
extension = None
try:
extension = client.get(
Expand All @@ -343,7 +353,7 @@ def delete_k8s_extension(

# If there is any custom delete logic, this will call the logic
extension_class.Delete(
cmd, client, resource_group_name, cluster_name, name, cluster_type, yes
cmd, client, resource_group_name, cluster_name, name, cluster_rp, cluster_type, yes
)

return sdk_no_wait(
Expand All @@ -358,7 +368,7 @@ def delete_k8s_extension(
)


def __create_identity(cmd, resource_group_name, cluster_name, cluster_type):
def __create_identity(cmd, resource_group_name, cluster_name, cluster_rp, cluster_type):
subscription_id = get_subscription_id(cmd.cli_ctx)
resources = cf_resources(cmd.cli_ctx, subscription_id)

Expand All @@ -369,7 +379,7 @@ def __create_identity(cmd, resource_group_name, cluster_name, cluster_type):
):
return None, None

cluster_rp, parent_api_version = get_cluster_rp_api_version(cluster_type)
cluster_rp, parent_api_version = get_cluster_rp_api_version(cluster_rp=cluster_rp, cluster_type=cluster_type)

cluster_resource_id = (
"/subscriptions/{0}/resourceGroups/{1}/providers/{2}/{3}/{4}".format(
Expand Down
Loading