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

cleanup runcommand cli #3748

Merged
merged 2 commits into from
Aug 5, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
15 changes: 0 additions & 15 deletions src/aks-preview/azext_aks_preview/_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,6 @@
from jmespath import functions


def aks_run_command_result_format(cmdResult):
result = OrderedDict()
if cmdResult['provisioningState'] == "Succeeded":
result['exit code'] = cmdResult['exitCode']
result['logs'] = cmdResult['logs']
return result
if cmdResult['provisioningState'] == "Failed":
result['provisioning state'] = cmdResult['provisioningState']
result['reason'] = cmdResult['reason']
return result
result['provisioning state'] = cmdResult['provisioningState']
result['started At'] = cmdResult['startedAt']
return result


def aks_agentpool_show_table_format(result):
"""Format an agent pool as summary results for display with "-o table"."""
return [_aks_agentpool_table_format(result)]
Expand Down
26 changes: 0 additions & 26 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,32 +667,6 @@
short-summary: Display diagnostic results for the Kubernetes cluster after kollect is done.
"""

helps['aks command'] = """
type: group
short-summary: see detail usage in 'az aks command invoke', 'az aks command result'.
"""

helps['aks command invoke'] = """
type: command
short-summary: run a shell command (with kubectl, helm) on your aks cluster, support attaching files as well.
parameters:
- name: --command -c
type: string
short-summary: command or shell script you want run.
- name: --file -f
type: string
short-summary: files will be used by the command, use '.' to attach the current folder.
"""

helps['aks command result'] = """
type: command
short-summary: fetch result from previously triggered 'aks command invoke'.
parameters:
- name: --command-id -i
type: string
short-summary: commandId returned from 'aks command invoke'.
"""

helps['aks maintenanceconfiguration'] = """
type: group
short-summary: Commands to manage maintenance configurations in managed Kubernetes cluster.
Expand Down
7 changes: 0 additions & 7 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,6 @@ def load_arguments(self, _):
with self.argument_context('aks nodepool') as c:
c.argument('cluster_name', type=str, help='The cluster name.')

with self.argument_context('aks command invoke') as c:
c.argument('command_string', type=str, options_list=["--command", "-c"], help='the command to run')
c.argument('command_files', options_list=["--file", "-f"], required=False, action="append", help='attach any files the command may use, or use \'.\' to upload the current folder.')

with self.argument_context('aks command result') as c:
c.argument('command_id', type=str, options_list=["--command-id", "-i"], help='the command ID from "aks command invoke"')

for scope in ['aks nodepool add']:
with self.argument_context(scope) as c:
c.argument('nodepool_name', type=str, options_list=['--name', '-n'], validator=validate_nodepool_name, help='The node pool name.')
Expand Down
6 changes: 0 additions & 6 deletions src/aks-preview/azext_aks_preview/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,6 @@ def load_command_table(self, _):
g.custom_command('get-versions', 'aks_get_versions',
table_transformer=aks_versions_table_format)

with self.command_group('aks command', managed_clusters_sdk, client_factory=cf_managed_clusters) as g:
g.custom_command('invoke', 'aks_runcommand', supports_no_wait=True,
table_transformer=aks_run_command_result_format)
g.custom_command('result', 'aks_command_result',
supports_no_wait=False, table_transformer=aks_run_command_result_format)

