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

Custom User Confirmation for Partners #70

Merged
merged 6 commits into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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
40 changes: 31 additions & 9 deletions src/k8s-extension/azext_k8s_extension/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,47 @@

helps[f'{consts.EXTENSION_NAME}'] = """
type: group
short-summary: Commands to manage K8s-extensions.
short-summary: Commands to manage Kubernetes Extensions.
"""

helps[f'{consts.EXTENSION_NAME} create'] = """
helps[f'{consts.EXTENSION_NAME} create'] = f"""
type: command
short-summary: Create a K8s-extension.
short-summary: Create a Kubernetes Extension.
examples:
- name: Create a Kubernetes Extension
text: |-
az {consts.EXTENSION_NAME} create --resource-group my-resource-group \\
--cluster-name mycluster --cluster-type connectedClusters \\
--name myextension --extension-type microsoft.openservicemesh \\
--scope cluster --release-train stable
"""

helps[f'{consts.EXTENSION_NAME} list'] = """
helps[f'{consts.EXTENSION_NAME} list'] = f"""
type: command
short-summary: List K8s-extensions.
short-summary: List Kubernetes Extensions.
examples:
- name: List all Kubernetes Extensions on a cluster
text: |-
az {consts.EXTENSION_NAME} list --resource-group my-resource-group \\
--cluster-name mycluster --cluster-type connectedClusters
"""

helps[f'{consts.EXTENSION_NAME} delete'] = """
helps[f'{consts.EXTENSION_NAME} delete'] = f"""
type: command
short-summary: Delete a K8s-extension.
short-summary: Delete a Kubernetes Extension.
examples:
- name: Delete an existing Kubernetes Extension
text: |-
az {consts.EXTENSION_NAME} delete --resource-group my-resource-group \\
--cluster-name mycluster --cluster-type connectedClusters --name myextension
"""

helps[f'{consts.EXTENSION_NAME} show'] = """
helps[f'{consts.EXTENSION_NAME} show'] = f"""
type: command
short-summary: Show details of a K8s-extension.
short-summary: Show a Kubernetes Extension.
examples:
- name: Show details of a Kubernetes Extension
text: |-
az {consts.EXTENSION_NAME} show --resource-group my-resource-group \\
--cluster-name mycluster --cluster-type connectedClusters --name myextension
"""
5 changes: 5 additions & 0 deletions src/k8s-extension/azext_k8s_extension/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,8 @@ def load_arguments(self, _):
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} delete") as c:
c.argument('yes',
options_list=['--yes', '-y'],
help='Ignore confirmation prompts')
2 changes: 1 addition & 1 deletion src/k8s-extension/azext_k8s_extension/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ def load_command_table(self, _):
is_preview=True) \
as g:
g.custom_command('create', 'create_k8s_extension')
g.custom_command('delete', 'delete_k8s_extension', confirmation=True)
g.custom_command('delete', 'delete_k8s_extension')
jonathan-innis marked this conversation as resolved.
Show resolved Hide resolved
g.custom_command('list', 'list_k8s_extension', table_transformer=k8s_extension_list_table_format)
g.custom_show_command('show', 'show_k8s_extension', table_transformer=k8s_extension_show_table_format)
6 changes: 3 additions & 3 deletions src/k8s-extension/azext_k8s_extension/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def update_k8s_extension(client, resource_group_name, cluster_type, cluster_name
# return client.update(resource_group_name, cluster_rp, cluster_type, cluster_name, name, upd_extension)


def delete_k8s_extension(client, resource_group_name, cluster_name, name, cluster_type):
def delete_k8s_extension(cmd, client, resource_group_name, cluster_name, name, cluster_type, yes=False):
"""Delete an existing Kubernetes Extension.

"""
Expand All @@ -201,12 +201,12 @@ def delete_k8s_extension(client, resource_group_name, cluster_name, name, cluste
try:
extension = client.get(resource_group_name, cluster_rp, cluster_type, cluster_name, name)
except HttpResponseError:
logger.warning("No extension with name '%s' found on cluster '%s', so nothing to delete", cluster_name, name)
logger.warning("No extension with name '%s' found on cluster '%s', so nothing to delete", name, cluster_name)
jonathan-innis marked this conversation as resolved.
Show resolved Hide resolved
return None
extension_class = ExtensionFactory(extension.extension_type.lower())

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

return client.delete(resource_group_name, cluster_rp, cluster_type, cluster_name, name)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@
from knack.log import get_logger

from ..vendored_sdks.models import ExtensionInstance
from ..vendored_sdks.models import ExtensionInstanceUpdate
from ..vendored_sdks.models import ScopeCluster
from ..vendored_sdks.models import Scope

from .PartnerExtensionModel import PartnerExtensionModel
from .DefaultExtension import DefaultExtension
from .ContainerInsights import _get_container_insights_settings

logger = get_logger(__name__)


class AzureDefender(PartnerExtensionModel):
class AzureDefender(DefaultExtension):
def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_type, extension_type,
scope, auto_upgrade_minor_version, release_train, version, target_namespace,
release_namespace, configuration_settings, configuration_protected_settings,
Expand Down Expand Up @@ -59,17 +58,3 @@ def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_t
configuration_protected_settings=configuration_protected_settings
)
return extension_instance, name, create_identity

def Update(self, extension, auto_upgrade_minor_version, release_train, version):
"""ExtensionType 'microsoft.azuredefender.kubernetes' specific validations & defaults for Update
Must create and return a valid 'ExtensionInstanceUpdate' object.

"""
return ExtensionInstanceUpdate(
auto_upgrade_minor_version=auto_upgrade_minor_version,
release_train=release_train,
version=version
)

def Delete(self, client, resource_group_name, cluster_name, name, cluster_type):
pass
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import copy
from hashlib import md5
from typing import Any, Dict, List, Tuple
from azext_k8s_extension.partner_extensions.DefaultExtension import DefaultExtension

import azure.mgmt.relay
import azure.mgmt.relay.models
Expand All @@ -27,10 +28,9 @@
from msrestazure.azure_exceptions import CloudError

from .._client_factory import cf_resources
from .PartnerExtensionModel import PartnerExtensionModel
from .DefaultExtension import DefaultExtension, user_confirmation_factory
from ..vendored_sdks.models import (
ExtensionInstance,
ExtensionInstanceUpdate,
Scope,
ScopeCluster
)
Expand All @@ -41,7 +41,7 @@


# pylint: disable=too-many-instance-attributes
class AzureMLKubernetes(PartnerExtensionModel):
class AzureMLKubernetes(DefaultExtension):
def __init__(self):
# constants for configuration settings.
self.DEFAULT_RELEASE_NAMESPACE = 'azureml'
Expand Down Expand Up @@ -158,18 +158,12 @@ def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_t
)
return extension_instance, name, create_identity

def Update(self, extension, auto_upgrade_minor_version, release_train, version):
return ExtensionInstanceUpdate(
auto_upgrade_minor_version=auto_upgrade_minor_version,
release_train=release_train,
version=version
)

def Delete(self, client, resource_group_name, cluster_name, name, cluster_type):
def Delete(self, cmd, client, resource_group_name, cluster_name, name, cluster_type, yes):
# Give a warning message
logger.warning("If nvidia.com/gpu or fuse resource is not recognized by kubernetes after this deletion, "
"you probably have installed nvidia-device-plugin or fuse-device-plugin before installing AMLArc extension. "
"Please try to reinstall device plugins to fix this issue.")
user_confirmation_factory(cmd, yes)

def __validate_config(self, configuration_settings, configuration_protected_settings):
# perform basic validation of the input config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,18 @@
from msrestazure.tools import parse_resource_id, is_valid_resource_id

from ..vendored_sdks.models import ExtensionInstance
from ..vendored_sdks.models import ExtensionInstanceUpdate
from ..vendored_sdks.models import ScopeCluster
from ..vendored_sdks.models import Scope

from .PartnerExtensionModel import PartnerExtensionModel
from .DefaultExtension import DefaultExtension

from .._client_factory import (
cf_resources, cf_resource_groups, cf_log_analytics)

logger = get_logger(__name__)