# AKS maintenance configuration commands
with self.command_group('aks maintenanceconfiguration', maintenance_configuration_sdk, client_factory=cf_maintenance_configurations) as g:
g.custom_command('list', 'aks_maintenanceconfiguration_list')
Expand Down
110 changes: 0 additions & 110 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@
ManagedClusterPodIdentity,
ManagedClusterPodIdentityException,
UserAssignedIdentity,
RunCommandRequest,
ComponentsQit0EtSchemasManagedclusterpropertiesPropertiesIdentityprofileAdditionalproperties)
from ._client_factory import cf_resource_groups
from ._client_factory import get_auth_management_client
Expand Down Expand Up @@ -2294,115 +2293,6 @@ def aks_upgrade(cmd, # pylint: disable=unused-argument, too-many-return-state
return sdk_no_wait(no_wait, client.begin_create_or_update, resource_group_name, name, instance, headers=headers)


def aks_runcommand(cmd, client, resource_group_name, name, command_string="", command_files=None):
colorama.init()

mc = client.get(resource_group_name, name)

if not command_string:
raise CLIError('Command cannot be empty.')

request_payload = RunCommandRequest(command=command_string)
request_payload.context = _get_command_context(command_files)
if mc.aad_profile is not None and mc.aad_profile.managed:
request_payload.cluster_token = _get_dataplane_aad_token(
cmd.cli_ctx, "6dae42f8-4368-4678-94ff-3960e28e3630")

commandResultFuture = client.begin_run_command(
resource_group_name, name, request_payload, polling_interval=5, retry_total=0)

return _print_command_result(cmd.cli_ctx, commandResultFuture.result(300))


def aks_command_result(cmd, client, resource_group_name, name, command_id=""):
if not command_id:
raise CLIError('CommandID cannot be empty.')

commandResult = client.get_command_result(
resource_group_name, name, command_id)
return _print_command_result(cmd.cli_ctx, commandResult)


def _print_command_result(cli_ctx, commandResult):
# cli_ctx.data['safe_params'] contains list of parameter name user typed in, without value.
# cli core also use this calculate ParameterSetName header for all http request from cli.
if cli_ctx.data['safe_params'] is None or "-o" in cli_ctx.data['safe_params'] or "--output" in cli_ctx.data['safe_params']:
# user specified output format, honor their choice, return object to render pipeline
return commandResult
else:
# user didn't specified any format, we can customize the print for best experience
if commandResult.provisioning_state == "Succeeded":
# succeed, print exitcode, and logs
print(f"{colorama.Fore.GREEN}command started at {commandResult.started_at}, finished at {commandResult.finished_at}, with exitcode={commandResult.exit_code}{colorama.Style.RESET_ALL}")
print(commandResult.logs)
return

if commandResult.provisioning_state == "Failed":
# failed, print reason in error
print(
f"{colorama.Fore.RED}command failed with reason: {commandResult.reason}{colorama.Style.RESET_ALL}")
return

# *-ing state
print(f"{colorama.Fore.BLUE}command is in : {commandResult.provisioning_state} state{colorama.Style.RESET_ALL}")
return None


def _get_command_context(command_files):
if not command_files:
return ""

filesToAttach = {}
# . means to attach current folder, cannot combine more files. (at least for now)
if len(command_files) == 1 and command_files[0] == ".":
# current folder
cwd = os.getcwd()
for filefolder, _, files in os.walk(cwd):
for file in files:
# retain folder structure
rel = os.path.relpath(filefolder, cwd)
filesToAttach[os.path.join(
filefolder, file)] = os.path.join(rel, file)
else:
for file in command_files:
if file == ".":
raise CLIError(
". is used to attach current folder, not expecting other attachements.")
if os.path.isfile(file):
# for individual attached file, flatten them to same folder
filesToAttach[file] = os.path.basename(file)
else:
raise CLIError(f"{file} is not valid file, or not accessable.")

if len(filesToAttach) < 1:
logger.debug("no files to attach!")
return ""

zipStream = io.BytesIO()
zipFile = zipfile.ZipFile(zipStream, "w")
for _, (osfile, zipEntry) in enumerate(filesToAttach.items()):
zipFile.write(osfile, zipEntry)
# zipFile.printdir() // use this to debug
zipFile.close()

return str(base64.encodebytes(zipStream.getbuffer()), "utf-8")


def _get_dataplane_aad_token(cli_ctx, serverAppId):
# this function is mostly copied from keyvault cli
import adal
try:
return Profile(cli_ctx=cli_ctx).get_raw_token(resource=serverAppId)[0][2].get('accessToken')
except adal.AdalError as err:
# pylint: disable=no-member
if (hasattr(err, 'error_response') and
('error_description' in err.error_response) and
('AADSTS70008:' in err.error_response['error_description'])):
raise CLIError(
"Credentials have expired due to inactivity. Please run 'az login'")
raise CLIError(err)


def _upgrade_single_nodepool_image_version(no_wait, client, resource_group_name, cluster_name, nodepool_name):
return sdk_no_wait(no_wait, client.begin_upgrade_node_image_version, resource_group_name, cluster_name, nodepool_name)

Expand Down
Loading