class ContainerInsights(PartnerExtensionModel):
class ContainerInsights(DefaultExtension):
def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_type, extension_type,
scope, auto_upgrade_minor_version, release_train, version, target_namespace,
release_namespace, configuration_settings, configuration_protected_settings,
Expand Down Expand Up @@ -71,20 +70,6 @@ def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_t
)
return extension_instance, name, create_identity

def Update(self, extension, auto_upgrade_minor_version, release_train, version):
"""ExtensionType 'microsoft.azuremonitor.containers' specific validations & defaults for Update
Must create and return a valid 'ExtensionInstanceUpdate' object.

"""
return ExtensionInstanceUpdate(
auto_upgrade_minor_version=auto_upgrade_minor_version,
release_train=release_train,
version=version
)

def Delete(self, client, resource_group_name, cluster_name, name, cluster_type):
pass


# Custom Validation Logic for Container Insights

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

# pylint: disable=unused-argument

from azure.cli.core.util import user_confirmation

from ..vendored_sdks.models import ExtensionInstance
from ..vendored_sdks.models import ExtensionInstanceUpdate
from ..vendored_sdks.models import ScopeCluster
Expand Down Expand Up @@ -56,5 +58,11 @@ def Update(self, extension, auto_upgrade_minor_version, release_train, version):
version=version
)

def Delete(self, client, resource_group_name, cluster_name, name, cluster_type):
pass
def Delete(self, cmd, client, resource_group_name, cluster_name, name, cluster_type, yes):
user_confirmation_factory(cmd, yes)


def user_confirmation_factory(cmd, yes, message="Are you sure you want to perform this operation?"):
if cmd.cli_ctx.config.getboolean('core', 'disable_confirm_prompt', fallback=False):
return
user_confirmation(message, yes=yes)
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
from ..vendored_sdks.models import ScopeNamespace
from ..vendored_sdks.models import Scope

from .PartnerExtensionModel import PartnerExtensionModel
from .DefaultExtension import DefaultExtension


class DefaultExtensionWithIdentity(PartnerExtensionModel):
class DefaultExtensionWithIdentity(DefaultExtension):
def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_type, extension_type,
scope, auto_upgrade_minor_version, release_train, version, target_namespace,
release_namespace, configuration_settings, configuration_protected_settings,
Expand Down Expand Up @@ -55,6 +55,3 @@ def Update(self, extension, auto_upgrade_minor_version, release_train, version):
release_train=release_train,
version=version
)

def Delete(self, client, resource_group_name, cluster_name, name, cluster_type):
pass
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# pylint: disable=redefined-outer-name
# pylint: disable=no-member

from azext_k8s_extension.partner_extensions.DefaultExtension import DefaultExtension
from knack.log import get_logger

from azure.cli.core.azclierror import InvalidArgumentValueError, RequiredArgumentMissingError
Expand All @@ -16,9 +17,7 @@
import yaml
import requests

from ..partner_extensions import PartnerExtensionModel

from .PartnerExtensionModel import PartnerExtensionModel
from .DefaultExtension import DefaultExtension

from ..vendored_sdks.models import (
ExtensionInstance,
Expand All @@ -32,7 +31,7 @@
logger = get_logger(__name__)


class OpenServiceMesh(PartnerExtensionModel):
class OpenServiceMesh(DefaultExtension):

def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_type, extension_type,
scope, auto_upgrade_minor_version, release_train, version, target_namespace,
Expand Down Expand Up @@ -100,9 +99,6 @@ def Update(self, extension, auto_upgrade_minor_version, release_train, version):
version=version
)

def Delete(self, client, resource_group_name, cluster_name, name, cluster_type):
pass


def _validate_tested_distro(cmd, cluster_resource_group_name, cluster_name, extension_version):

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ def Update(self, extension: ExtensionInstance, auto_upgrade_minor_version: bool,
pass

@abstractmethod
def Delete(self, client, resource_group_name: str, cluster_name: str, name: str, cluster_type: str):
def Delete(self, cmd, client, resource_group_name: str, cluster_name: str, name: str, cluster_type: str, yes: bool):
pass