diff --git a/linter_exclusions.yml b/linter_exclusions.yml index 6054be4859..cc9aa0ce58 100644 --- a/linter_exclusions.yml +++ b/linter_exclusions.yml @@ -2287,6 +2287,11 @@ ssh vm: ssh_args: rule_exclusions: - no_positional_parameters +ssh arc: + parameters: + ssh_args: + rule_exclusions: + - no_positional_parameters storage account create: parameters: hierarchical_namespace: diff --git a/src/ssh/HISTORY.md b/src/ssh/HISTORY.md index 9065fdee50..1ae5296778 100644 --- a/src/ssh/HISTORY.md +++ b/src/ssh/HISTORY.md @@ -1,5 +1,15 @@ Release History =============== +1.1.0 +----- +* SSHArc Public Preview +* Add support for connecting to Arc Servers using AAD Certificates or Local User credentials. +* New command az ssh arc. +* New parameters: --resource-type and --ssh-proxy-folder. +* Validate that target machine exists before attempting to connect. +* Stop looking for OpenSSH client executables under C:\Windows\System32\OpenSSH on Windows. Path variable must be set properly for pre-installed OpenSSH. +* Append username to host name on config files when using local user credentials. + 1.0.1 ----- * Added --ssh-client-folder parameter. @@ -68,4 +78,4 @@ Release History 0.1.0 ----- -* Initial release. +* Initial release. \ No newline at end of file diff --git a/src/ssh/azext_ssh/_client_factory.py b/src/ssh/azext_ssh/_client_factory.py new file mode 100644 index 0000000000..e91e3a9b8b --- /dev/null +++ b/src/ssh/azext_ssh/_client_factory.py @@ -0,0 +1,31 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from azure.cli.core.commands.client_factory import get_mgmt_service_client + + +def cf_hybridconnectivity_cl(cli_ctx, *_): + from azext_ssh.vendored_sdks.hybridconnectivity import HybridConnectivityManagementAPI + return get_mgmt_service_client(cli_ctx, + HybridConnectivityManagementAPI) + + +def cf_endpoint(cli_ctx, *_): + return cf_hybridconnectivity_cl(cli_ctx).endpoints + + +def cf_connectedmachine_cl(cli_ctx, *_): + from azext_ssh.vendored_sdks.connectedmachine import ConnectedMachine + return get_mgmt_service_client(cli_ctx, + ConnectedMachine) + + +def cf_machine(cli_ctx, *_): + return cf_connectedmachine_cl(cli_ctx).machines diff --git a/src/ssh/azext_ssh/_help.py b/src/ssh/azext_ssh/_help.py index 7eb37c94e8..7850f465b5 100644 --- a/src/ssh/azext_ssh/_help.py +++ b/src/ssh/azext_ssh/_help.py @@ -7,19 +7,19 @@ from knack.help_files import helps helps['ssh'] = """ type: group - short-summary: SSH into resources (Azure VMs, etc) using AAD issued openssh certificates + short-summary: SSH into resources (Azure VMs, Arc servers, etc) using AAD issued openssh certificates. """ helps['ssh vm'] = """ type: command - short-summary: SSH into Azure VMs using an ssh certificate - long-summary: Users can login using AAD issued certificates or using local user credentials. We recommend login using AAD issued certificates. To SSH as a local user in the target machine, you must provide the local user name using the --local-user argument. + short-summary: SSH into Azure VMs or Arc Servers. + long-summary: Users can login using AAD issued certificates or using local user credentials. We recommend login using AAD issued certificates. To SSH using local user credentials, you must provide the local user name using the --local-user parameter. examples: - - name: Give a resource group and VM to SSH to + - name: Give a resource group name and machine name to SSH using AAD issued certificates text: | - az ssh vm --resource-group myResourceGroup --vm-name myVm + az ssh vm --resource-group myResourceGroup --name myVM - - name: Give the public IP (or hostname) of a VM to SSH to + - name: Give the public IP (or hostname) of a VM to SSH using AAD issued certificates text: | az ssh vm --ip 1.2.3.4 az ssh vm --hostname example.com @@ -32,33 +32,51 @@ helps['ssh vm'] = """ text: | az ssh vm --ip 1.2.3.4 -- -A -o ForwardX11=yes - - name: Give a local user name to SSH using local user credentials on the target machine using certificate based authentication. + - name: Give the Resource Type of the target. Useful when there is an Azure VM and an Arc Server with the same name in the same resource group. Resource type can be either "Microsoft.HybridCompute" for Arc Servers or "Microsoft.Compute" for Azure Virtual Machines. text: | - az ssh vm --local-user username --ip 1.2.3.4 --certificate-file cert.pub --private-key key + az ssh vm --resource-type [Microsoft.Compute|Microsoft.HybridCompute] --resource-group myResourceGroup --name myVM - - name: Give a local user name to SSH using local user credentials on the target machine using key based authentication. + - name: Give a local user name to SSH with local user credentials using certificate based authentication. text: | - az ssh vm --local-user username --resource-group myResourceGroup --vm-name myVM --private-key-file key + az ssh vm --local-user username --ip 1.2.3.4 --certificate-file cert.pub --private-key-file key - - name: Give a local user name to SSH using local user credentials on the target machine using password based authentication. + - name: Give a local user name to SSH with local user credentials using key based authentication. text: | - az ssh vm --local-user username --ip 1.2.3.4 + az ssh vm --local-user username --resource-group myResourceGroup --name myVM --private-key-file key + + - name: Give a local user name to SSH with local user credentials using password based authentication. + text: | + az ssh vm --local-user username --resource-group myResourceGroup --name myArcServer + + - name: Give a SSH Client Folder to use the ssh executables in that folder, like ssh-keygen.exe and ssh.exe. If not provided, the extension attempt to use pre-installed OpenSSH client (in that case, ensure OpenSSH client is installed and the Path environment variable is set correctly). + text: | + az ssh vm --resource-group myResourceGroup --name myVM --ssh-client-folder "C:\\Program Files\\OpenSSH" """ helps['ssh config'] = """ type: command - short-summary: Create an SSH config for resources (Azure VMs, etc) which can then be used by clients that support OpenSSH configs and certificates - long-summary: Other software (git/rsync/etc) that support setting an SSH command can be set to use the config file by setting the command to 'ssh -F /path/to/config' e.g. rsync -e 'ssh -F /path/to/config' + short-summary: Create an SSH config for resources (Azure VMs, Arc Servers, etc) which can then be used by clients that support OpenSSH configs and certificates + long-summary: Other software (git/rsync/etc) that support setting an SSH command can be set to use the config file by setting the command to 'ssh -F /path/to/config' e.g. rsync -e 'ssh -F /path/to/config'. Users can create ssh config files that use AAD issued certificates or local user credentials. examples: - - name: Give a resource group and VM for which to create a config, and save in a local file + - name: Give the resource group and machine name for which to create a config using AAD issued certificates, save in a local file, and then ssh into that resource text: | - az ssh config --resource-group myResourceGroup --vm-name myVm --file ./sshconfig + az ssh config --resource-group myResourceGroup --name myVm --file ./sshconfig + ssh -F ./sshconfig myResourceGroup-myVM - - name: Give the public IP (or hostname) of a VM for which to create a config and then ssh + - name: Give the public IP (or hostname) of an Azure VM for which to create a config and then ssh into that VM text: | az ssh config --ip 1.2.3.4 --file ./sshconfig ssh -F ./sshconfig 1.2.3.4 + - name: Give a local user to create a config using local user credentials, save in local file, and then ssh into that resource + text: | + az ssh config --resource-group myResourceGroup --name myMachine --local-user username --certificate-file cert --private-key-file key --file ./sshconfig + ssh -F ./sshconfig MyResourceGroup-myMachine-username + + - name: Give Keys Destination Folder to store the generated keys and certificates. If not provided, SSH keys are stored in new folder "az_ssh_config" next to the config file. + text: | + az ssh config --ip 1.2.3.4 --file ./sshconfig --keys-destination-folder /home/user/mykeys + - name: Create a generic config for use with any host text: | #Bash @@ -72,6 +90,14 @@ helps['ssh config'] = """ az ssh config --ip \\* --file ./sshconfig rsync -e 'ssh -F ./sshconfig' -avP directory/ myvm:~/directory GIT_SSH_COMMAND="ssh -F ./sshconfig" git clone myvm:~/gitrepo + + - name: Give SSH Client Folder to use the ssh executables in that folder. If not provided, the extension attempt to use pre-installed OpenSSH client (in that case, ensure OpenSSH client is installed and the Path environment variable is set correctly). + text: | + az ssh config --file ./sshconfig --resource-group myResourceGroup --name myMachine --ssh-client-folder "C:\\Program Files\\OpenSSH" + + - name: Give the Resource Type of the target. Useful when there is an Azure VM and an Arc Server with the same name in the same resource group. Resource type can be either "Microsoft.HybridCompute" for Arc Servers or "Microsoft.Compute" for Azure Virtual Machines. + text: | + az ssh config --resource-type [Microsoft.Compute|Microsoft.HybridCompute] --resource-group myResourceGroup --name myVM --file ./myconfig """ helps['ssh cert'] = """ @@ -82,3 +108,37 @@ helps['ssh cert'] = """ text: | az ssh cert --public-key-file ./id_rsa.pub --file ./id_rsa-aadcert.pub """ + +helps['ssh arc'] = """ + type: command + short-summary: SSH into Azure Arc Servers + long-summary: Users can login using AAD issued certificates or using local user credentials. We recommend login using AAD issued certificates as azure automatically rotate SSH CA keys. To SSH as a local user in the target machine, you must provide the local user name using the --local-user argument. + examples: + - name: Give a resource group name and machine name to SSH using AAD issued certificates + text: | + az ssh arc --resource-group myResourceGroup --name myMachine + + - name: Using a custom private key file + text: | + az ssh arc --resource-group myResourceGroup --name myMachine --private-key-file key --public-key-file key.pub + + - name: Using additional ssh arguments + text: | + az ssh arc --resource-group myResourceGroup --name myMachine -- -A -o ForwardX11=yes + + - name: Give a local user name to SSH with local user credentials using certificate based authentication. + text: | + az ssh arc --local-user username --resource-group myResourceGroup --name myMachine --certificate-file cert.pub --private-key-file key + + - name: Give a local user name to SSH with local user credentials using key based authentication. + text: | + az ssh arc --local-user username --resource-group myResourceGroup --name myMachine --private-key-file key + + - name: Give a local user name to SSH with local user credentials using password based authentication. + text: | + az ssh arc --local-user username --resource-group myResourceGroup --name myMachine + + - name: Give a SSH Client Folder to use the ssh executables in that folder, like ssh-keygen.exe and ssh.exe. If not provided, the extension attempt to use pre-installed OpenSSH client (ensure OpenSSH client is installed and the Path environment variable is set correctly). + text: | + az ssh arc --resource-group myResourceGroup --name myMachine --ssh-client-folder "C:\\Program Files\\OpenSSH" +""" diff --git a/src/ssh/azext_ssh/_params.py b/src/ssh/azext_ssh/_params.py index bd7b59f924..2a8e749422 100644 --- a/src/ssh/azext_ssh/_params.py +++ b/src/ssh/azext_ssh/_params.py @@ -19,9 +19,19 @@ def load_arguments(self, _): c.argument('cert_file', options_list=['--certificate-file', '-c'], help='Path to a certificate file used for authentication when using local user credentials.') c.argument('port', options_list=['--port'], help='SSH port') + c.argument('resource_type', options_list=['--resource-type'], + help='Resource type should be either Microsoft.Compute or Microsoft.HybridCompute', + completer=["Microsoft.HybridCompute", "Microsoft.Compute"]) c.argument('ssh_client_folder', options_list=['--ssh-client-folder'], help='Folder path that contains ssh executables (ssh.exe, ssh-keygen.exe, etc). ' 'Default to ssh pre-installed if not provided.') + c.argument('delete_credentials', options_list=['--force-delete-credentials', '--delete-private-key'], + help=('This is an internal argument. This argument is used by Azure Portal to provide a one click ' + 'SSH login experience in Cloud shell.'), + deprecate_info=c.deprecate(hide=True), action='store_true') + c.argument('ssh_proxy_folder', options_list=['--ssh-proxy-folder'], + help=('Path to the folder where the ssh proxy should be saved. ' + 'Default to .clientsshproxy folder in user\'s home directory if not provided.')) c.positional('ssh_args', nargs='*', help='Additional arguments passed to OpenSSH') with self.argument_context('ssh config') as c: @@ -38,8 +48,13 @@ def load_arguments(self, _): help='Overwrites the config file if this flag is set') c.argument('credentials_folder', options_list=['--keys-destination-folder', '--keys-dest-folder'], help='Folder where new generated keys will be stored.') + c.argument('port', options_list=['--port'], help='SSH Port') + c.argument('resource_type', options_list=['--resource-type'], + help='Resource type should be either Microsoft.Compute or Microsoft.HybridCompute') c.argument('cert_file', options_list=['--certificate-file', '-c'], help='Path to certificate file') - c.argument('port', options_list=['--port'], help='SSH port') + c.argument('ssh_proxy_folder', options_list=['--ssh-proxy-folder'], + help=('Path to the folder where the ssh proxy should be saved. ' + 'Default to .clientsshproxy folder in user\'s home directory if not provided.')) c.argument('ssh_client_folder', options_list=['--ssh-client-folder'], help='Folder path that contains ssh executables (ssh.exe, ssh-keygen.exe, etc). ' 'Default to ssh pre-installed if not provided.') @@ -53,3 +68,23 @@ def load_arguments(self, _): c.argument('ssh_client_folder', options_list=['--ssh-client-folder'], help='Folder path that contains ssh executables (ssh.exe, ssh-keygen.exe, etc). ' 'Default to ssh pre-installed if not provided.') + + with self.argument_context('ssh arc') as c: + c.argument('vm_name', options_list=['--vm-name', '--name', '-n'], help='The name of the Arc Server') + c.argument('public_key_file', options_list=['--public-key-file', '-p'], help='The RSA public key file path') + c.argument('private_key_file', options_list=['--private-key-file', '-i'], help='The RSA private key file path') + c.argument('local_user', options_list=['--local-user'], + help='The username for a local user') + c.argument('cert_file', options_list=['--certificate-file', '-c'], help='Path to certificate file') + c.argument('port', options_list=['--port'], help='Port to connect to on the remote host.') + c.argument('ssh_client_folder', options_list=['--ssh-client-folder'], + help='Folder path that contains ssh executables (ssh.exe, ssh-keygen.exe, etc). ' + 'Default to ssh pre-installed if not provided.') + c.argument('delete_credentials', options_list=['--force-delete-credentials', '--delete-private-key'], + help=('This is an internal argument. This argument is used by Azure Portal to provide a one click ' + 'SSH login experience in Cloud shell.'), + deprecate_info=c.deprecate(hide=True), action='store_true') + c.argument('ssh_proxy_folder', options_list=['--ssh-proxy-folder'], + help=('Path to the folder where the ssh proxy should be saved. ' + 'Default to .clientsshproxy folder in user\'s home directory if not provided.')) + c.positional('ssh_args', nargs='*', help='Additional arguments passed to OpenSSH') diff --git a/src/ssh/azext_ssh/commands.py b/src/ssh/azext_ssh/commands.py index 44fcd1e736..335ba21eca 100644 --- a/src/ssh/azext_ssh/commands.py +++ b/src/ssh/azext_ssh/commands.py @@ -10,3 +10,4 @@ def load_command_table(self, _): g.custom_command('vm', 'ssh_vm') g.custom_command('config', 'ssh_config') g.custom_command('cert', 'ssh_cert') + g.custom_command('arc', 'ssh_arc') diff --git a/src/ssh/azext_ssh/connectivity_utils.py b/src/ssh/azext_ssh/connectivity_utils.py new file mode 100644 index 0000000000..0a625f220e --- /dev/null +++ b/src/ssh/azext_ssh/connectivity_utils.py @@ -0,0 +1,173 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import time +import stat +import os +import urllib.request +import json +import base64 +from glob import glob + +import colorama +from colorama import Fore +from colorama import Style + +from azure.core.exceptions import ResourceNotFoundError +from azure.cli.core import telemetry +from azure.cli.core import azclierror +from azure.mgmt.core.tools import resource_id +from azure.cli.core.commands.client_factory import get_subscription_id +from knack import log + +from . import file_utils +from . import constants as consts + +logger = log.get_logger(__name__) + + +# Get the Access Details to connect to Arc Connectivity platform from the HybridConnectivity RP +def get_relay_information(cmd, resource_group, vm_name, certificate_validity_in_seconds): + from azext_ssh._client_factory import cf_endpoint + client = cf_endpoint(cmd.cli_ctx) + + if not certificate_validity_in_seconds or \ + certificate_validity_in_seconds > consts.RELAY_INFO_MAXIMUM_DURATION_IN_SECONDS: + certificate_validity_in_seconds = consts.RELAY_INFO_MAXIMUM_DURATION_IN_SECONDS + + try: + t0 = time.time() + result = client.list_credentials(resource_group_name=resource_group, machine_name=vm_name, + endpoint_name="default", expiresin=certificate_validity_in_seconds) + time_elapsed = time.time() - t0 + telemetry.add_extension_event('ssh', {'Context.Default.AzureCLI.SSHListCredentialsTime': time_elapsed}) + except ResourceNotFoundError: + logger.debug("Default Endpoint couldn't be found. Trying to create Default Endpoint.") + _create_default_endpoint(cmd, resource_group, vm_name, client) + try: + t0 = time.time() + result = client.list_credentials(resource_group_name=resource_group, machine_name=vm_name, + endpoint_name="default", expiresin=certificate_validity_in_seconds) + time_elapsed = time.time() - t0 + telemetry.add_extension_event('ssh', {'Context.Default.AzureCLI.SSHListCredentialsTime': time_elapsed}) + except Exception as e: + raise azclierror.ClientRequestError(f"Request for Azure Relay Information Failed:\n{str(e)}") + except Exception as e: + raise azclierror.ClientRequestError(f"Request for Azure Relay Information Failed:\n{str(e)}") + return result + + +def _create_default_endpoint(cmd, resource_group, vm_name, client): + az_resource_id = resource_id(subscription=get_subscription_id(cmd.cli_ctx), resource_group=resource_group, + namespace="Microsoft.HybridCompute", type="machines", name=vm_name) + endpoint_resource = {"id": az_resource_id, "type_properties_type": "default"} + try: + client.create_or_update(resource_group, vm_name, "default", endpoint_resource) + except Exception as e: + colorama.init() + raise azclierror.UnauthorizedError(f"Unable to create Default Endpoint for {vm_name} in {resource_group}." + f"\nError: {str(e)}", + Fore.YELLOW + "Contact Owner/Contributor of the resource." + Style.RESET_ALL) + + +# Downloads client side proxy to connect to Arc Connectivity Platform +def get_client_side_proxy(arc_proxy_folder): + + request_uri, install_location, older_version_location = _get_proxy_filename_and_url(arc_proxy_folder) + install_dir = os.path.dirname(install_location) + + # Only download new proxy if it doesn't exist already + if not os.path.isfile(install_location): + t0 = time.time() + # download the executable + try: + with urllib.request.urlopen(request_uri) as response: + response_content = response.read() + response.close() + except Exception as e: + raise azclierror.ClientRequestError(f"Failed to download client proxy executable from {request_uri}. " + "Error: " + str(e)) from e + time_elapsed = time.time() - t0 + + proxy_data = { + 'Context.Default.AzureCLI.SSHProxyDownloadTime': time_elapsed, + 'Context.Default.AzureCLI.SSHProxyVersion': consts.CLIENT_PROXY_VERSION + } + telemetry.add_extension_event('ssh', proxy_data) + + # if directory doesn't exist, create it + if not os.path.isdir(install_dir): + file_utils.create_directory(install_dir, f"Failed to create client proxy directory '{install_dir}'. ") + # if directory exists, delete any older versions of the proxy + else: + older_version_files = glob(older_version_location) + for f in older_version_files: + file_utils.delete_file(f, f"failed to delete older version file {f}", warning=True) + + # write executable in the install location + file_utils.write_to_file(install_location, 'wb', response_content, "Failed to create client proxy file. ") + os.chmod(install_location, os.stat(install_location).st_mode | stat.S_IXUSR) + colorama.init() + print(Fore.GREEN + f"SSH Client Proxy saved to {install_location}" + Style.RESET_ALL) + + return install_location + + +def _get_proxy_filename_and_url(arc_proxy_folder): + import platform + operating_system = platform.system() + machine = platform.machine() + + logger.debug("Platform OS: %s", operating_system) + logger.debug("Platform architecture: %s", machine) + + if machine.endswith('64'): + architecture = 'amd64' + elif machine.endswith('86'): + architecture = '386' + elif machine == '': + raise azclierror.BadRequestError("Couldn't identify the platform architecture.") + else: + raise azclierror.BadRequestError(f"Unsuported architecture: {machine} is not currently supported") + + # define the request url and install location based on the os and architecture + proxy_name = f"sshProxy_{operating_system.lower()}_{architecture}" + request_uri = (f"{consts.CLIENT_PROXY_STORAGE_URL}/{consts.CLIENT_PROXY_RELEASE}" + f"/{proxy_name}_{consts.CLIENT_PROXY_VERSION}") + install_location = proxy_name + "_" + consts.CLIENT_PROXY_VERSION.replace('.', '_') + older_location = proxy_name + "*" + + if operating_system == 'Windows': + request_uri = request_uri + ".exe" + install_location = install_location + ".exe" + older_location = older_location + ".exe" + elif operating_system not in ('Linux', 'Darwin'): + raise azclierror.BadRequestError(f"Unsuported OS: {operating_system} platform is not currently supported") + + if not arc_proxy_folder: + install_location = os.path.expanduser(os.path.join('~', os.path.join(".clientsshproxy", install_location))) + older_location = os.path.expanduser(os.path.join('~', os.path.join(".clientsshproxy", older_location))) + else: + install_location = os.path.join(arc_proxy_folder, install_location) + older_location = os.path.join(arc_proxy_folder, older_location) + + return request_uri, install_location, older_location + + +def format_relay_info_string(relay_info): + relay_info_string = json.dumps( + { + "relay": { + "namespaceName": relay_info.namespace_name, + "namespaceNameSuffix": relay_info.namespace_name_suffix, + "hybridConnectionName": relay_info.hybrid_connection_name, + "accessKey": relay_info.access_key, + "expiresOn": relay_info.expires_on + } + }) + result_bytes = relay_info_string.encode("ascii") + enc = base64.b64encode(result_bytes) + base64_result_string = enc.decode("ascii") + return base64_result_string diff --git a/src/ssh/azext_ssh/constants.py b/src/ssh/azext_ssh/constants.py new file mode 100644 index 0000000000..ea044a918d --- /dev/null +++ b/src/ssh/azext_ssh/constants.py @@ -0,0 +1,20 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +from colorama import Fore +from colorama import Style + +CLIENT_PROXY_VERSION = "1.3.017634" +CLIENT_PROXY_RELEASE = "release01-11-21" +CLIENT_PROXY_STORAGE_URL = "https://sshproxysa.blob.core.windows.net" +CLEANUP_TOTAL_TIME_LIMIT_IN_SECONDS = 120 +CLEANUP_TIME_INTERVAL_IN_SECONDS = 10 +CLEANUP_AWAIT_TERMINATION_IN_SECONDS = 30 +RELAY_INFO_MAXIMUM_DURATION_IN_SECONDS = 3600 +WINDOWS_INVALID_FOLDERNAME_CHARS = "\\/*:<>?\"|" +RECOMMENDATION_SSH_CLIENT_NOT_FOUND = (Fore.YELLOW + "Ensure OpenSSH is installed and the PATH Environment " + "Variable is set correctly.\nAlternatively, use " + "--ssh-client-folder to provide OpenSSH folder path." + Style.RESET_ALL) +RECOMMENDATION_RESOURCE_NOT_FOUND = (Fore.YELLOW + "Please ensure the active subscription is set properly " + "and resource exists." + Style.RESET_ALL) diff --git a/src/ssh/azext_ssh/custom.py b/src/ssh/azext_ssh/custom.py index 78100f6aaa..dfe7ef5909 100644 --- a/src/ssh/azext_ssh/custom.py +++ b/src/ssh/azext_ssh/custom.py @@ -7,6 +7,9 @@ import os import hashlib import json import tempfile +import time +import platform +import oschmod import colorama from colorama import Fore @@ -14,65 +17,83 @@ from colorama import Style from knack import log from azure.cli.core import azclierror +from azure.cli.core import telemetry +from azure.core.exceptions import ResourceNotFoundError, HttpResponseError from . import ip_utils from . import rsa_parser from . import ssh_utils +from . import connectivity_utils from . import ssh_info +from . import file_utils +from . import constants as const logger = log.get_logger(__name__) def ssh_vm(cmd, resource_group_name=None, vm_name=None, ssh_ip=None, public_key_file=None, private_key_file=None, use_private_ip=False, local_user=None, cert_file=None, port=None, - ssh_client_folder=None, ssh_args=None): + ssh_client_folder=None, delete_credentials=False, resource_type=None, ssh_proxy_folder=None, ssh_args=None): + # delete_credentials can only be used by Azure Portal to provide one-click experience on CloudShell. + if delete_credentials and os.environ.get("AZUREPS_HOST_ENVIRONMENT") != "cloud-shell/1.0": + raise azclierror.ArgumentUsageError("Can't use --delete-private-key outside an Azure Cloud Shell session.") + + # include openssh client logs to --debug output to make it easier to users to debug connection issued. if '--debug' in cmd.cli_ctx.data['safe_params'] and set(['-v', '-vv', '-vvv']).isdisjoint(ssh_args): - ssh_args = ['-v'] if not ssh_args else ['-v'] + ssh_args + ssh_args = ['-vvv'] if not ssh_args else ['-vvv'] + ssh_args - _assert_args(resource_group_name, vm_name, ssh_ip, cert_file, local_user) + _assert_args(resource_group_name, vm_name, ssh_ip, resource_type, cert_file, local_user) + + # all credentials for this command are saved in temp folder and deleted at the end of execution. credentials_folder = None + op_call = ssh_utils.start_ssh_connection ssh_session = ssh_info.SSHSession(resource_group_name, vm_name, ssh_ip, public_key_file, private_key_file, use_private_ip, local_user, cert_file, port, - ssh_client_folder, ssh_args) - _do_ssh_op(cmd, ssh_session, credentials_folder, op_call) + ssh_client_folder, ssh_args, delete_credentials, resource_type, + ssh_proxy_folder, credentials_folder) + ssh_session.resource_type = _decide_resource_type(cmd, ssh_session) + _do_ssh_op(cmd, ssh_session, op_call) def ssh_config(cmd, config_path, resource_group_name=None, vm_name=None, ssh_ip=None, public_key_file=None, private_key_file=None, overwrite=False, use_private_ip=False, - local_user=None, cert_file=None, port=None, credentials_folder=None, ssh_client_folder=None): + local_user=None, cert_file=None, port=None, resource_type=None, credentials_folder=None, + ssh_proxy_folder=None, ssh_client_folder=None): - _assert_args(resource_group_name, vm_name, ssh_ip, cert_file, local_user) # If user provides their own key pair, certificate will be written in the same folder as public key. if (public_key_file or private_key_file) and credentials_folder: raise azclierror.ArgumentUsageError("--keys-destination-folder can't be used in conjunction with " "--public-key-file/-p or --private-key-file/-i.") + _assert_args(resource_group_name, vm_name, ssh_ip, resource_type, cert_file, local_user) config_session = ssh_info.ConfigSession(config_path, resource_group_name, vm_name, ssh_ip, public_key_file, - private_key_file, overwrite, use_private_ip, local_user, cert_file, - port, ssh_client_folder) - + private_key_file, overwrite, use_private_ip, local_user, cert_file, port, + resource_type, credentials_folder, ssh_proxy_folder, ssh_client_folder) op_call = ssh_utils.write_ssh_config + config_session.resource_type = _decide_resource_type(cmd, config_session) + # if the folder doesn't exist, this extension won't create a new one. config_folder = os.path.dirname(config_session.config_path) if not os.path.isdir(config_folder): raise azclierror.InvalidArgumentValueError(f"Config file destination folder {config_folder} " "does not exist.") - - # Default credential location - # Add logic to test if credentials folder is valid if not credentials_folder: # * is not a valid name for a folder in Windows. Treat this as a special case. folder_name = config_session.ip if config_session.ip != "*" else "all_ips" if config_session.resource_group_name and config_session.vm_name: folder_name = config_session.resource_group_name + "-" + config_session.vm_name - credentials_folder = os.path.join(config_folder, os.path.join("az_ssh_config", folder_name)) - else: - credentials_folder = os.path.abspath(credentials_folder) + if not set(folder_name).isdisjoint(set(const.WINDOWS_INVALID_FOLDERNAME_CHARS)) and \ + platform.system() == "Windows" and (not config_session.local_user or config_session.is_arc()): + folder_name = file_utils.remove_invalid_characters_foldername(folder_name) + if folder_name == "": + raise azclierror.RequiredArgumentMissingError("Can't create default folder for generated keys. " + "Please provide --keys-destination-folder.") + config_session.credentials_folder = os.path.join(config_folder, os.path.join("az_ssh_config", folder_name)) - _do_ssh_op(cmd, config_session, credentials_folder, op_call) + _do_ssh_op(cmd, config_session, op_call) def ssh_cert(cmd, cert_path=None, public_key_file=None, ssh_client_folder=None): @@ -111,32 +132,61 @@ def ssh_cert(cmd, cert_path=None, public_key_file=None, ssh_client_folder=None): print(Fore.GREEN + f"Generated SSH certificate {cert_file}." + Style.RESET_ALL) -def _do_ssh_op(cmd, op_info, credentials_folder, op_call): +def ssh_arc(cmd, resource_group_name=None, vm_name=None, public_key_file=None, private_key_file=None, + local_user=None, cert_file=None, port=None, ssh_client_folder=None, delete_credentials=False, + ssh_proxy_folder=None, ssh_args=None): + + ssh_vm(cmd, resource_group_name, vm_name, None, public_key_file, private_key_file, False, local_user, cert_file, + port, ssh_client_folder, delete_credentials, "Microsoft.HybridCompute", ssh_proxy_folder, ssh_args) + + +def _do_ssh_op(cmd, op_info, op_call): # Get ssh_ip before getting public key to avoid getting "ResourceNotFound" exception after creating the keys - op_info.ip = op_info.ip or ip_utils.get_ssh_ip(cmd, op_info.resource_group_name, - op_info.vm_name, op_info.use_private_ip) - - if not op_info.ip: - if not op_info.use_private_ip: - raise azclierror.ResourceNotFoundError(f"VM '{op_info.vm_name}' does not have a public " - "IP address to SSH to") - - raise azclierror.ResourceNotFoundError("Internal Error. Couldn't determine the IP address.") + if not op_info.is_arc(): + if op_info.ssh_proxy_folder: + logger.warning("Target machine is not an Arc Server, --ssh-proxy-folder value will be ignored.") + op_info.ip = op_info.ip or ip_utils.get_ssh_ip(cmd, op_info.resource_group_name, + op_info.vm_name, op_info.use_private_ip) + if not op_info.ip: + if not op_info.use_private_ip: + raise azclierror.ResourceNotFoundError(f"VM '{op_info.vm_name}' does not have a public " + "IP address to SSH to") + raise azclierror.ResourceNotFoundError("Internal Error. Couldn't determine the IP address.") # If user provides local user, no credentials should be deleted. delete_keys = False delete_cert = False + cert_lifetime = None # If user provides a local user, use the provided credentials for authentication if not op_info.local_user: delete_cert = True op_info.public_key_file, op_info.private_key_file, delete_keys = \ - _check_or_create_public_private_files(op_info.public_key_file, - op_info.private_key_file, - credentials_folder, - op_info.ssh_client_folder) - + _check_or_create_public_private_files(op_info.public_key_file, op_info.private_key_file, + op_info.credentials_folder, op_info.ssh_client_folder) op_info.cert_file, op_info.local_user = _get_and_write_certificate(cmd, op_info.public_key_file, None, op_info.ssh_client_folder) + if op_info.is_arc(): + # pylint: disable=broad-except + try: + cert_lifetime = ssh_utils.get_certificate_lifetime(op_info.cert_file, + op_info.ssh_client_folder).total_seconds() + except Exception as e: + logger.warning("Couldn't determine certificate expiration. Error: %s", str(e)) + + try: + if op_info.is_arc(): + op_info.proxy_path = connectivity_utils.get_client_side_proxy(op_info.ssh_proxy_folder) + op_info.relay_info = connectivity_utils.get_relay_information(cmd, op_info.resource_group_name, + op_info.vm_name, cert_lifetime) + except Exception as e: + if delete_keys or delete_cert: + logger.debug("An error occured before operation concluded. Deleting generated keys: %s %s %s", + op_info.private_key_file + ', ' if delete_keys else "", + op_info.public_key_file + ', ' if delete_keys else "", + op_info.cert_file if delete_cert else "") + ssh_utils.do_cleanup(delete_keys, delete_cert, op_info.cert_file, + op_info.private_key_file, op_info.public_key_file) + raise e op_call(op_info, delete_keys, delete_cert) @@ -158,6 +208,7 @@ def _get_and_write_certificate(cmd, public_key_file, cert_file, ssh_client_folde from azure.cli.core._profile import Profile profile = Profile(cli_ctx=cmd.cli_ctx) + t0 = time.time() # We currently are using the presence of get_msal_token to detect if we are running on an older azure cli client # TODO: Remove when adal has been deprecated for a while if hasattr(profile, "get_msal_token"): @@ -168,6 +219,9 @@ def _get_and_write_certificate(cmd, public_key_file, cert_file, ssh_client_folde certificatedata = credential.get_token(*scopes, data=data) certificate = certificatedata.token + time_elapsed = time.time() - t0 + telemetry.add_extension_event('ssh', {'Context.Default.AzureCLI.SSHGetCertificateTime': time_elapsed}) + if not cert_file: cert_file = public_key_file + "-aadcert.pub" @@ -199,10 +253,16 @@ def _prepare_jwk_data(public_key_file): return data -def _assert_args(resource_group, vm_name, ssh_ip, cert_file, username): +def _assert_args(resource_group, vm_name, ssh_ip, resource_type, cert_file, username): + if resource_type and resource_type.lower() != "microsoft.compute" \ + and resource_type.lower() != "microsoft.hybridcompute": + raise azclierror.InvalidArgumentValueError("--resource-type must be either \"Microsoft.Compute\" " + "for Azure VMs or \"Microsoft.HybridCompute\" for Arc Servers.") + if not (resource_group or vm_name or ssh_ip): raise azclierror.RequiredArgumentMissingError( - "The VM must be specified by --ip or --resource-group and --vm-name/--name") + "The VM must be specified by --ip or --resource-group and " + "--vm-name/--name") if resource_group and not vm_name or vm_name and not resource_group: raise azclierror.MutuallyExclusiveArgumentError( @@ -223,7 +283,7 @@ def _assert_args(resource_group, vm_name, ssh_ip, cert_file, username): def _check_or_create_public_private_files(public_key_file, private_key_file, credentials_folder, ssh_client_folder=None): delete_keys = False - # If nothing is passed, then create a directory with a ephemeral keypair + # If nothing is passed in create a temporary directory with a ephemeral keypair if not public_key_file and not private_key_file: # We only want to delete the keys if the user hasn't provided their own keys # Only ssh vm deletes generated keys. @@ -255,13 +315,18 @@ def _check_or_create_public_private_files(public_key_file, private_key_file, cre if not os.path.isfile(private_key_file): raise azclierror.FileOperationError(f"Private key file {private_key_file} not found") + # Try to get private key if it's saved next to the public key. Not fail if it can't be found. + if not private_key_file: + if public_key_file.endswith(".pub"): + private_key_file = public_key_file[:-4] if os.path.isfile(public_key_file[:-4]) else None + return public_key_file, private_key_file, delete_keys def _write_cert_file(certificate_contents, cert_file): with open(cert_file, 'w', encoding='utf-8') as f: f.write(f"ssh-rsa-cert-v01@openssh.com {certificate_contents}") - + oschmod.set_mode(cert_file, 0o644) return cert_file @@ -281,3 +346,112 @@ def _get_modulus_exponent(public_key_file): exponent = parser.exponent return modulus, exponent + + +def _decide_resource_type(cmd, op_info): + # If the user provides an IP address the target will be treated as an Azure VM even if it is an + # Arc Server. Which just means that the Connectivity Proxy won't be used to establish connection. + is_arc_server = False + is_azure_vm = False + + if op_info.ip: + is_azure_vm = True + vm = None + + elif op_info.resource_type: + if op_info.resource_type.lower() == "microsoft.hybridcompute": + arc, arc_error, is_arc_server = _check_if_arc_server(cmd, op_info.resource_group_name, op_info.vm_name) + if not is_arc_server: + colorama.init() + if isinstance(arc_error, ResourceNotFoundError): + raise azclierror.ResourceNotFoundError(f"The resource {op_info.vm_name} in the resource group " + f"{op_info.resource_group_name} was not found.", + const.RECOMMENDATION_RESOURCE_NOT_FOUND) + raise azclierror.BadRequestError("Unable to determine that the target machine is an Arc Server. " + f"Error:\n{str(arc_error)}", const.RECOMMENDATION_RESOURCE_NOT_FOUND) + + elif op_info.resource_type.lower() == "microsoft.compute": + vm, vm_error, is_azure_vm = _check_if_azure_vm(cmd, op_info.resource_group_name, op_info.vm_name) + if not is_azure_vm: + colorama.init() + if isinstance(vm_error, ResourceNotFoundError): + raise azclierror.ResourceNotFoundError(f"The resource {op_info.vm_name} in the resource group " + f"{op_info.resource_group_name} was not found.", + const.RECOMMENDATION_RESOURCE_NOT_FOUND) + raise azclierror.BadRequestError("Unable to determine that the target machine is an Azure VM. " + f"Error:\n{str(vm_error)}", const.RECOMMENDATION_RESOURCE_NOT_FOUND) + + else: + vm, vm_error, is_azure_vm = _check_if_azure_vm(cmd, op_info.resource_group_name, op_info.vm_name) + arc, arc_error, is_arc_server = _check_if_arc_server(cmd, op_info.resource_group_name, op_info.vm_name) + + if is_azure_vm and is_arc_server: + colorama.init() + raise azclierror.BadRequestError(f"{op_info.resource_group_name} has Azure VM and Arc Server with the " + f"same name: {op_info.vm_name}.", + Fore.YELLOW + "Please provide a --resource-type." + Style.RESET_ALL) + if not is_azure_vm and not is_arc_server: + colorama.init() + if isinstance(arc_error, ResourceNotFoundError) and isinstance(vm_error, ResourceNotFoundError): + raise azclierror.ResourceNotFoundError(f"The resource {op_info.vm_name} in the resource group " + f"{op_info.resource_group_name} was not found. ", + const.RECOMMENDATION_RESOURCE_NOT_FOUND) + raise azclierror.BadRequestError("Unable to determine the target machine type as Azure VM or " + f"Arc Server. Errors:\n{str(arc_error)}\n{str(vm_error)}", + const.RECOMMENDATION_RESOURCE_NOT_FOUND) + + # Note: We are not able to determine the os of the target if the user only provides an IP address. + os_type = None + if is_azure_vm and vm and vm.storage_profile and vm.storage_profile.os_disk and vm.storage_profile.os_disk.os_type: + os_type = vm.storage_profile.os_disk.os_type + + if is_arc_server and arc and arc.properties and arc.properties and arc.properties.os_name: + os_type = arc.properties.os_name + + # Note 2: This is a temporary check while AAD login is not enabled for Windows. + if os_type and os_type.lower() == 'windows' and not op_info.local_user: + colorama.init() + raise azclierror.RequiredArgumentMissingError("SSH Login using AAD credentials is not currently supported " + "for Windows.", + Fore.YELLOW + "Please provide --local-user." + Style.RESET_ALL) + + if os_type: + telemetry.add_extension_event('ssh', {'Context.Default.AzureCLI.TargetOSType': os_type}) + + target_resource_type = "Microsoft.Compute" + if is_arc_server: + target_resource_type = "Microsoft.HybridCompute" + telemetry.add_extension_event('ssh', {'Context.Default.AzureCLI.TargetResourceType': target_resource_type}) + + return target_resource_type + + +def _check_if_azure_vm(cmd, resource_group_name, vm_name): + from azure.cli.core.commands import client_factory + from azure.cli.core import profiles + vm = None + try: + compute_client = client_factory.get_mgmt_service_client(cmd.cli_ctx, profiles.ResourceType.MGMT_COMPUTE) + vm = compute_client.virtual_machines.get(resource_group_name, vm_name) + except ResourceNotFoundError as e: + return None, e, False + # If user is not authorized to get the VM, it will throw a HttpResponseError + except HttpResponseError as e: + return None, e, False + + return vm, None, True + + +def _check_if_arc_server(cmd, resource_group_name, vm_name): + from azext_ssh._client_factory import cf_machine + client = cf_machine(cmd.cli_ctx) + arc = None + try: + arc = client.get(resource_group_name=resource_group_name, machine_name=vm_name) + except ResourceNotFoundError as e: + return None, e, False + # If user is not authorized to get the arc server, it will throw a HttpResponseError + except HttpResponseError as e: + return None, e, False + + return arc, None, True diff --git a/src/ssh/azext_ssh/file_utils.py b/src/ssh/azext_ssh/file_utils.py index 1e178ab44a..c9ccca3dd3 100644 --- a/src/ssh/azext_ssh/file_utils.py +++ b/src/ssh/azext_ssh/file_utils.py @@ -5,9 +5,9 @@ import errno import os -from knack import log - from azure.cli.core import azclierror +from knack import log +from . import constants as const logger = log.get_logger(__name__) @@ -49,3 +49,38 @@ def delete_folder(dir_path, message, warning=False): logger.warning(message) else: raise azclierror.FileOperationError(message + "Error: " + str(e)) from e + + +def create_directory(file_path, error_message): + try: + os.makedirs(file_path) + except Exception as e: + raise azclierror.FileOperationError(error_message + "Error: " + str(e)) from e + + +def write_to_file(file_path, mode, content, error_message, encoding=None): + # pylint: disable=unspecified-encoding + try: + if encoding: + with open(file_path, mode, encoding=encoding) as f: + f.write(content) + else: + with open(file_path, mode) as f: + f.write(content) + except Exception as e: + raise azclierror.FileOperationError(error_message + "Error: " + str(e)) from e + + +def get_line_that_contains(substring, lines): + for line in lines: + if substring in line: + return line + return None + + +def remove_invalid_characters_foldername(folder_name): + new_foldername = "" + for c in folder_name: + if c not in const.WINDOWS_INVALID_FOLDERNAME_CHARS: + new_foldername += c + return new_foldername diff --git a/src/ssh/azext_ssh/ssh_info.py b/src/ssh/azext_ssh/ssh_info.py index 6ef02efab6..5e99459e92 100644 --- a/src/ssh/azext_ssh/ssh_info.py +++ b/src/ssh/azext_ssh/ssh_info.py @@ -3,13 +3,26 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- import os +import datetime +import oschmod + +import colorama +from colorama import Fore +from colorama import Style + from azure.cli.core import azclierror +from knack import log +from . import file_utils +from . import connectivity_utils + +logger = log.get_logger(__name__) class SSHSession(): # pylint: disable=too-many-instance-attributes def __init__(self, resource_group_name, vm_name, ssh_ip, public_key_file, private_key_file, - use_private_ip, local_user, cert_file, port, ssh_client_folder, ssh_args): + use_private_ip, local_user, cert_file, port, ssh_client_folder, ssh_args, + delete_credentials, resource_type, ssh_proxy_folder, credentials_folder): self.resource_group_name = resource_group_name self.vm_name = vm_name self.ip = ssh_ip @@ -17,35 +30,57 @@ class SSHSession(): self.local_user = local_user self.port = port self.ssh_args = ssh_args + self.delete_credentials = delete_credentials + self.resource_type = resource_type + self.proxy_path = None + self.relay_info = None self.public_key_file = os.path.abspath(public_key_file) if public_key_file else None self.private_key_file = os.path.abspath(private_key_file) if private_key_file else None self.cert_file = os.path.abspath(cert_file) if cert_file else None self.ssh_client_folder = os.path.abspath(ssh_client_folder) if ssh_client_folder else None + self.ssh_proxy_folder = os.path.abspath(ssh_proxy_folder) if ssh_proxy_folder else None + self.credentials_folder = os.path.abspath(credentials_folder) if credentials_folder else None + + def is_arc(self): + if self.resource_type == "Microsoft.HybridCompute": + return True + return False def get_host(self): - if self.local_user and self.ip: - return self.local_user + "@" + self.ip + if not self.is_arc(): + if self.local_user and self.ip: + return self.local_user + "@" + self.ip + else: + if self.local_user and self.vm_name: + return self.local_user + "@" + self.vm_name raise azclierror.BadRequestError("Unable to determine host.") + # build args behaves different depending on the resource type def build_args(self): private_key = [] port_arg = [] certificate = [] + proxy_command = [] if self.private_key_file: private_key = ["-i", self.private_key_file] - if self.port: - port_arg = ["-p", self.port] if self.cert_file: certificate = ["-o", "CertificateFile=\"" + self.cert_file + "\""] - return private_key + certificate + port_arg + if self.is_arc(): + if self.port: + proxy_command = ["-o", f"ProxyCommand=\"{self.proxy_path}\" -p {self.port}"] + else: + proxy_command = ["-o", f"ProxyCommand=\"{self.proxy_path}\""] + else: + if self.port: + port_arg = ["-p", self.port] + return proxy_command + private_key + certificate + port_arg class ConfigSession(): - # pylint: disable=too-few-public-methods # pylint: disable=too-many-instance-attributes def __init__(self, config_path, resource_group_name, vm_name, ssh_ip, public_key_file, private_key_file, overwrite, use_private_ip, local_user, cert_file, port, - ssh_client_folder): + resource_type, credentials_folder, ssh_proxy_folder, ssh_client_folder): self.config_path = os.path.abspath(config_path) self.resource_group_name = resource_group_name self.vm_name = vm_name @@ -54,24 +89,61 @@ class ConfigSession(): self.use_private_ip = use_private_ip self.local_user = local_user self.port = port + self.resource_type = resource_type + self.proxy_path = None + self.relay_info = None + self.relay_info_path = None self.public_key_file = os.path.abspath(public_key_file) if public_key_file else None self.private_key_file = os.path.abspath(private_key_file) if private_key_file else None self.cert_file = os.path.abspath(cert_file) if cert_file else None self.ssh_client_folder = os.path.abspath(ssh_client_folder) if ssh_client_folder else None + self.ssh_proxy_folder = os.path.abspath(ssh_proxy_folder) if ssh_proxy_folder else None + self.credentials_folder = os.path.abspath(credentials_folder) if credentials_folder else None - def get_config_text(self): + def is_arc(self): + if self.resource_type == "Microsoft.HybridCompute": + return True + return False + + def get_config_text(self, is_aad): lines = [""] - if self.resource_group_name and self.vm_name and self.ip: - lines = lines + self._get_rg_and_vm_entry() - # default to all hosts for config - if not self.ip: - self.ip = "*" - lines = lines + self._get_ip_entry() + if self.is_arc(): + self.relay_info_path = self._create_relay_info_file() + lines = lines + self._get_arc_entry(is_aad) + else: + if self.resource_group_name and self.vm_name and self.ip: + lines = lines + self._get_rg_and_vm_entry(is_aad) + # default to all hosts for config + if not self.ip: + self.ip = "*" + lines = lines + self._get_ip_entry(is_aad) return lines - def _get_rg_and_vm_entry(self): + def _get_arc_entry(self, is_aad): lines = [] - lines.append("Host " + self.resource_group_name + "-" + self.vm_name) + if is_aad: + lines.append("Host " + self.resource_group_name + "-" + self.vm_name) + else: + lines.append("Host " + self.resource_group_name + "-" + self.vm_name + "-" + self.local_user) + lines.append("\tHostName " + self.vm_name) + lines.append("\tUser " + self.local_user) + if self.cert_file: + lines.append("\tCertificateFile \"" + self.cert_file + "\"") + if self.private_key_file: + lines.append("\tIdentityFile \"" + self.private_key_file + "\"") + if self.port: + lines.append("\tProxyCommand \"" + self.proxy_path + "\" " + "-r \"" + self.relay_info_path + "\" " + + "-p " + self.port) + else: + lines.append("\tProxyCommand \"" + self.proxy_path + "\" " + "-r \"" + self.relay_info_path + "\"") + return lines + + def _get_rg_and_vm_entry(self, is_aad): + lines = [] + if is_aad: + lines.append("Host " + self.resource_group_name + "-" + self.vm_name) + else: + lines.append("Host " + self.resource_group_name + "-" + self.vm_name + "-" + self.local_user) lines.append("\tUser " + self.local_user) lines.append("\tHostName " + self.ip) if self.cert_file: @@ -82,9 +154,13 @@ class ConfigSession(): lines.append("\tPort " + self.port) return lines - def _get_ip_entry(self): + def _get_ip_entry(self, is_aad): lines = [] - lines.append("Host " + self.ip) + if is_aad: + lines.append("Host " + self.ip) + else: + lines.append("Host " + self.ip + "-" + self.local_user) + lines.append("\tHostName " + self.ip) lines.append("\tUser " + self.local_user) if self.cert_file: lines.append("\tCertificateFile \"" + self.cert_file + "\"") @@ -93,3 +169,30 @@ class ConfigSession(): if self.port: lines.append("\tPort " + self.port) return lines + + def _create_relay_info_file(self): + relay_info_dir = self.credentials_folder + relay_info_filename = None + if not os.path.isdir(relay_info_dir): + os.makedirs(relay_info_dir) + + if self.vm_name and self.resource_group_name: + relay_info_filename = self.resource_group_name + "-" + self.vm_name + "-relay_info" + + relay_info_path = os.path.join(relay_info_dir, relay_info_filename) + # Overwrite relay_info if it already exists in that folder. + file_utils.delete_file(relay_info_path, f"{relay_info_path} already exists, and couldn't be overwritten.") + file_utils.write_to_file(relay_info_path, 'w', connectivity_utils.format_relay_info_string(self.relay_info), + f"Couldn't write relay information to file {relay_info_path}.", 'utf-8') + oschmod.set_mode(relay_info_path, 0o644) + # pylint: disable=broad-except + try: + expiration = datetime.datetime.fromtimestamp(self.relay_info.expires_on) + expiration = expiration.strftime("%Y-%m-%d %I:%M:%S %p") + colorama.init() + print(Fore.GREEN + f"Generated relay information {relay_info_path} is valid until {expiration} " + "in local time." + Style.RESET_ALL) + except Exception as e: + logger.warning("Couldn't determine relay information expiration. Error: %s", str(e)) + + return relay_info_path diff --git a/src/ssh/azext_ssh/ssh_utils.py b/src/ssh/azext_ssh/ssh_utils.py index 6b33833c47..aa85f33687 100644 --- a/src/ssh/azext_ssh/ssh_utils.py +++ b/src/ssh/azext_ssh/ssh_utils.py @@ -5,97 +5,88 @@ import os import platform import subprocess -import time import multiprocessing as mp +import time import datetime import re -from azext_ssh import file_utils +import colorama + +from colorama import Fore +from colorama import Style from knack import log from azure.cli.core import azclierror +from azure.cli.core import telemetry + +from . import file_utils +from . import connectivity_utils +from . import constants as const logger = log.get_logger(__name__) -CLEANUP_TOTAL_TIME_LIMIT_IN_SECONDS = 120 -CLEANUP_TIME_INTERVAL_IN_SECONDS = 10 -CLEANUP_AWAIT_TERMINATION_IN_SECONDS = 30 +def start_ssh_connection(op_info, delete_keys, delete_cert): + try: + # Initialize these so that if something fails in the try block before these + # are initialized, then the finally block won't fail. + cleanup_process = None + log_file = None + connection_status = None -def start_ssh_connection(ssh_info, delete_keys, delete_cert): + ssh_arg_list = [] + if op_info.ssh_args: + ssh_arg_list = op_info.ssh_args - ssh_arg_list = [] - if ssh_info.ssh_args: - ssh_arg_list = ssh_info.ssh_args + env = os.environ.copy() + if op_info.is_arc(): + env['SSHPROXY_RELAY_INFO'] = connectivity_utils.format_relay_info_string(op_info.relay_info) - command = [_get_ssh_client_path('ssh', ssh_info.ssh_client_folder), ssh_info.get_host()] + # Get ssh client before starting the clean up process in case there is an error in getting client. + command = [_get_ssh_client_path('ssh', op_info.ssh_client_folder), op_info.get_host()] - log_file = None - if delete_keys or delete_cert: - if '-E' not in ssh_arg_list and set(['-v', '-vv', '-vvv']).isdisjoint(ssh_arg_list): - # If the user either provides his own client log file (-E) or - # wants the client log messages to be printed to the console (-vvv/-vv/-v), - # we should not use the log files to check for connection success. - log_file_dir = os.path.dirname(ssh_info.cert_file) - log_file_name = 'ssh_client_log_' + str(os.getpid()) - log_file = os.path.join(log_file_dir, log_file_name) - ssh_arg_list = ['-E', log_file, '-v'] + ssh_arg_list - # Create a new process that will wait until the connection is established and then delete keys. - cleanup_process = mp.Process(target=_do_cleanup, args=(delete_keys, delete_cert, ssh_info.cert_file, - ssh_info.private_key_file, ssh_info.public_key_file, log_file, True)) - cleanup_process.start() + if not op_info.cert_file and not op_info.private_key_file: + # In this case, even if delete_credentials is true, there is nothing to clean-up. + op_info.delete_credentials = False - command = command + ssh_info.build_args() + ssh_arg_list + log_file, ssh_arg_list, cleanup_process = _start_cleanup(op_info.cert_file, op_info.private_key_file, + op_info.public_key_file, op_info.delete_credentials, + delete_keys, delete_cert, ssh_arg_list) + command = command + op_info.build_args() + ssh_arg_list - logger.debug("Running ssh command %s", ' '.join(command)) - connection_status = subprocess.call(command, shell=platform.system() == 'Windows') + connection_duration = time.time() + logger.debug("Running ssh command %s", ' '.join(command)) - if delete_keys or delete_cert: - if cleanup_process.is_alive(): - cleanup_process.terminate() - # wait for process to terminate - t0 = time.time() - while cleanup_process.is_alive() and (time.time() - t0) < CLEANUP_AWAIT_TERMINATION_IN_SECONDS: - time.sleep(1) + # pylint: disable=subprocess-run-check + try: + if set(['-v', '-vv', '-vvv']).isdisjoint(ssh_arg_list) or log_file: + connection_status = subprocess.run(command, env=env, stderr=subprocess.PIPE, text=True) + else: + # Logs are sent to stderr. In that case, we shouldn't capture stderr. + connection_status = subprocess.run(command, env=env, text=True) + except Exception as e: + colorama.init() + raise azclierror.BadRequestError(f"Failed to run ssh command with error: {str(e)}.", + const.RECOMMENDATION_SSH_CLIENT_NOT_FOUND) - if log_file: - _print_error_messages_from_ssh_log(log_file, connection_status) + connection_duration = (time.time() - connection_duration) / 60 + ssh_connection_data = {'Context.Default.AzureCLI.SSHConnectionDurationInMinutes': connection_duration} + if connection_status and connection_status.returncode == 0: + ssh_connection_data['Context.Default.AzureCLI.SSHConnectionStatus'] = "Success" + telemetry.add_extension_event('ssh', ssh_connection_data) - # Make sure all files have been properly removed. - _do_cleanup(delete_keys, delete_cert, ssh_info.cert_file, ssh_info.private_key_file, ssh_info.public_key_file) - if log_file: - file_utils.delete_file(log_file, f"Couldn't delete temporary log file {log_file}. ", True) - if delete_keys: - temp_dir = os.path.dirname(ssh_info.cert_file) - file_utils.delete_folder(temp_dir, f"Couldn't delete temporary folder {temp_dir}", True) + finally: + # Even if something fails between the creation of the credentials and the end of the ssh connection, we + # want to make sure that all credentials are cleaned up, and that the clean up process is terminated. + _terminate_cleanup(delete_keys, delete_cert, op_info.delete_credentials, cleanup_process, op_info.cert_file, + op_info.private_key_file, op_info.public_key_file, log_file, connection_status) def write_ssh_config(config_info, delete_keys, delete_cert): - - if delete_keys or delete_cert: - # Warn users to delete credentials once config file is no longer being used. - # If user provided keys, only ask them to delete the certificate. - path_to_delete = os.path.dirname(config_info.cert_file) - items_to_delete = " (id_rsa, id_rsa.pub, id_rsa.pub-aadcert.pub)" - if not delete_keys: - path_to_delete = config_info.cert_file - items_to_delete = "" - - expiration = None - # pylint: disable=broad-except - try: - expiration = get_certificate_start_and_end_times(config_info.cert_file, config_info.ssh_client_folder)[1] - expiration = expiration.strftime("%Y-%m-%d %I:%M:%S %p") - except Exception as e: - logger.warning("Couldn't determine certificate expiration. Error: %s", str(e)) - - if expiration: - logger.warning("The generated certificate %s is valid until %s in local time.", - config_info.cert_file, expiration) - logger.warning("%s contains sensitive information%s. Please delete it once you no longer this config file.", - path_to_delete, items_to_delete) - - config_text = config_info.get_config_text() - + # if delete cert is true, then this is AAD login. + config_text = config_info.get_config_text(delete_cert) + _issue_config_cleanup_warning(delete_cert, delete_keys, config_info.is_arc(), + config_info.cert_file, config_info.relay_info_path, + config_info.ssh_client_folder) if config_info.overwrite: mode = 'w' else: @@ -108,30 +99,24 @@ def create_ssh_keyfile(private_key_file, ssh_client_folder=None): sshkeygen_path = _get_ssh_client_path("ssh-keygen", ssh_client_folder) command = [sshkeygen_path, "-f", private_key_file, "-t", "rsa", "-q", "-N", ""] logger.debug("Running ssh-keygen command %s", ' '.join(command)) - subprocess.call(command, shell=platform.system() == 'Windows') + try: + subprocess.call(command) + except Exception as e: + colorama.init() + raise azclierror.BadRequestError(f"Failed to create ssh key file with error: {str(e)}.", + const.RECOMMENDATION_SSH_CLIENT_NOT_FOUND) def get_ssh_cert_info(cert_file, ssh_client_folder=None): sshkeygen_path = _get_ssh_client_path("ssh-keygen", ssh_client_folder) command = [sshkeygen_path, "-L", "-f", cert_file] logger.debug("Running ssh-keygen command %s", ' '.join(command)) - return subprocess.check_output(command, shell=platform.system() == 'Windows').decode().splitlines() - - -def get_ssh_cert_principals(cert_file, ssh_client_folder=None): - info = get_ssh_cert_info(cert_file, ssh_client_folder) - principals = [] - in_principal = False - for line in info: - if ":" in line: - in_principal = False - if "Principals:" in line: - in_principal = True - continue - if in_principal: - principals.append(line.strip()) - - return principals + try: + return subprocess.check_output(command).decode().splitlines() + except Exception as e: + colorama.init() + raise azclierror.BadRequestError(f"Failed to get certificate info with error: {str(e)}.", + const.RECOMMENDATION_SSH_CLIENT_NOT_FOUND) def _get_ssh_cert_validity(cert_file, ssh_client_folder=None): @@ -154,24 +139,53 @@ def get_certificate_start_and_end_times(cert_file, ssh_client_folder=None): return times -def _print_error_messages_from_ssh_log(log_file, connection_status): +def get_certificate_lifetime(cert_file, ssh_client_folder=None): + times = get_certificate_start_and_end_times(cert_file, ssh_client_folder) + lifetime = None + if times: + lifetime = times[1] - times[0] + return lifetime + + +def get_ssh_cert_principals(cert_file, ssh_client_folder=None): + info = get_ssh_cert_info(cert_file, ssh_client_folder) + principals = [] + in_principal = False + for line in info: + if ":" in line: + in_principal = False + if "Principals:" in line: + in_principal = True + continue + if in_principal: + principals.append(line.strip()) + + return principals + + +def _print_error_messages_from_ssh_log(log_file, connection_status, delete_cert): with open(log_file, 'r', encoding='utf-8') as ssh_log: log_text = ssh_log.read() log_lines = log_text.splitlines() - if "debug1: Authentication succeeded" not in log_text or connection_status != 0: + if ("debug1: Authentication succeeded" not in log_text and + not re.search("^Authenticated to .*\n", log_text, re.MULTILINE)) \ + or (connection_status and connection_status.returncode): for line in log_lines: if "debug1:" not in line: print(line) - if "Permission denied (publickey)." in log_text: + # This connection fails when using our generated certificates. + # Only throw error if conection fails with AAD login. + if "Permission denied (publickey)." in log_text and delete_cert: # pylint: disable=bare-except # pylint: disable=too-many-boolean-expressions # Check if OpenSSH client and server versions are incompatible try: regex = 'OpenSSH.*_([0-9]+)\\.([0-9]+)' local_major, local_minor = re.findall(regex, log_lines[0])[0] - remote_major, remote_minor = re.findall(regex, _get_line_that_contains("remote software version", - log_lines))[0] + remote_major, remote_minor = re.findall(regex, + file_utils.get_line_that_contains("remote software version", + log_lines))[0] local_major = int(local_major) local_minor = int(local_minor) remote_major = int(remote_major) @@ -196,13 +210,6 @@ def _print_error_messages_from_ssh_log(log_file, connection_status): ssh_log.close() -def _get_line_that_contains(substring, lines): - for line in lines: - if substring in line: - return line - return None - - def _get_ssh_client_path(ssh_command="ssh", ssh_client_folder=None): if ssh_client_folder: ssh_path = os.path.join(ssh_client_folder, ssh_command) @@ -212,70 +219,34 @@ def _get_ssh_client_path(ssh_command="ssh", ssh_client_folder=None): logger.debug("Attempting to run %s from path %s", ssh_command, ssh_path) return ssh_path logger.warning("Could not find %s in provided --ssh-client-folder %s. " - "Attempting to get pre-installed OpenSSH bits.", ssh_command, ssh_client_folder) + "Attempting to use pre-installed OpenSSH.", ssh_path, ssh_client_folder) ssh_path = ssh_command - - if platform.system() == 'Windows': - # If OS architecture is 64bit and python architecture is 32bit, - # look for System32 under SysNative folder. - machine = platform.machine() - os_architecture = None - # python interpreter architecture - platform_architecture = platform.architecture()[0] - sys_path = None - - if machine.endswith('64'): - os_architecture = '64bit' - elif machine.endswith('86'): - os_architecture = '32bit' - elif machine == '': - raise azclierror.BadRequestError("Couldn't identify the OS architecture.") - else: - raise azclierror.BadRequestError(f"Unsuported OS architecture: {machine} is not currently supported") - - if os_architecture == "64bit": - sys_path = 'SysNative' if platform_architecture == '32bit' else 'System32' - else: - sys_path = 'System32' - - system_root = os.environ['SystemRoot'] - system32_path = os.path.join(system_root, sys_path) - ssh_path = os.path.join(system32_path, "openSSH", (ssh_command + ".exe")) - logger.debug("Platform architecture: %s", platform_architecture) - logger.debug("OS architecture: %s", os_architecture) - logger.debug("System Root: %s", system_root) - logger.debug("Attempting to run %s from path %s", ssh_command, ssh_path) - - if not os.path.isfile(ssh_path): - raise azclierror.UnclassifiedUserFault( - "Could not find " + ssh_command + ".exe on path " + ssh_path + ". " - "Make sure OpenSSH is installed correctly: " - "https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse . " - "Or use --ssh-client-folder to provide folder path with ssh executables. ") - return ssh_path -def _do_cleanup(delete_keys, delete_cert, cert_file, private_key, public_key, log_file=None, wait=False): - # if there is a log file, use it to check for the connection success +def do_cleanup(delete_keys, delete_cert, cert_file, private_key, public_key, log_file=None, wait=False): if log_file: t0 = time.time() match = False - while (time.time() - t0) < CLEANUP_TOTAL_TIME_LIMIT_IN_SECONDS and not match: - time.sleep(CLEANUP_TIME_INTERVAL_IN_SECONDS) + while (time.time() - t0) < const.CLEANUP_TOTAL_TIME_LIMIT_IN_SECONDS and not match: + time.sleep(const.CLEANUP_TIME_INTERVAL_IN_SECONDS) # pylint: disable=bare-except + # pylint: disable=anomalous-backslash-in-string try: with open(log_file, 'r', encoding='utf-8') as ssh_client_log: - match = "debug1: Authentication succeeded" in ssh_client_log.read() + log_text = ssh_client_log.read() + # The "debug1:..." message doesn't seems to exist in OpenSSH 3.9 + match = ("debug1: Authentication succeeded" in log_text or + re.search("^Authenticated to .*\n", log_text, re.MULTILINE)) ssh_client_log.close() except: # If there is an exception, wait for a little bit and try again - time.sleep(CLEANUP_TIME_INTERVAL_IN_SECONDS) + time.sleep(const.CLEANUP_TIME_INTERVAL_IN_SECONDS) elif wait: # if we are not checking the logs, but still want to wait for connection before deleting files - time.sleep(CLEANUP_TOTAL_TIME_LIMIT_IN_SECONDS) + time.sleep(const.CLEANUP_TOTAL_TIME_LIMIT_IN_SECONDS) if delete_keys and private_key: file_utils.delete_file(private_key, f"Couldn't delete private key {private_key}. ", True) @@ -283,3 +254,101 @@ def _do_cleanup(delete_keys, delete_cert, cert_file, private_key, public_key, lo file_utils.delete_file(public_key, f"Couldn't delete public key {public_key}. ", True) if delete_cert and cert_file: file_utils.delete_file(cert_file, f"Couldn't delete certificate {cert_file}. ", True) + + +def _start_cleanup(cert_file, private_key_file, public_key_file, delete_credentials, delete_keys, + delete_cert, ssh_arg_list): + log_file = None + cleanup_process = None + if delete_keys or delete_cert or delete_credentials: + if '-E' not in ssh_arg_list and set(['-v', '-vv', '-vvv']).isdisjoint(ssh_arg_list): + # If the user either provides his own client log file (-E) or + # wants the client log messages to be printed to the console (-vvv/-vv/-v), + # we should not use the log files to check for connection success. + if cert_file: + log_dir = os.path.dirname(cert_file) + elif private_key_file: + log_dir = os.path.dirname(private_key_file) + log_file_name = 'ssh_client_log_' + str(os.getpid()) + log_file = os.path.join(log_dir, log_file_name) + ssh_arg_list = ['-E', log_file, '-v'] + ssh_arg_list + # Create a new process that will wait until the connection is established and then delete keys. + cleanup_process = mp.Process(target=do_cleanup, args=(delete_keys or delete_credentials, + delete_cert or delete_credentials, + cert_file, private_key_file, public_key_file, + log_file, True)) + cleanup_process.start() + + return log_file, ssh_arg_list, cleanup_process + + +def _terminate_cleanup(delete_keys, delete_cert, delete_credentials, cleanup_process, cert_file, + private_key_file, public_key_file, log_file, connection_status): + try: + if connection_status and connection_status.stderr: + if connection_status.returncode != 0: + # Check if stderr is a proxy error + regex = ("{\"level\":\"fatal\",\"msg\":\"sshproxy: error copying information from the connection: " + ".*\",\"time\":\".*\"}.*") + if re.search(regex, connection_status.stderr): + logger.error("Please make sure SSH port is allowed using \"azcmagent config list\" in the target " + "Arc Server. Ensure SSHD is running on the target machine.") + print(connection_status.stderr) + finally: + if delete_keys or delete_cert or delete_credentials: + if cleanup_process and cleanup_process.is_alive(): + cleanup_process.terminate() + # wait for process to terminate + t0 = time.time() + while cleanup_process.is_alive() and (time.time() - t0) < const.CLEANUP_AWAIT_TERMINATION_IN_SECONDS: + time.sleep(1) + + if log_file and os.path.isfile(log_file): + _print_error_messages_from_ssh_log(log_file, connection_status, delete_cert) + + # Make sure all files have been properly removed. + do_cleanup(delete_keys or delete_credentials, delete_cert or delete_credentials, + cert_file, private_key_file, public_key_file) + if log_file: + file_utils.delete_file(log_file, f"Couldn't delete temporary log file {log_file}. ", True) + if delete_keys: + # This is only true if keys were generated, so they must be in a temp folder. + temp_dir = os.path.dirname(cert_file) + file_utils.delete_folder(temp_dir, f"Couldn't delete temporary folder {temp_dir}", True) + + +def _issue_config_cleanup_warning(delete_cert, delete_keys, is_arc, cert_file, relay_info_path, ssh_client_folder): + if delete_cert: + colorama.init() + # pylint: disable=broad-except + try: + expiration = get_certificate_start_and_end_times(cert_file, ssh_client_folder)[1] + expiration = expiration.strftime("%Y-%m-%d %I:%M:%S %p") + print(Fore.GREEN + f"Generated SSH certificate {cert_file} is valid until {expiration} in local time." + + Style.RESET_ALL) + except Exception as e: + logger.warning("Couldn't determine certificate expiration. Error: %s", str(e)) + + if delete_keys or delete_cert or is_arc: + # Warn users to delete credentials once config file is no longer being used. + # If user provided keys, only ask them to delete the certificate. + if is_arc: + relay_info_filename = os.path.basename(relay_info_path) + if delete_keys and delete_cert: + path_to_delete = f"{os.path.dirname(cert_file)} contains" + items_to_delete = f" (id_rsa, id_rsa.pub, id_rsa.pub-aadcert.pub, {relay_info_filename})" + elif delete_cert: + path_to_delete = f"{cert_file} and {relay_info_path} contain" + items_to_delete = "" + else: + path_to_delete = f"{relay_info_path} contains" + items_to_delete = "" + else: + path_to_delete = f"{os.path.dirname(cert_file)} contains" + items_to_delete = " (id_rsa, id_rsa.pub, id_rsa.pub-aadcert.pub)" + if not delete_keys: + path_to_delete = f"{cert_file} contains" + items_to_delete = "" + + logger.warning("%s sensitive information%s. Please delete it once you no longer " + "need this config file.", path_to_delete, items_to_delete) diff --git a/src/ssh/azext_ssh/tests/latest/test_custom.py b/src/ssh/azext_ssh/tests/latest/test_custom.py index 96ee88879d..51212fac19 100644 --- a/src/ssh/azext_ssh/tests/latest/test_custom.py +++ b/src/ssh/azext_ssh/tests/latest/test_custom.py @@ -2,16 +2,15 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- - import io -from azure.cli.core import azclierror -from unittest import mock import unittest - - +from unittest import mock from azext_ssh import custom -from azext_ssh import ssh_info from azext_ssh import ssh_utils +from azext_ssh import ssh_info + +from azure.cli.core import azclierror +from azure.core.exceptions import ResourceNotFoundError class SshCustomCommandTest(unittest.TestCase): @@ -19,49 +18,132 @@ class SshCustomCommandTest(unittest.TestCase): @mock.patch('azext_ssh.custom._do_ssh_op') @mock.patch('azext_ssh.custom._assert_args') @mock.patch('azext_ssh.ssh_info.SSHSession') - def test_ssh_vm(self, mock_info, mock_assert, mock_do_op): + @mock.patch('azext_ssh.custom._decide_resource_type') + def test_ssh_vm(self, mock_type, mock_info, mock_assert, mock_do_op): cmd = mock.Mock() + ssh_info = mock.Mock() + mock_info.return_value = ssh_info cmd.cli_ctx.data = {'safe_params': []} - custom.ssh_vm(cmd, "rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", ['-vvv']) + custom.ssh_vm(cmd, "rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", False, "type", "proxy", ['-vvv']) - mock_info.assert_called_once_with("rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", ['-vvv']) - mock_assert.assert_called_once_with("rg", "vm", "ip", "cert", "username") - mock_do_op.assert_called_once_with(cmd, mock.ANY, None, ssh_utils.start_ssh_connection) + mock_info.assert_called_once_with("rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", ['-vvv'], False, "type", "proxy", None) + mock_assert.assert_called_once_with("rg", "vm", "ip", "type", "cert", "username") + mock_type.assert_called_once_with(cmd, ssh_info) + mock_do_op.assert_called_once_with(cmd, ssh_info, ssh_utils.start_ssh_connection) @mock.patch('azext_ssh.custom._do_ssh_op') @mock.patch('azext_ssh.custom._assert_args') @mock.patch('azext_ssh.ssh_info.SSHSession') - def test_ssh_vm_debug(self, mock_info, mock_assert, mock_do_op): + @mock.patch('azext_ssh.custom._decide_resource_type') + def test_ssh_vm_debug(self, mock_type, mock_info, mock_assert, mock_do_op): cmd = mock.Mock() + ssh_info = mock.Mock() + mock_info.return_value = ssh_info cmd.cli_ctx.data = {'safe_params': ['--debug']} - custom.ssh_vm(cmd, "rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", []) + custom.ssh_vm(cmd, "rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", False, "type", "proxy", []) - mock_info.assert_called_once_with("rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", ['-v']) - mock_assert.assert_called_once_with("rg", "vm", "ip", "cert", "username") - mock_do_op.assert_called_once_with(cmd, mock.ANY, None, ssh_utils.start_ssh_connection) + mock_info.assert_called_once_with("rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", ['-vvv'], False, "type", "proxy", None) + mock_assert.assert_called_once_with("rg", "vm", "ip", "type", "cert", "username") + mock_type.assert_called_once_with(cmd, ssh_info) + mock_do_op.assert_called_once_with(cmd, ssh_info, ssh_utils.start_ssh_connection) @mock.patch('azext_ssh.custom._do_ssh_op') - @mock.patch('azext_ssh.ssh_utils.write_ssh_config') + @mock.patch('azext_ssh.custom._decide_resource_type') + @mock.patch('os.environ.get') @mock.patch('azext_ssh.custom._assert_args') - @mock.patch('os.path.isdir') - @mock.patch('os.path.dirname') - @mock.patch('os.path.join') - @mock.patch('azext_ssh.ssh_info.ConfigSession') - def test_ssh_config(self, mock_info, mock_join, mock_dirname, mock_isdir, mock_assert, mock_ssh_utils, mock_do_op): + @mock.patch('azext_ssh.ssh_info.SSHSession') + def test_ssh_vm_delete_credentials_cloudshell(self, mock_info, mock_assert, mock_getenv, mock_type, mock_op): + mock_getenv.return_value = "cloud-shell/1.0" cmd = mock.Mock() - mock_dirname.return_value = "configdir" + ssh_info = mock.Mock() + cmd.cli_ctx.data = {'safe_params': []} + mock_info.return_value = ssh_info + + custom.ssh_vm(cmd, "rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", True, "type", "proxy", []) + + mock_info.assert_called_once_with("rg", "vm", "ip", "public", "private", False, "username", "cert", "port", "ssh_folder", [], True, "type", "proxy", None) + mock_assert.assert_called_once_with("rg", "vm", "ip", "type", "cert", "username") + mock_type.assert_called_once_with(cmd, ssh_info) + mock_op.assert_called_once_with(cmd, ssh_info, ssh_utils.start_ssh_connection) + + @mock.patch('os.environ.get') + def test_delete_credentials_not_cloudshell(self, mock_getenv): + mock_getenv.return_value = None + cmd = mock.Mock() + self.assertRaises( + azclierror.ArgumentUsageError, custom.ssh_vm, cmd, 'rg', 'vm', 'ip', 'pub', 'priv', False, 'user', 'cert', 'port', 'client', True, 'type', 'proxy', []) + + @mock.patch('azext_ssh.custom._assert_args') + @mock.patch('azext_ssh.custom._do_ssh_op') + @mock.patch('azext_ssh.custom._decide_resource_type') + @mock.patch('os.path.dirname') + @mock.patch('os.path.isdir') + @mock.patch('azext_ssh.ssh_info.ConfigSession') + @mock.patch('os.path.join') + def test_ssh_config_no_cred_folder(self, mock_join, mock_info, mock_isdir, mock_dirname, mock_type, mock_do_op, mock_assert): + cmd = mock.Mock() + + config_info = mock.Mock() + config_info.ip = "ip" + config_info.resource_group_name = "rg" + config_info.vm_name = "vm" + config_info.credentials_folder = None + + mock_info.return_value = config_info mock_isdir.return_value = True + mock_dirname.return_value = "config_folder" + + expected_join_calls = [ + mock.call("az_ssh_config", "rg-vm"), + mock.call("config_folder", "az_ssh_config/rg-vm") + ] mock_join.side_effect = ['az_ssh_config/rg-vm', 'path/to/az_ssh_config/rg-vm'] - custom.ssh_config(cmd, "path/to/file", "rg", "vm", "ip", "public", "private", False, False, "username", "cert", "port", None, "client/folder") + custom.ssh_config(cmd, "config", "rg", "vm", "ip", "pub", "priv", True, False, "user", "cert", "port", "type", None, "proxy", "client") - mock_info.assert_called_once_with("path/to/file", "rg", "vm", "ip", "public", "private", False, False, "username", "cert", "port", "client/folder") - mock_assert.assert_called_once_with("rg", "vm", "ip", "cert", "username") - mock_do_op.assert_called_once_with(cmd, mock.ANY, 'path/to/az_ssh_config/rg-vm', ssh_utils.write_ssh_config) + mock_join.assert_has_calls(expected_join_calls) + mock_info.assert_called_once_with("config", "rg", "vm", "ip", "pub", "priv", True, False, "user", "cert", "port", "type", None, "proxy", "client") + mock_type.assert_called_once_with(cmd, config_info) + mock_assert.assert_called_once_with("rg", "vm", "ip", "type", "cert", "user") + mock_do_op.assert_called_once_with(cmd, config_info, ssh_utils.write_ssh_config) + + @mock.patch('azext_ssh.custom._assert_args') + @mock.patch('azext_ssh.custom._do_ssh_op') + @mock.patch('azext_ssh.custom._decide_resource_type') + @mock.patch('azext_ssh.ssh_info.ConfigSession') + @mock.patch('os.path.isdir') + @mock.patch('os.path.dirname') + def test_ssh_config_cred_folder(self, mock_dirname, mock_isdir, mock_info, mock_type, mock_op, mock_assert): + cmd = mock.Mock() + config_info = mock.Mock() + mock_info.return_value = config_info + mock_isdir.return_value = True + mock_dirname.return_value = "config_folder" + + custom.ssh_config(cmd, "config", "rg", "vm", "ip", None, None, True, False, "user", "cert", "port", "type", "cred", "proxy", "client") + + mock_type.assert_called_once_with(cmd, config_info) + mock_info.assert_called_once_with("config", "rg", "vm", "ip", None, None, True, False, "user", "cert", "port", "type", "cred", "proxy", "client") + mock_assert.assert_called_once_with("rg", "vm", "ip", "type", "cert", "user") + mock_op.assert_called_once_with(cmd, config_info, ssh_utils.write_ssh_config) + + + def test_ssh_config_credentials_folder_and_key(self): + cmd = mock.Mock() + self.assertRaises( + azclierror.ArgumentUsageError, custom.ssh_config, cmd, 'path', 'rg', 'vm', 'ip', 'pub', 'priv', True, False, 'user', 'cert', 'port', 'type', 'cred', 'proxy', 'client' + ) + + @mock.patch('azext_ssh.custom.ssh_vm') + def test_ssh_arc(self, mock_vm): + cmd = mock.Mock() + custom.ssh_arc(cmd, "rg", "vm", "pub", "priv", "user", "cert", "port", "client", False, "proxy", []) + + mock_vm.assert_called_once_with(cmd, "rg", "vm", None, "pub", "priv", False, "user", "cert", "port", "client", False, "Microsoft.HybridCompute", "proxy", []) def test_ssh_cert_no_args(self): cmd = mock.Mock() @@ -90,126 +172,30 @@ class SshCustomCommandTest(unittest.TestCase): mock_get_keys.assert_called_once_with('/pubkey/path', None, None, '/client/path') mock_write_cert.assert_called_once_with(cmd, 'pubkey', '/cert/path', '/client/path') - - @mock.patch('os.path.isdir') - @mock.patch('os.path.abspath') - @mock.patch('azext_ssh.custom._check_or_create_public_private_files') - @mock.patch('azext_ssh.custom._get_and_write_certificate') - def test_ssh_cert(self, mock_write_cert, mock_get_keys, mock_abspath, mock_isdir): - cmd = mock.Mock() - mock_isdir.return_value = True - mock_abspath.side_effect = ['/pubkey/path', '/cert/path', '/client/path'] - mock_get_keys.return_value = "pubkey", "privkey", False - mock_write_cert.return_value = "cert", "username" - - custom.ssh_cert(cmd, "cert", "pubkey", "ssh/folder") - - mock_get_keys.assert_called_once_with('/pubkey/path', None, None, '/client/path') - mock_write_cert.assert_called_once_with(cmd, 'pubkey', '/cert/path', '/client/path') - - @mock.patch('azext_ssh.ssh_utils.get_ssh_cert_principals') - @mock.patch('os.path.join') - @mock.patch('azext_ssh.custom._check_or_create_public_private_files') - @mock.patch('azext_ssh.ip_utils.get_ssh_ip') - @mock.patch('azext_ssh.custom._get_modulus_exponent') - @mock.patch('azure.cli.core._profile.Profile') - @mock.patch('azext_ssh.custom._write_cert_file') - def test_do_ssh_op_aad_user(self, mock_write_cert, mock_ssh_creds, mock_get_mod_exp, mock_ip, - mock_check_files, mock_join, mock_principal): - cmd = mock.Mock() - cmd.cli_ctx = mock.Mock() - cmd.cli_ctx.cloud = mock.Mock() - cmd.cli_ctx.cloud.name = "azurecloud" - - op_info = mock.Mock() - op_info.ip = "1.2.3.4" - op_info.public_key_file = "publicfile" - op_info.private_key_file = "privatefile" - op_info.use_private_ip = False - op_info.local_user = None - op_info.cert_file = None - op_info.ssh_client_folder = "/client/folder" - - mock_op = mock.Mock() - mock_check_files.return_value = "public", "private", False - mock_principal.return_value = ["username"] - mock_get_mod_exp.return_value = "modulus", "exponent" - profile = mock_ssh_creds.return_value - profile._adal_cache = True - profile.get_msal_token.return_value = "username", "certificate" - mock_join.return_value = "public-aadcert.pub" - - custom._do_ssh_op(cmd, op_info, "cred/folder", mock_op) - - mock_check_files.assert_called_once_with("publicfile", "privatefile", "cred/folder", "/client/folder") - mock_ip.assert_not_called() - mock_get_mod_exp.assert_called_once_with("public") - mock_write_cert.assert_called_once_with("certificate", "public-aadcert.pub") - mock_op.assert_called_once_with(op_info, False, True) - @mock.patch('azext_ssh.custom._check_or_create_public_private_files') - @mock.patch('azext_ssh.ip_utils.get_ssh_ip') - def test_do_ssh_op_local_user(self, mock_ip, mock_check_files): - cmd = mock.Mock() - mock_op = mock.Mock() - mock_ip.return_value = "1.2.3.4" - - op_info = mock.Mock() - op_info.resource_group_name = "rg" - op_info.vm_name = "vm" - op_info.ip = None - op_info.public_key_file = "publicfile" - op_info.private_key_file = "privatefile" - op_info.use_private_ip = False - op_info.local_user = "username" - op_info.certificate = "cert" - op_info.ssh_client_folder = "/client/folder" - - custom._do_ssh_op(cmd, op_info, "/cred/folder", mock_op) - - mock_check_files.assert_not_called() - mock_ip.assert_called_once_with(cmd, "rg", "vm", False) - mock_op.assert_called_once_with(op_info, False, False) - - @mock.patch('azext_ssh.custom._check_or_create_public_private_files') - @mock.patch('azext_ssh.ip_utils.get_ssh_ip') - def test_do_ssh_op_no_public_ip(self, mock_ip, mock_check_files): - cmd = mock.Mock() - mock_op = mock.Mock() - mock_ip.return_value = None - - op_info = mock.Mock() - op_info.vm_name = "vm" - op_info.resource_group_name = "rg" - op_info.ip = None - op_info.use_private_ip = False - - self.assertRaises( - azclierror.ResourceNotFoundError, custom._do_ssh_op, cmd, op_info, "/cred/folder", mock_op) - - mock_check_files.assert_not_called() - mock_ip.assert_called_once_with(cmd, "rg", "vm", False) - mock_op.assert_not_called() - + def test_assert_args_invalid_resource_type(self): + self.assertRaises(azclierror.InvalidArgumentValueError, custom._assert_args, 'rg', 'vm', 'ip', "Microsoft.Network", 'cert', 'user') + def test_assert_args_no_ip_or_vm(self): - self.assertRaises(azclierror.RequiredArgumentMissingError, custom._assert_args, None, None, None, None, None) + self.assertRaises(azclierror.RequiredArgumentMissingError, custom._assert_args, None, None, None, None, None, None) def test_assert_args_vm_rg_mismatch(self): - self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, "rg", None, None, None, None) - self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, None, "vm", None, None, None) + self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, "rg", None, None, None, None, None) + self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, None, "vm", None, None, None, None) def test_assert_args_ip_with_vm_or_rg(self): - self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, None, "vm", "ip", None, None) - self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, "rg", "vm", "ip", None, None) - + self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, None, "vm", "ip", None, None, None) + self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, "rg", None, "ip", None, None, None) + self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, "rg", "vm", "ip", None, None, None) + def test_assert_args_cert_with_no_user(self): - self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, None, None, "ip", "certificate", None) + self.assertRaises(azclierror.MutuallyExclusiveArgumentError, custom._assert_args, None, None, "ip", None, "certificate", None) @mock.patch('os.path.isfile') def test_assert_args_invalid_cert_filepath(self, mock_is_file): mock_is_file.return_value = False - self.assertRaises(azclierror.FileOperationError, custom._assert_args, 'rg', 'vm', None, 'cert_path', 'username') - + self.assertRaises(azclierror.FileOperationError, custom._assert_args, 'rg', 'vm', None, 'Microsoft.HybridCompute', 'cert_path', 'username') + @mock.patch('azext_ssh.ssh_utils.create_ssh_keyfile') @mock.patch('tempfile.mkdtemp') @mock.patch('os.path.isfile') @@ -268,6 +254,16 @@ class SshCustomCommandTest(unittest.TestCase): mock_isfile.assert_called_once_with("public") + @mock.patch('os.path.isfile') + def test_check_or_create_public_private_files_no_public(self, mock_isfile): + mock_isfile.side_effect = [True, True] + public, private, delete = custom._check_or_create_public_private_files("key.pub", None, None) + self.assertEqual(public, 'key.pub') + self.assertEqual(private, 'key') + self.assertEqual(delete, False) + mock_isfile.assert_has_calls([mock.call("key.pub"), mock.call('key')]) + + @mock.patch('os.path.isfile') @mock.patch('os.path.join') def test_check_or_create_public_private_files_no_private(self, mock_join, mock_isfile): @@ -281,17 +277,20 @@ class SshCustomCommandTest(unittest.TestCase): mock.call("public"), mock.call("private") ]) + @mock.patch('builtins.open') - def test_write_cert_file(self, mock_open): + @mock.patch('oschmod.set_mode') + def test_write_cert_file(self, mock_mode, mock_open): mock_file = mock.Mock() mock_open.return_value.__enter__.return_value = mock_file custom._write_cert_file("cert", "publickey-aadcert.pub") + mock_mode.assert_called_once_with("publickey-aadcert.pub", 0o644) mock_open.assert_called_once_with("publickey-aadcert.pub", 'w', encoding='utf-8') mock_file.write.assert_called_once_with("ssh-rsa-cert-v01@openssh.com cert") - + @mock.patch('azext_ssh.rsa_parser.RSAParser') @mock.patch('os.path.isfile') @mock.patch('builtins.open') @@ -325,6 +324,207 @@ class SshCustomCommandTest(unittest.TestCase): mock_parser_obj.parse.side_effect = ValueError self.assertRaises(azclierror.FileOperationError, custom._get_modulus_exponent, 'file') + + @mock.patch('azext_ssh.ssh_utils.get_ssh_cert_principals') + @mock.patch('os.path.join') + @mock.patch('azext_ssh.custom._check_or_create_public_private_files') + @mock.patch('azext_ssh.ip_utils.get_ssh_ip') + @mock.patch('azext_ssh.custom._get_modulus_exponent') + @mock.patch('azure.cli.core._profile.Profile') + @mock.patch('azext_ssh.custom._write_cert_file') + def test_do_ssh_op_aad_user_compute(self, mock_write_cert, mock_ssh_creds, mock_get_mod_exp, mock_ip, + mock_check_files, mock_join, mock_principal): + cmd = mock.Mock() + cmd.cli_ctx = mock.Mock() + cmd.cli_ctx.cloud = mock.Mock() + cmd.cli_ctx.cloud.name = "azurecloud" -if __name__ == '__main__': - unittest.main() + op_info = ssh_info.SSHSession(None, None, "1.2.3.4", None, None, False, None, None, None, None, None, None, "Microsoft.Compute", None, None) + op_info.public_key_file = "publicfile" + op_info.private_key_file = "privatefile" + op_info.ssh_client_folder = "/client/folder" + + mock_op = mock.Mock() + mock_check_files.return_value = "public", "private", False + mock_principal.return_value = ["username"] + mock_get_mod_exp.return_value = "modulus", "exponent" + profile = mock_ssh_creds.return_value + profile._adal_cache = True + profile.get_msal_token.return_value = "username", "certificate" + mock_join.return_value = "public-aadcert.pub" + + custom._do_ssh_op(cmd, op_info, mock_op) + + mock_check_files.assert_called_once_with("publicfile", "privatefile", None, "/client/folder") + mock_ip.assert_not_called() + mock_get_mod_exp.assert_called_once_with("public") + mock_write_cert.assert_called_once_with("certificate", "public-aadcert.pub") + mock_op.assert_called_once_with(op_info, False, True) + + @mock.patch('azext_ssh.custom._check_or_create_public_private_files') + @mock.patch('azext_ssh.ip_utils.get_ssh_ip') + def test_do_ssh_op_local_user_compute(self, mock_ip, mock_check_files): + cmd = mock.Mock() + mock_op = mock.Mock() + mock_ip.return_value = "1.2.3.4" + + op_info = ssh_info.ConfigSession("config", "rg", "vm", None, None, None, False, False, "username", None, None, "Microsoft.Compute", None, None, None) + op_info.public_key_file = "publicfile" + op_info.private_key_file = "privatefile" + op_info.cert_file = "cert" + op_info.ssh_client_folder = "/client/folder" + + custom._do_ssh_op(cmd, op_info, mock_op) + + mock_check_files.assert_not_called() + mock_ip.assert_called_once_with(cmd, "rg", "vm", False) + mock_op.assert_called_once_with(op_info, False, False) + + @mock.patch('azext_ssh.custom._check_or_create_public_private_files') + @mock.patch('azext_ssh.ip_utils.get_ssh_ip') + def test_do_ssh_op_no_public_ip(self, mock_ip, mock_check_files): + cmd = mock.Mock() + mock_op = mock.Mock() + mock_ip.return_value = None + + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, None, None, None, None, None, None, "Microsoft.Compute", None, None) + + self.assertRaises( + azclierror.ResourceNotFoundError, custom._do_ssh_op, cmd, op_info, mock_op) + + mock_check_files.assert_not_called() + mock_ip.assert_called_once_with(cmd, "rg", "vm", False) + mock_op.assert_not_called() + + @mock.patch('azext_ssh.connectivity_utils.get_client_side_proxy') + @mock.patch('azext_ssh.connectivity_utils.get_relay_information') + @mock.patch('azext_ssh.ssh_utils.start_ssh_connection') + @mock.patch('azext_ssh.custom._check_or_create_public_private_files') + @mock.patch('azext_ssh.custom._get_and_write_certificate') + def test_do_ssh_op_arc_local_user(self, mock_get_cert, mock_check_keys, mock_start_ssh, mock_get_relay_info, mock_get_proxy): + cmd = mock.Mock() + mock_op = mock.Mock() + + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, "user", None, "port", None, [], False, "Microsoft.HybridCompute", None, None) + op_info.private_key_file = "priv" + op_info.cert_file = "cert" + op_info.ssh_client_folder = "client" + op_info.ssh_proxy_folder = "proxy" + + custom._do_ssh_op(cmd, op_info, mock_op) + + mock_get_proxy.assert_called_once_with('proxy') + mock_get_relay_info.assert_called_once_with(cmd, 'rg', 'vm', None) + mock_op.assert_called_once_with(op_info, False, False) + mock_get_cert.assert_not_called() + mock_check_keys.assert_not_called() + + @mock.patch('azext_ssh.connectivity_utils.get_client_side_proxy') + @mock.patch('azext_ssh.custom.connectivity_utils.get_relay_information') + @mock.patch('azext_ssh.ssh_utils.get_ssh_cert_principals') + @mock.patch('os.path.join') + @mock.patch('azext_ssh.custom._check_or_create_public_private_files') + @mock.patch('azext_ssh.custom._get_modulus_exponent') + @mock.patch('azure.cli.core._profile.Profile') + @mock.patch('azext_ssh.custom._write_cert_file') + @mock.patch('azext_ssh.ssh_utils.start_ssh_connection') + @mock.patch('azext_ssh.ssh_utils.get_certificate_lifetime') + def test_do_ssh_arc_op_aad_user(self, mock_cert_exp, mock_start_ssh, mock_write_cert, mock_ssh_creds, mock_get_mod_exp, mock_check_files, + mock_join, mock_principal, mock_get_relay_info, mock_get_proxy): + + mock_get_proxy.return_value = '/path/to/proxy' + mock_get_relay_info.return_value = 'relay' + cmd = mock.Mock() + cmd.cli_ctx = mock.Mock() + cmd.cli_ctx.cloud = mock.Mock() + cmd.cli_ctx.cloud.name = "azurecloud" + mock_check_files.return_value = "public", "private", False + mock_principal.return_value = ["username"] + mock_get_mod_exp.return_value = "modulus", "exponent" + profile = mock_ssh_creds.return_value + profile._adal_cache = True + profile.get_msal_token.return_value = "username", "certificate" + mock_join.return_value = "public-aadcert.pub" + from datetime import timedelta + mock_cert_exp.return_value = timedelta(seconds=3600) + + mock_op = mock.Mock() + + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, None, None, "port", None, [], False, "Microsoft.HybridCompute", None, None) + op_info.public_key_file = "publicfile" + op_info.private_key_file = "privatefile" + op_info.ssh_client_folder = "client" + op_info.ssh_proxy_folder = "proxy" + + custom._do_ssh_op(cmd, op_info, mock_op) + + self.assertEqual(op_info.local_user, "username") + self.assertEqual(op_info.cert_file, "public-aadcert.pub") + + mock_check_files.assert_called_once_with("publicfile", "privatefile", None, "client") + mock_get_mod_exp.assert_called_once_with("public") + mock_write_cert.assert_called_once_with("certificate", "public-aadcert.pub") + mock_get_proxy.assert_called_once_with('proxy') + mock_get_relay_info.assert_called_once_with(cmd, 'rg', 'vm', 3600) + mock_op.assert_called_once_with(op_info, False, True) + + def test_decide_resource_type_ip(self): + cmd = mock.Mock() + op_info = ssh_info.SSHSession(None, None, "ip", None, None, False, None, None, None, None, [], False, None, None, None) + self.assertEqual(custom._decide_resource_type(cmd, op_info), "Microsoft.Compute") + + @mock.patch('azext_ssh.custom._check_if_arc_server') + def test_decide_resource_type_resourcetype_arc(self, mock_is_arc): + cmd = mock.Mock() + mock_is_arc.return_value = None, None, True + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, None, None, None, None, [], False, "Microsoft.HybridCompute", None, None) + self.assertEqual(custom._decide_resource_type(cmd, op_info), "Microsoft.HybridCompute") + + @mock.patch('azext_ssh.custom._check_if_azure_vm') + def test_decide_resource_type_resourcetype_arc(self, mock_is_vm): + cmd = mock.Mock() + mock_is_vm.return_value = None, None, True + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, None, None, None, None, [], False, "Microsoft.Compute", None, None) + self.assertEqual(custom._decide_resource_type(cmd, op_info), "Microsoft.Compute") + + @mock.patch('azext_ssh.custom._check_if_azure_vm') + @mock.patch('azext_ssh.custom._check_if_arc_server') + def test_decide_resource_type_rg_vm_both(self, mock_is_arc, mock_is_vm): + cmd = mock.Mock() + mock_is_vm.return_value = None, None, True + mock_is_arc.return_value = None, None, True + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, None, None, None, None, [], False, None, None, None) + self.assertRaises( + azclierror.BadRequestError, custom._decide_resource_type, cmd, op_info) + + @mock.patch('azext_ssh.custom._check_if_azure_vm') + @mock.patch('azext_ssh.custom._check_if_arc_server') + def test_decide_resource_type_rg_vm_neither(self, mock_is_arc, mock_is_vm): + cmd = mock.Mock() + mock_is_vm.return_value = None, ResourceNotFoundError(), False + mock_is_arc.return_value = None, ResourceNotFoundError(), False + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, None, None, None, None, [], False, None, None, None) + self.assertRaises( + azclierror.ResourceNotFoundError, custom._decide_resource_type, cmd, op_info) + + @mock.patch('azext_ssh.custom._check_if_azure_vm') + @mock.patch('azext_ssh.custom._check_if_arc_server') + def test_decide_resource_type_rg_vm_arc(self, mock_is_arc, mock_is_vm): + cmd = mock.Mock() + mock_is_vm.return_value = None, ResourceNotFoundError(), False + mock_is_arc.return_value = None, None, True + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, None, None, None, None, [], False, None, None, None) + self.assertEqual(custom._decide_resource_type(cmd, op_info), "Microsoft.HybridCompute") + + @mock.patch('azext_ssh.custom._check_if_azure_vm') + @mock.patch('azext_ssh.custom._check_if_arc_server') + def test_decide_resource_type_rg_vm_arc(self, mock_is_arc, mock_is_vm): + cmd = mock.Mock() + mock_is_vm.return_value = None, None, True + mock_is_arc.return_value = None, ResourceNotFoundError(), False + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, None, None, None, None, [], False, None, None, None) + self.assertEqual(custom._decide_resource_type(cmd, op_info), "Microsoft.Compute") + + + if __name__ == '__main__': + unittest.main() diff --git a/src/ssh/azext_ssh/tests/latest/test_ssh_info.py b/src/ssh/azext_ssh/tests/latest/test_ssh_info.py index 1157ed2c1e..40a231d508 100644 --- a/src/ssh/azext_ssh/tests/latest/test_ssh_info.py +++ b/src/ssh/azext_ssh/tests/latest/test_ssh_info.py @@ -12,14 +12,16 @@ from azext_ssh import ssh_info class SSHInfoTest(unittest.TestCase): @mock.patch('os.path.abspath') def test_ssh_session(self, mock_abspath): - mock_abspath.side_effect = ["pub_path", "priv_path", "cert_path", "client_path"] + mock_abspath.side_effect = ["pub_path", "priv_path", "cert_path", "client_path", "proxy_path", "cred_path"] expected_abspath_calls = [ mock.call("pub"), mock.call("priv"), mock.call("cert"), - mock.call("client/folder") + mock.call("client/folder"), + mock.call("proxy/path"), + mock.call("cred/path") ] - session = ssh_info.SSHSession("rg", "vm", "ip", "pub", "priv", False, "user", "cert", "port", "client/folder", ['-v', '-E', 'path']) + session = ssh_info.SSHSession("rg", "vm", "ip", "pub", "priv", False, "user", "cert", "port", "client/folder", ['-v', '-E', 'path'], False, 'arc', 'proxy/path', 'cred/path') mock_abspath.assert_has_calls(expected_abspath_calls) self.assertEqual(session.resource_group_name, "rg") self.assertEqual(session.vm_name, "vm") @@ -32,28 +34,46 @@ class SSHInfoTest(unittest.TestCase): self.assertEqual(session.ssh_args, ['-v', '-E', 'path']) self.assertEqual(session.cert_file, "cert_path") self.assertEqual(session.ssh_client_folder, "client_path") - + self.assertEqual(session.ssh_proxy_folder, "proxy_path") + self.assertEqual(session.credentials_folder, "cred_path") + self.assertEqual(session.relay_info, None) + self.assertEqual(session.resource_type, "arc") + self.assertEqual(session.proxy_path, None) + self.assertEqual(session.delete_credentials, False) + + def test_ssh_session_get_host(self): - session = ssh_info.SSHSession(None, None, "ip", None, None, False, "user", None, None, None, []) + session = ssh_info.SSHSession(None, None, "ip", None, None, False, "user", None, None, None, [], False, "Microsoft.Compute", None, None) self.assertEqual("user@ip", session.get_host()) - + session = ssh_info.SSHSession("rg", "vm", None, None, None, False, "user", None, None, None, [], False, "Microsoft.HybridCompute", None, None) + self.assertEqual("user@vm", session.get_host()) + @mock.patch('os.path.abspath') - def test_ssh_session_build_args(self, mock_abspath): + def test_ssh_session_build_args_compute(self, mock_abspath): mock_abspath.side_effect = ["pub_path", "priv_path", "cert_path", "client_path"] - session = ssh_info.SSHSession("rg", "vm", "ip", "pub", "priv", False, "user", "cert", "port", "client/folder", []) + session = ssh_info.SSHSession("rg", "vm", "ip", "pub", "priv", False, "user", "cert", "port", "client/folder", [], None, "Microsoft.Compute", None, None) self.assertEqual(["-i", "priv_path", "-o", "CertificateFile=\"cert_path\"", "-p", "port"], session.build_args()) - + + @mock.patch('os.path.abspath') + def test_ssh_session_build_args_hyvridcompute(self, mock_abspath): + mock_abspath.side_effect = ["pub_path", "priv_path", "cert_path", "client_path"] + session = ssh_info.SSHSession("rg", "vm", "ip", "pub", "priv", False, "user", "cert", "port", "client/folder", [], None, "Microsoft.HybridCompute", None, None) + session.proxy_path = "proxy_path" + self.assertEqual(["-o", "ProxyCommand=\"proxy_path\" -p port", "-i", "priv_path", "-o", "CertificateFile=\"cert_path\""], session.build_args()) + @mock.patch('os.path.abspath') def test_config_session(self, mock_abspath): - mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path"] + mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path", "proxy_path", "cred_path"] expected_abspath_calls = [ mock.call("config"), mock.call("pub"), mock.call("priv"), mock.call("cert"), - mock.call("client/folder") + mock.call("client"), + mock.call("proxy"), + mock.call("cred") ] - session = ssh_info.ConfigSession("config", "rg", "vm", "ip", "pub", "priv", False, False, "user", "cert", "port", "client/folder") + session = ssh_info.ConfigSession("config", "rg", "vm", "ip", "pub", "priv", False, False, "user", "cert", "port", "arc", "cred", "proxy", "client") mock_abspath.assert_has_calls(expected_abspath_calls) self.assertEqual(session.config_path, "config_path") self.assertEqual(session.resource_group_name, "rg") @@ -67,10 +87,16 @@ class SSHInfoTest(unittest.TestCase): self.assertEqual(session.port, "port") self.assertEqual(session.cert_file, "cert_path") self.assertEqual(session.ssh_client_folder, "client_path") - + self.assertEqual(session.resource_type, "arc") + self.assertEqual(session.proxy_path, None) + self.assertEqual(session.relay_info, None) + self.assertEqual(session.relay_info_path, None) + self.assertEqual(session.ssh_proxy_folder, "proxy_path") + self.assertEqual(session.credentials_folder, "cred_path") + @mock.patch('os.path.abspath') def test_get_rg_and_vm_entry(self, mock_abspath): - expected_lines = [ + expected_lines_aad = [ "Host rg-vm", "\tUser user", "\tHostName ip", @@ -78,29 +104,73 @@ class SSHInfoTest(unittest.TestCase): "\tIdentityFile \"priv_path\"", "\tPort port", ] + expected_lines_local_user = [ + "Host rg-vm-user", + "\tUser user", + "\tHostName ip", + "\tCertificateFile \"cert_path\"", + "\tIdentityFile \"priv_path\"", + "\tPort port", + ] + mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path", "proxy_path", "cred_path"] + session = ssh_info.ConfigSession("config", "rg", "vm", "ip", "pub", "priv", False, False, "user", "cert", "port", "compute", "cred", "proxy", "client") - mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path"] - session = ssh_info.ConfigSession("config", "rg", "vm", "ip", "pub", "priv", False, False, "user", "cert", "port", "client/folder") + self.assertEqual(session._get_rg_and_vm_entry(True), expected_lines_aad) + self.assertEqual(session._get_rg_and_vm_entry(False), expected_lines_local_user) - self.assertEqual(session._get_rg_and_vm_entry(), expected_lines) @mock.patch('os.path.abspath') def test_get_ip_entry(self, mock_abspath): - expected_lines = [ + expected_lines_aad = [ "Host ip", "\tUser user", "\tCertificateFile \"cert_path\"", "\tIdentityFile \"priv_path\"" ] + expected_lines_local_user = [ + "Host ip-user", + "\tHostName ip", + "\tUser user", + "\tCertificateFile \"cert_path\"", + "\tIdentityFile \"priv_path\"" + ] - mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path"] - session = ssh_info.ConfigSession("config", "rg", "vm", "ip", "pub", "priv", False, False, "user", "cert", None, "client/folder") + mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path", "cred_folder"] + session = ssh_info.ConfigSession("config", "rg", "vm", "ip", "pub", "priv", False, False, "user", "cert", None, "compute", "cred", None, "client/folder") + + self.assertEqual(session._get_ip_entry(True), expected_lines_aad) + self.assertEqual(session._get_ip_entry(False), expected_lines_local_user) - self.assertEqual(session._get_ip_entry(), expected_lines) - @mock.patch('os.path.abspath') - def test_get_config_text(self, mock_abspath): - expected_lines = [ + def test_get_arc_entry(self, mock_abspath): + expected_lines_aad = [ + "Host rg-vm", + "\tHostName vm", + "\tUser user", + "\tCertificateFile \"cert_path\"", + "\tIdentityFile \"priv_path\"", + "\tProxyCommand \"proxy_path\" -r \"relay_info_path\" -p port" + ] + + expected_lines_local_user = [ + "Host rg-vm-user", + "\tHostName vm", + "\tUser user", + "\tCertificateFile \"cert_path\"", + "\tIdentityFile \"priv_path\"", + "\tProxyCommand \"proxy_path\" -r \"relay_info_path\" -p port" + ] + + mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path", "cred_folder"] + session = ssh_info.ConfigSession("config", "rg", "vm", None, "pub", "priv", False, False, "user", "cert", "port", "arc", "cred", None, "client/folder") + session.proxy_path = "proxy_path" + session.relay_info_path = "relay_info_path" + self.assertEqual(session._get_arc_entry(True), expected_lines_aad) + self.assertEqual(session._get_arc_entry(False), expected_lines_local_user) + + @mock.patch('os.path.abspath') + def test_get_config_text_compute(self, mock_abspath): + expected_lines_aad = [ "", "Host rg-vm", "\tUser user", @@ -115,12 +185,57 @@ class SSHInfoTest(unittest.TestCase): "\tPort port", ] - mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path"] - session = ssh_info.ConfigSession("config", "rg", "vm", "ip", "pub", "priv", False, False, "user", "cert", "port", "client/folder") + expected_lines_local_user = [ + "", + "Host rg-vm-user", + "\tUser user", + "\tHostName ip", + "\tCertificateFile \"cert_path\"", + "\tIdentityFile \"priv_path\"", + "\tPort port", + "Host ip-user", + "\tHostName ip", + "\tUser user", + "\tCertificateFile \"cert_path\"", + "\tIdentityFile \"priv_path\"", + "\tPort port", + ] - self.assertEqual(session.get_config_text(), expected_lines) + mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path", "cred_path"] + session = ssh_info.ConfigSession("config", "rg", "vm", "ip", "pub", "priv", False, False, "user", "cert", "port", "compute", "cred", None, "client/folder") + self.assertEqual(session.get_config_text(True), expected_lines_aad) + self.assertEqual(session.get_config_text(False), expected_lines_local_user) + @mock.patch('os.path.abspath') + @mock.patch.object(ssh_info.ConfigSession, '_create_relay_info_file') + def test_get_config_text_arc(self, create_file, mock_abspath): + create_file.return_value = "relay_info_path" + expected_lines_aad = [ + "", + "Host rg-vm", + "\tHostName vm", + "\tUser user", + "\tCertificateFile \"cert_path\"", + "\tIdentityFile \"priv_path\"", + "\tProxyCommand \"proxy_path\" -r \"relay_info_path\"" + ] + + expected_lines_local_user = [ + "", + "Host rg-vm-user", + "\tHostName vm", + "\tUser user", + "\tCertificateFile \"cert_path\"", + "\tIdentityFile \"priv_path\"", + "\tProxyCommand \"proxy_path\" -r \"relay_info_path\"" + ] + + mock_abspath.side_effect = ["config_path", "pub_path", "priv_path", "cert_path", "client_path", "cred_path"] + session = ssh_info.ConfigSession("config", "rg", "vm", None, "pub", "priv", False, False, "user", "cert", None, "Microsoft.HybridCompute", "cred", None, "client/folder") + session.proxy_path = "proxy_path" + self.assertEqual(session.get_config_text(True), expected_lines_aad) + self.assertEqual(session.get_config_text(False), expected_lines_local_user) if __name__ == '__main__': unittest.main() diff --git a/src/ssh/azext_ssh/tests/latest/test_ssh_utils.py b/src/ssh/azext_ssh/tests/latest/test_ssh_utils.py index c1ef7f2f13..4d004a0b69 100644 --- a/src/ssh/azext_ssh/tests/latest/test_ssh_utils.py +++ b/src/ssh/azext_ssh/tests/latest/test_ssh_utils.py @@ -7,252 +7,155 @@ from azure.cli.core import azclierror from unittest import mock import unittest import platform +import os from azext_ssh import ssh_utils +from azext_ssh import ssh_info -class SSHUtilsTests(unittest.TestCase): - @mock.patch('os.path.join') +class SSHUtilsTests(unittest.TestCase): + @mock.patch.object(ssh_utils, '_start_cleanup') + @mock.patch.object(ssh_utils, '_terminate_cleanup') @mock.patch.object(ssh_utils, '_get_ssh_client_path') - @mock.patch('subprocess.call') - @mock.patch('azext_ssh.ssh_info.SSHSession.build_args') - @mock.patch('azext_ssh.ssh_info.SSHSession.get_host') - @mock.patch('os.path.dirname') - @mock.patch('multiprocessing.Process.start') - @mock.patch('azext_ssh.ssh_utils._print_error_messages_from_ssh_log') - def test_start_ssh_connection(self, mock_print_error, mock_start, mock_dirname, mock_host, mock_build, mock_call, mock_path, mock_join): - mock_path.return_value = "ssh" - mock_join.return_value = "/log/file/path" - mock_build.return_value = ['-i', 'file', '-o', 'option'] - mock_host.return_value = "user@ip" - mock_dirname.return_value = "dirname" + @mock.patch('subprocess.run') + @mock.patch('os.environ.copy') + def test_start_ssh_connection_compute(self, mock_copy_env, mock_call, mock_path, mock_terminatecleanup, mock_startcleanup): + + op_info = ssh_info.SSHSession("rg", "vm", "ip", None, None, False, "user", None, "port", None, ['arg1', 'arg2', 'arg3'], False, "Microsof.Compute", None, None) + op_info.public_key_file = "pub" + op_info.private_key_file = "priv" + op_info.cert_file = "cert" + op_info.ssh_client_folder = "client" + mock_call.return_value = 0 - - expected_command = ["ssh", "user@ip", "-i", "file", "-o", "option", "-E", "/log/file/path", "-v"] - - op_info = mock.Mock() - op_info.ip = "ip" - op_info.port = "port" - op_info.local_user = "user" - op_info.private_key_file = "private" - op_info.public_key_file = "public" - op_info.cert_file = "cert" - op_info.ssh_args = None - op_info.ssh_client_folder = "client/folder" - op_info.build_args = mock_build - op_info.get_host = mock_host + mock_path.return_value = 'ssh' + mock_copy_env.return_value = {'var1':'value1', 'var2':'value2', 'var3':'value3'} + mock_startcleanup.return_value = 'log', ['arg1', 'arg2', 'arg3', '-E', 'log', '-v'], 'cleanup process' + expected_command = ['ssh', 'user@ip', '-i', 'priv', '-o', 'CertificateFile=\"cert\"', '-p', 'port', 'arg1', 'arg2', 'arg3', '-E', 'log', '-v'] + expected_env = {'var1':'value1', 'var2':'value2', 'var3':'value3'} ssh_utils.start_ssh_connection(op_info, True, True) - mock_start.assert_called_once() - mock_print_error.assert_called_once_with("/log/file/path", 0) - mock_path.assert_called_once_with('ssh', 'client/folder') - mock_call.assert_called_once_with(expected_command, shell=platform.system() == 'Windows') + + mock_path.assert_called_once_with('ssh', 'client') + mock_startcleanup.assert_called_with('cert', 'priv', 'pub', False, True, True, ['arg1', 'arg2', 'arg3']) + mock_call.assert_called_once_with(expected_command, env=expected_env, stderr=mock.ANY, text=True) + mock_terminatecleanup.assert_called_once_with(True, True, False, 'cleanup process', 'cert', 'priv', 'pub', 'log', 0) + @mock.patch.object(ssh_utils, '_terminate_cleanup') + @mock.patch('os.environ.copy') @mock.patch.object(ssh_utils, '_get_ssh_client_path') - @mock.patch('subprocess.call') - @mock.patch('azext_ssh.ssh_info.SSHSession.build_args') - @mock.patch('azext_ssh.ssh_info.SSHSession.get_host') - def test_start_ssh_connection_with_args(self, mock_host, mock_build, mock_call, mock_path): - mock_path.return_value = "ssh" - mock_host.return_value = "user@ip" - mock_build.return_value = ["-i", "private", "-o", "CertificateFile=cert", "-p", "2222"] - - expected_command = ["ssh", "user@ip", "-i", "private", "-o", "CertificateFile=cert", "-p", "2222", "--thing", "-vv"] - - op_info = mock.Mock() - op_info.ip = "ip" - op_info.port = "2222" - op_info.local_user = "user" - op_info.private_key_file = "private" - op_info.public_key_file = "public" + @mock.patch('subprocess.run') + @mock.patch('azext_ssh.custom.connectivity_utils.format_relay_info_string') + def test_start_ssh_connection_arc(self, mock_relay_str, mock_call, mock_path, mock_copy_env, mock_terminatecleanup): + + op_info = ssh_info.SSHSession("rg", "vm", None, None, None, False, "user", None, "port", None, ['arg1'], False, "Microsoft.HybridCompute", None, None) + op_info.public_key_file = "pub" + op_info.private_key_file = "priv" op_info.cert_file = "cert" - op_info.ssh_args = ["--thing", "-vv"] - op_info.ssh_client_folder = "client/folder" - op_info.build_args = mock_build - op_info.get_host = mock_host + op_info.ssh_client_folder = "client" + op_info.proxy_path = "proxy" + op_info.relay_info = "relay" + + mock_call.return_value = 0 + mock_relay_str.return_value = 'relay_string' + mock_copy_env.return_value = {'var1':'value1', 'var2':'value2', 'var3':'value3'} + mock_path.return_value = 'ssh' + expected_command = ['ssh', 'user@vm', '-o', 'ProxyCommand=\"proxy\" -p port', '-i', 'priv', '-o', 'CertificateFile=\"cert\"', 'arg1'] + expected_env = {'var1':'value1', 'var2':'value2', 'var3':'value3', 'SSHPROXY_RELAY_INFO':'relay_string'} - ssh_utils.start_ssh_connection(op_info, True, True) + ssh_utils.start_ssh_connection(op_info, False, False) - mock_path.assert_called_once_with('ssh', 'client/folder') - mock_call.assert_called_once_with(expected_command, shell=platform.system() == 'Windows') - - @mock.patch.object(ssh_utils, 'get_certificate_start_and_end_times') - @mock.patch('azext_ssh.ssh_info.ConfigSession.get_config_text') - def test_write_ssh_config_ip_and_vm(self, mock_get_text, mock_validity): + mock_relay_str.assert_called_once_with('relay') + mock_path.assert_called_once_with('ssh', 'client') + mock_call.assert_called_once_with(expected_command, env=expected_env, stderr=mock.ANY, text=True) + mock_terminatecleanup.assert_called_once_with(False, False, False, None, 'cert', 'priv', 'pub', None, 0) + + + @mock.patch.object(ssh_utils, '_issue_config_cleanup_warning') + @mock.patch('os.path.abspath') + def test_write_ssh_config_ip_and_vm_compute_append(self, mock_abspath, mock_warning): + op_info = ssh_info.ConfigSession("config", "rg", "vm", "ip", None, None, False, False, "user", None, "port", "Microsoft.Compute", None, None, "client") + op_info.config_path = "config" + op_info.ssh_client_folder = "client" + op_info.private_key_file = "priv" + op_info.public_key_file = "pub" + op_info.cert_file = "cert" expected_lines = [ "", "Host rg-vm", - "\tUser username", - "\tHostName 1.2.3.4", - "\tCertificateFile cert", - "\tIdentityFile privatekey", + "\tUser user", + "\tHostName ip", + "\tCertificateFile \"cert\"", + "\tIdentityFile \"priv\"", "\tPort port", - "Host 1.2.3.4", - "\tUser username", - "\tCertificateFile cert", - "\tIdentityFile privatekey", + "Host ip", + "\tUser user", + "\tCertificateFile \"cert\"", + "\tIdentityFile \"priv\"", "\tPort port" ] - - mock_validity.return_value = None - mock_get_text.return_value = expected_lines - - op_info = mock.Mock() - op_info.config_path = "path/to/file" - op_info.resource_group_name = "rg" - op_info.vm_name = "vm" - op_info.overwrite = True - op_info.port = "port" - op_info.ip = "1.2.3.4" - op_info.local_user = "username" - op_info.cert_file = "cert" - op_info.private_key_file = "privatekey" - op_info.ssh_client_folder = "client/folder" - op_info.get_config_text = mock_get_text - - with mock.patch('builtins.open') as mock_open: - mock_file = mock.Mock() - mock_open.return_value.__enter__.return_value = mock_file - ssh_utils.write_ssh_config(op_info, True, False) - mock_validity.assert_called_once_with("cert", "client/folder") - mock_open.assert_called_once_with("path/to/file", "w", encoding='utf-8') - mock_file.write.assert_called_once_with('\n'.join(expected_lines)) - - - @mock.patch.object(ssh_utils, 'get_certificate_start_and_end_times') - @mock.patch('azext_ssh.ssh_info.ConfigSession.get_config_text') - def test_write_ssh_config_append(self, mock_get_text, mock_validity): - expected_lines = [ - "", - "Host rg-vm", - "\tUser username", - "\tHostName 1.2.3.4", - "\tCertificateFile cert", - "\tIdentityFile privatekey", - "Host 1.2.3.4", - "\tUser username", - "\tCertificateFile cert", - "\tIdentityFile privatekey" - ] - - mock_validity.return_value = None - mock_get_text.return_value = expected_lines - - op_info = mock.Mock() - op_info.config_path = "path/to/file" - op_info.resource_group_name = "rg" - op_info.vm_name = "vm" - op_info.overwrite = False - op_info.ip = "1.2.3.4" - op_info.local_user = "username" - op_info.cert_file = "cert" - op_info.private_key_file = "privatekey" - op_info.ssh_client_folder = "client/folder" - op_info.get_config_text = mock_get_text with mock.patch('builtins.open') as mock_open: mock_file = mock.Mock() mock_open.return_value.__enter__.return_value = mock_file ssh_utils.write_ssh_config( - op_info, True, True - ) + op_info, True, True) - mock_validity.assert_called_once_with("cert", "client/folder") + mock_warning.assert_called_once_with(True, True, False, "cert", None, "client") + mock_open.assert_called_once_with("config", 'a', encoding='utf-8') + mock_file.write.assert_called_once_with('\n'.join(expected_lines)) - mock_open.assert_called_once_with("path/to/file", "a", encoding='utf-8') + @mock.patch.object(ssh_utils, '_issue_config_cleanup_warning') + @mock.patch('os.path.abspath') + @mock.patch.object(ssh_info.ConfigSession, '_create_relay_info_file') + def test_write_ssh_config_arc_overwrite(self, mock_create_file, mock_abspath, mock_warning): + op_info = ssh_info.ConfigSession("config", "rg", "vm", None, None, None, True, False, "user", None, "port", "Microsoft.HybridCompute", None, None, "client") + op_info.config_path = "config" + op_info.ssh_client_folder = "client" + op_info.private_key_file = "priv" + op_info.public_key_file = "pub" + op_info.cert_file = "cert" + op_info.proxy_path = "proxy" + mock_create_file.return_value = "relay" + expected_lines = [ + "", + "Host rg-vm", + "\tHostName vm", + "\tUser user", + "\tCertificateFile \"cert\"", + "\tIdentityFile \"priv\"", + "\tProxyCommand \"proxy\" -r \"relay\" -p port" + ] + + with mock.patch('builtins.open') as mock_open: + mock_file = mock.Mock() + mock_open.return_value.__enter__.return_value = mock_file + ssh_utils.write_ssh_config( + op_info, True, True) + + mock_warning.assert_called_once_with(True, True, True, "cert", "relay", "client") + mock_open.assert_called_once_with("config", 'w', encoding='utf-8') mock_file.write.assert_called_once_with('\n'.join(expected_lines)) - @mock.patch('os.path.join') @mock.patch('platform.system') @mock.patch('os.path.isfile') - def test_get_ssh_client_path_with_client_folder_non_windows(self, mock_isfile, mock_system, mock_join): - mock_join.return_value = "ssh_path" - mock_system.return_value = "Linux" - mock_isfile.return_value = True - actual_path = ssh_utils._get_ssh_client_path(ssh_client_folder='/client/folder') - self.assertEqual(actual_path, "ssh_path") - mock_join.assert_called_once_with('/client/folder', 'ssh') - mock_isfile.assert_called_once_with("ssh_path") - - @mock.patch('os.path.join') - @mock.patch('platform.system') - @mock.patch('os.path.isfile') - def test_get_ssh_client_path_with_client_folder_windows(self, mock_isfile, mock_system, mock_join): - mock_join.return_value = "ssh_keygen_path" - mock_system.return_value = "Windows" - mock_isfile.return_value = True - actual_path = ssh_utils._get_ssh_client_path(ssh_command='ssh-keygen', ssh_client_folder='/client/folder') - self.assertEqual(actual_path, "ssh_keygen_path.exe") - mock_join.assert_called_once_with('/client/folder', 'ssh-keygen') - mock_isfile.assert_called_once_with("ssh_keygen_path.exe") - - @mock.patch('os.path.join') - @mock.patch('platform.system') - @mock.patch('os.path.isfile') - def test_get_ssh_client_path_with_client_folder_no_file(self, mock_isfile, mock_system, mock_join): + def test_get_ssh_client_path_not_found(self, mock_isfile, mock_system, mock_join): mock_join.return_value = "ssh_path" mock_system.return_value = "Mac" mock_isfile.return_value = False - actual_path = ssh_utils._get_ssh_client_path(ssh_client_folder='/client/folder') - self.assertEqual(actual_path, "ssh") - mock_join.assert_called_once_with('/client/folder', 'ssh') - mock_isfile.assert_called_once_with("ssh_path") - - @mock.patch('platform.system') - def test_get_ssh_client_preinstalled_non_windows(self, mock_system): - mock_system.return_value = "Mac" - actual_path = ssh_utils._get_ssh_client_path() - self.assertEqual('ssh', actual_path) - mock_system.assert_called_once_with() - - def test_get_ssh_client_preinstalled_windows_32bit(self): - self._test_get_ssh_client_path_preinstalled_windows('32bit', 'x86', 'System32') - - def test_get_ssh_client_preinstalled_windows_64bitOS_32bitPlatform(self): - self._test_get_ssh_client_path_preinstalled_windows('32bit', 'x64', 'SysNative') + path = ssh_utils._get_ssh_client_path("ssh", "folder") + self.assertEqual(path, "ssh") - def test_get_ssh_client_preinstalled_windows_64bitOS_64bitPlatform(self): - self._test_get_ssh_client_path_preinstalled_windows('64bit', 'x64', 'System32') - - @mock.patch('platform.system') - @mock.patch('platform.architecture') - @mock.patch('platform.machine') @mock.patch('os.path.join') - @mock.patch('os.environ') - @mock.patch('os.path.isfile') - def _test_get_ssh_client_path_preinstalled_windows(self, platform_arch, os_arch, expected_sysfolder, mock_isfile, mock_environ, mock_join, mock_machine, mock_arch, mock_system): - mock_system.return_value = "Windows" - mock_arch.return_value = (platform_arch, "foo", "bar") - mock_machine.return_value = os_arch - mock_environ.__getitem__.return_value = "rootpath" - mock_join.side_effect = ["system32path", "sshfilepath"] - mock_isfile.return_value = True - - expected_join_calls = [ - mock.call("rootpath", expected_sysfolder), - mock.call("system32path", "openSSH", "ssh.exe") - ] - - actual_path = ssh_utils._get_ssh_client_path() - - self.assertEqual("sshfilepath", actual_path) - mock_system.assert_called_once_with() - mock_arch.assert_called_once_with() - mock_environ.__getitem__.assert_called_once_with("SystemRoot") - mock_join.assert_has_calls(expected_join_calls) - mock_isfile.assert_called_once_with("sshfilepath") - - @mock.patch('platform.system') - @mock.patch('platform.architecture') - @mock.patch('platform.machine') - @mock.patch('os.environ') @mock.patch('os.path.isfile') - def test_get_ssh_path_windows_ssh_preinstalled_not_found(self, mock_isfile, mock_environ, mock_machine, mock_arch, mock_sys): - mock_sys.return_value = "Windows" - mock_arch.return_value = ("32bit", "foo", "bar") - mock_machine.return_value = "x64" - mock_environ.__getitem__.return_value = "rootpath" - mock_isfile.return_value = False - - self.assertRaises(azclierror.UnclassifiedUserFault, ssh_utils._get_ssh_client_path) + def test_get_ssh_client_path_found(self, mock_isfile, mock_system, mock_join): + mock_join.return_value = "ssh_path" + mock_system.return_value = "Windows" + mock_isfile.return_value = True + path = ssh_utils._get_ssh_client_path("ssh-keygen", "folder") + self.assertEqual(path, "ssh_path.exe") + + def test_get_ssh_client_preinstalled(self): + path = ssh_utils._get_ssh_client_path("ssh-keygen", None) + self.assertEqual(path, "ssh-keygen") \ No newline at end of file diff --git a/src/ssh/azext_ssh/vendored_sdks/__init__.py b/src/ssh/azext_ssh/vendored_sdks/__init__.py new file mode 100644 index 0000000000..c9cfdc73e7 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/__init__.py @@ -0,0 +1,12 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +__path__ = __import__('pkgutil').extend_path(__path__, __name__) diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/__init__.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/__init__.py new file mode 100644 index 0000000000..9a8a1b4dcf --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/__init__.py @@ -0,0 +1,19 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._connected_machine import ConnectedMachine +from ._version import VERSION + +__version__ = VERSION +__all__ = ['ConnectedMachine'] + +try: + from ._patch import patch_sdk # type: ignore + patch_sdk() +except ImportError: + pass diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_configuration.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_configuration.py new file mode 100644 index 0000000000..102684e182 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_configuration.py @@ -0,0 +1,71 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import TYPE_CHECKING + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies +from azure.mgmt.core.policies import ARMHttpLoggingPolicy + +from ._version import VERSION + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any + + from azure.core.credentials import TokenCredential + + +class ConnectedMachineConfiguration(Configuration): + """Configuration for ConnectedMachine. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.TokenCredential + :param subscription_id: The ID of the target subscription. + :type subscription_id: str + """ + + def __init__( + self, + credential, # type: "TokenCredential" + subscription_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + if subscription_id is None: + raise ValueError("Parameter 'subscription_id' must not be None.") + super(ConnectedMachineConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.subscription_id = subscription_id + self.api_version = "2021-05-20" + self.credential_scopes = kwargs.pop('credential_scopes', ['https://management.azure.com/.default']) + kwargs.setdefault('sdk_moniker', 'mgmt-hybridcompute/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs # type: Any + ): + # type: (...) -> None + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or ARMHttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_connected_machine.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_connected_machine.py new file mode 100644 index 0000000000..75b9809af7 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_connected_machine.py @@ -0,0 +1,96 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import TYPE_CHECKING + +from azure.mgmt.core import ARMPipelineClient +from msrest import Deserializer, Serializer + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Optional + + from azure.core.credentials import TokenCredential + +from ._configuration import ConnectedMachineConfiguration +from .operations import MachinesOperations +from .operations import MachineExtensionsOperations +from .operations import ConnectedMachineOperationsMixin +from .operations import Operations +from .operations import PrivateLinkScopesOperations +from .operations import PrivateLinkResourcesOperations +from .operations import PrivateEndpointConnectionsOperations +from . import models + + +class ConnectedMachine(ConnectedMachineOperationsMixin): + """The Hybrid Compute Management Client. + + :ivar machines: MachinesOperations operations + :vartype machines: azure.mgmt.hybridcompute.operations.MachinesOperations + :ivar machine_extensions: MachineExtensionsOperations operations + :vartype machine_extensions: azure.mgmt.hybridcompute.operations.MachineExtensionsOperations + :ivar operations: Operations operations + :vartype operations: azure.mgmt.hybridcompute.operations.Operations + :ivar private_link_scopes: PrivateLinkScopesOperations operations + :vartype private_link_scopes: azure.mgmt.hybridcompute.operations.PrivateLinkScopesOperations + :ivar private_link_resources: PrivateLinkResourcesOperations operations + :vartype private_link_resources: azure.mgmt.hybridcompute.operations.PrivateLinkResourcesOperations + :ivar private_endpoint_connections: PrivateEndpointConnectionsOperations operations + :vartype private_endpoint_connections: azure.mgmt.hybridcompute.operations.PrivateEndpointConnectionsOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.TokenCredential + :param subscription_id: The ID of the target subscription. + :type subscription_id: str + :param str base_url: Service URL + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + """ + + def __init__( + self, + credential, # type: "TokenCredential" + subscription_id, # type: str + base_url=None, # type: Optional[str] + **kwargs # type: Any + ): + # type: (...) -> None + if not base_url: + base_url = 'https://management.azure.com' + self._config = ConnectedMachineConfiguration(credential, subscription_id, **kwargs) + self._client = ARMPipelineClient(base_url=base_url, config=self._config, **kwargs) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer(client_models) + self._serialize.client_side_validation = False + self._deserialize = Deserializer(client_models) + + self.machines = MachinesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.machine_extensions = MachineExtensionsOperations( + self._client, self._config, self._serialize, self._deserialize) + self.operations = Operations( + self._client, self._config, self._serialize, self._deserialize) + self.private_link_scopes = PrivateLinkScopesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.private_link_resources = PrivateLinkResourcesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.private_endpoint_connections = PrivateEndpointConnectionsOperations( + self._client, self._config, self._serialize, self._deserialize) + + def close(self): + # type: () -> None + self._client.close() + + def __enter__(self): + # type: () -> ConnectedMachine + self._client.__enter__() + return self + + def __exit__(self, *exc_details): + # type: (Any) -> None + self._client.__exit__(*exc_details) diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_version.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_version.py new file mode 100644 index 0000000000..e5754a47ce --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/_version.py @@ -0,0 +1,9 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +VERSION = "1.0.0b1" diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/__init__.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/__init__.py new file mode 100644 index 0000000000..5a8f3eca2b --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/__init__.py @@ -0,0 +1,10 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._connected_machine import ConnectedMachine +__all__ = ['ConnectedMachine'] diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/_configuration.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/_configuration.py new file mode 100644 index 0000000000..04e5e5f423 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/_configuration.py @@ -0,0 +1,67 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any, TYPE_CHECKING + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies +from azure.mgmt.core.policies import ARMHttpLoggingPolicy + +from .._version import VERSION + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + + +class ConnectedMachineConfiguration(Configuration): + """Configuration for ConnectedMachine. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :param subscription_id: The ID of the target subscription. + :type subscription_id: str + """ + + def __init__( + self, + credential: "AsyncTokenCredential", + subscription_id: str, + **kwargs: Any + ) -> None: + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + if subscription_id is None: + raise ValueError("Parameter 'subscription_id' must not be None.") + super(ConnectedMachineConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.subscription_id = subscription_id + self.api_version = "2021-05-20" + self.credential_scopes = kwargs.pop('credential_scopes', ['https://management.azure.com/.default']) + kwargs.setdefault('sdk_moniker', 'mgmt-hybridcompute/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs: Any + ) -> None: + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or ARMHttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/_connected_machine.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/_connected_machine.py new file mode 100644 index 0000000000..e5dbf9451b --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/_connected_machine.py @@ -0,0 +1,90 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any, Optional, TYPE_CHECKING + +from azure.mgmt.core import AsyncARMPipelineClient +from msrest import Deserializer, Serializer + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + +from ._configuration import ConnectedMachineConfiguration +from .operations import MachinesOperations +from .operations import MachineExtensionsOperations +from .operations import ConnectedMachineOperationsMixin +from .operations import Operations +from .operations import PrivateLinkScopesOperations +from .operations import PrivateLinkResourcesOperations +from .operations import PrivateEndpointConnectionsOperations +from .. import models + + +class ConnectedMachine(ConnectedMachineOperationsMixin): + """The Hybrid Compute Management Client. + + :ivar machines: MachinesOperations operations + :vartype machines: azure.mgmt.hybridcompute.aio.operations.MachinesOperations + :ivar machine_extensions: MachineExtensionsOperations operations + :vartype machine_extensions: azure.mgmt.hybridcompute.aio.operations.MachineExtensionsOperations + :ivar operations: Operations operations + :vartype operations: azure.mgmt.hybridcompute.aio.operations.Operations + :ivar private_link_scopes: PrivateLinkScopesOperations operations + :vartype private_link_scopes: azure.mgmt.hybridcompute.aio.operations.PrivateLinkScopesOperations + :ivar private_link_resources: PrivateLinkResourcesOperations operations + :vartype private_link_resources: azure.mgmt.hybridcompute.aio.operations.PrivateLinkResourcesOperations + :ivar private_endpoint_connections: PrivateEndpointConnectionsOperations operations + :vartype private_endpoint_connections: azure.mgmt.hybridcompute.aio.operations.PrivateEndpointConnectionsOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :param subscription_id: The ID of the target subscription. + :type subscription_id: str + :param str base_url: Service URL + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + """ + + def __init__( + self, + credential: "AsyncTokenCredential", + subscription_id: str, + base_url: Optional[str] = None, + **kwargs: Any + ) -> None: + if not base_url: + base_url = 'https://management.azure.com' + self._config = ConnectedMachineConfiguration(credential, subscription_id, **kwargs) + self._client = AsyncARMPipelineClient(base_url=base_url, config=self._config, **kwargs) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer(client_models) + self._serialize.client_side_validation = False + self._deserialize = Deserializer(client_models) + + self.machines = MachinesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.machine_extensions = MachineExtensionsOperations( + self._client, self._config, self._serialize, self._deserialize) + self.operations = Operations( + self._client, self._config, self._serialize, self._deserialize) + self.private_link_scopes = PrivateLinkScopesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.private_link_resources = PrivateLinkResourcesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.private_endpoint_connections = PrivateEndpointConnectionsOperations( + self._client, self._config, self._serialize, self._deserialize) + + async def close(self) -> None: + await self._client.close() + + async def __aenter__(self) -> "ConnectedMachine": + await self._client.__aenter__() + return self + + async def __aexit__(self, *exc_details) -> None: + await self._client.__aexit__(*exc_details) diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/__init__.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/__init__.py new file mode 100644 index 0000000000..641a5a8b66 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/__init__.py @@ -0,0 +1,25 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._machines_operations import MachinesOperations +from ._machine_extensions_operations import MachineExtensionsOperations +from ._connected_machine_operations import ConnectedMachineOperationsMixin +from ._operations import Operations +from ._private_link_scopes_operations import PrivateLinkScopesOperations +from ._private_link_resources_operations import PrivateLinkResourcesOperations +from ._private_endpoint_connections_operations import PrivateEndpointConnectionsOperations + +__all__ = [ + 'MachinesOperations', + 'MachineExtensionsOperations', + 'ConnectedMachineOperationsMixin', + 'Operations', + 'PrivateLinkScopesOperations', + 'PrivateLinkResourcesOperations', + 'PrivateEndpointConnectionsOperations', +] diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_connected_machine_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_connected_machine_operations.py new file mode 100644 index 0000000000..b05efa2259 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_connected_machine_operations.py @@ -0,0 +1,142 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, Callable, Dict, Generic, Optional, TypeVar, Union +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.core.polling import AsyncLROPoller, AsyncNoPolling, AsyncPollingMethod +from azure.mgmt.core.exceptions import ARMErrorFormat +from azure.mgmt.core.polling.async_arm_polling import AsyncARMPolling + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class ConnectedMachineOperationsMixin: + + async def _upgrade_extensions_initial( + self, + resource_group_name: str, + machine_name: str, + extension_upgrade_parameters: "models.MachineExtensionUpgrade", + **kwargs + ) -> None: + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self._upgrade_extensions_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(extension_upgrade_parameters, 'MachineExtensionUpgrade') + body_content_kwargs['content'] = body_content + request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + _upgrade_extensions_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/upgradeExtensions'} # type: ignore + + async def begin_upgrade_extensions( + self, + resource_group_name: str, + machine_name: str, + extension_upgrade_parameters: "models.MachineExtensionUpgrade", + **kwargs + ) -> AsyncLROPoller[None]: + """The operation to Upgrade Machine Extensions. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the hybrid machine. + :type machine_name: str + :param extension_upgrade_parameters: Parameters supplied to the Upgrade Extensions operation. + :type extension_upgrade_parameters: ~azure.mgmt.hybridcompute.models.MachineExtensionUpgrade + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of AsyncLROPoller that returns either None or the result of cls(response) + :rtype: ~azure.core.polling.AsyncLROPoller[None] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, AsyncPollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType[None] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = await self._upgrade_extensions_initial( + resource_group_name=resource_group_name, + machine_name=machine_name, + extension_upgrade_parameters=extension_upgrade_parameters, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + if cls: + return cls(pipeline_response, None, {}) + + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + } + + if polling is True: polling_method = AsyncARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = AsyncNoPolling() + else: polling_method = polling + if cont_token: + return AsyncLROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return AsyncLROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_upgrade_extensions.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/upgradeExtensions'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_machine_extensions_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_machine_extensions_operations.py new file mode 100644 index 0000000000..b9868deb18 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_machine_extensions_operations.py @@ -0,0 +1,571 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar, Union +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.core.polling import AsyncLROPoller, AsyncNoPolling, AsyncPollingMethod +from azure.mgmt.core.exceptions import ARMErrorFormat +from azure.mgmt.core.polling.async_arm_polling import AsyncARMPolling + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class MachineExtensionsOperations: + """MachineExtensionsOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + async def _create_or_update_initial( + self, + resource_group_name: str, + machine_name: str, + extension_name: str, + extension_parameters: "models.MachineExtension", + **kwargs + ) -> Optional["models.MachineExtension"]: + cls = kwargs.pop('cls', None) # type: ClsType[Optional["models.MachineExtension"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self._create_or_update_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(extension_parameters, 'MachineExtension') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + _create_or_update_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + async def begin_create_or_update( + self, + resource_group_name: str, + machine_name: str, + extension_name: str, + extension_parameters: "models.MachineExtension", + **kwargs + ) -> AsyncLROPoller["models.MachineExtension"]: + """The operation to create or update the extension. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine where the extension should be created or updated. + :type machine_name: str + :param extension_name: The name of the machine extension. + :type extension_name: str + :param extension_parameters: Parameters supplied to the Create Machine Extension operation. + :type extension_parameters: ~azure.mgmt.hybridcompute.models.MachineExtension + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of AsyncLROPoller that returns either MachineExtension or the result of cls(response) + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.mgmt.hybridcompute.models.MachineExtension] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, AsyncPollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineExtension"] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = await self._create_or_update_initial( + resource_group_name=resource_group_name, + machine_name=machine_name, + extension_name=extension_name, + extension_parameters=extension_parameters, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + return deserialized + + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + + if polling is True: polling_method = AsyncARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = AsyncNoPolling() + else: polling_method = polling + if cont_token: + return AsyncLROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return AsyncLROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_create_or_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + async def _update_initial( + self, + resource_group_name: str, + machine_name: str, + extension_name: str, + extension_parameters: "models.MachineExtensionUpdate", + **kwargs + ) -> Optional["models.MachineExtension"]: + cls = kwargs.pop('cls', None) # type: ClsType[Optional["models.MachineExtension"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self._update_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(extension_parameters, 'MachineExtensionUpdate') + body_content_kwargs['content'] = body_content + request = self._client.patch(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + _update_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + async def begin_update( + self, + resource_group_name: str, + machine_name: str, + extension_name: str, + extension_parameters: "models.MachineExtensionUpdate", + **kwargs + ) -> AsyncLROPoller["models.MachineExtension"]: + """The operation to create or update the extension. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine where the extension should be created or updated. + :type machine_name: str + :param extension_name: The name of the machine extension. + :type extension_name: str + :param extension_parameters: Parameters supplied to the Create Machine Extension operation. + :type extension_parameters: ~azure.mgmt.hybridcompute.models.MachineExtensionUpdate + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of AsyncLROPoller that returns either MachineExtension or the result of cls(response) + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.mgmt.hybridcompute.models.MachineExtension] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, AsyncPollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineExtension"] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = await self._update_initial( + resource_group_name=resource_group_name, + machine_name=machine_name, + extension_name=extension_name, + extension_parameters=extension_parameters, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + return deserialized + + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + + if polling is True: polling_method = AsyncARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = AsyncNoPolling() + else: polling_method = polling + if cont_token: + return AsyncLROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return AsyncLROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + async def _delete_initial( + self, + resource_group_name: str, + machine_name: str, + extension_name: str, + **kwargs + ) -> None: + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self._delete_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + _delete_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + async def begin_delete( + self, + resource_group_name: str, + machine_name: str, + extension_name: str, + **kwargs + ) -> AsyncLROPoller[None]: + """The operation to delete the extension. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine where the extension should be deleted. + :type machine_name: str + :param extension_name: The name of the machine extension. + :type extension_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of AsyncLROPoller that returns either None or the result of cls(response) + :rtype: ~azure.core.polling.AsyncLROPoller[None] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, AsyncPollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType[None] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = await self._delete_initial( + resource_group_name=resource_group_name, + machine_name=machine_name, + extension_name=extension_name, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + if cls: + return cls(pipeline_response, None, {}) + + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + + if polling is True: polling_method = AsyncARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = AsyncNoPolling() + else: polling_method = polling + if cont_token: + return AsyncLROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return AsyncLROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + async def get( + self, + resource_group_name: str, + machine_name: str, + extension_name: str, + **kwargs + ) -> "models.MachineExtension": + """The operation to get the extension. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine containing the extension. + :type machine_name: str + :param extension_name: The name of the machine extension. + :type extension_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: MachineExtension, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.MachineExtension + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineExtension"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + def list( + self, + resource_group_name: str, + machine_name: str, + expand: Optional[str] = None, + **kwargs + ) -> AsyncIterable["models.MachineExtensionsListResult"]: + """The operation to get all extensions of a non-Azure machine. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine containing the extension. + :type machine_name: str + :param expand: The expand expression to apply on the operation. + :type expand: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either MachineExtensionsListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.hybridcompute.models.MachineExtensionsListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineExtensionsListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if expand is not None: + query_parameters['$expand'] = self._serialize.query("expand", expand, 'str') + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('MachineExtensionsListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_machines_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_machines_operations.py new file mode 100644 index 0000000000..c066f92566 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_machines_operations.py @@ -0,0 +1,302 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar, Union +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.mgmt.core.exceptions import ARMErrorFormat + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class MachinesOperations: + """MachinesOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + async def delete( + self, + resource_group_name: str, + machine_name: str, + **kwargs + ) -> None: + """The operation to remove a hybrid machine identity in Azure. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the hybrid machine. + :type machine_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.delete.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}'} # type: ignore + + async def get( + self, + resource_group_name: str, + machine_name: str, + expand: Optional[Union[str, "models.InstanceViewTypes"]] = None, + **kwargs + ) -> "models.Machine": + """Retrieves information about the model view or the instance view of a hybrid machine. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the hybrid machine. + :type machine_name: str + :param expand: The expand expression to apply on the operation. + :type expand: str or ~azure.mgmt.hybridcompute.models.InstanceViewTypes + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Machine, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.Machine + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.Machine"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + if expand is not None: + query_parameters['$expand'] = self._serialize.query("expand", expand, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('Machine', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}'} # type: ignore + + def list_by_resource_group( + self, + resource_group_name: str, + **kwargs + ) -> AsyncIterable["models.MachineListResult"]: + """Lists all the hybrid machines in the specified resource group. Use the nextLink property in the + response to get the next page of hybrid machines. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either MachineListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.hybridcompute.models.MachineListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_resource_group.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('MachineListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list_by_resource_group.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines'} # type: ignore + + def list_by_subscription( + self, + **kwargs + ) -> AsyncIterable["models.MachineListResult"]: + """Lists all the hybrid machines in the specified subscription. Use the nextLink property in the + response to get the next page of hybrid machines. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either MachineListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.hybridcompute.models.MachineListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_subscription.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('MachineListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list_by_subscription.metadata = {'url': '/subscriptions/{subscriptionId}/providers/Microsoft.HybridCompute/machines'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_operations.py new file mode 100644 index 0000000000..581f88b893 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_operations.py @@ -0,0 +1,105 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.mgmt.core.exceptions import ARMErrorFormat + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class Operations: + """Operations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list( + self, + **kwargs + ) -> AsyncIterable["models.OperationListResult"]: + """Gets a list of hybrid compute operations. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either OperationListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.hybridcompute.models.OperationListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.OperationListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('OperationListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/providers/Microsoft.HybridCompute/operations'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_endpoint_connections_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_endpoint_connections_operations.py new file mode 100644 index 0000000000..29a4616941 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_endpoint_connections_operations.py @@ -0,0 +1,432 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar, Union +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.core.polling import AsyncLROPoller, AsyncNoPolling, AsyncPollingMethod +from azure.mgmt.core.exceptions import ARMErrorFormat +from azure.mgmt.core.polling.async_arm_polling import AsyncARMPolling + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class PrivateEndpointConnectionsOperations: + """PrivateEndpointConnectionsOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + async def get( + self, + resource_group_name: str, + scope_name: str, + private_endpoint_connection_name: str, + **kwargs + ) -> "models.PrivateEndpointConnection": + """Gets a private endpoint connection. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param private_endpoint_connection_name: The name of the private endpoint connection. + :type private_endpoint_connection_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: PrivateEndpointConnection, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.PrivateEndpointConnection + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateEndpointConnection"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('PrivateEndpointConnection', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + async def _update_initial( + self, + resource_group_name: str, + scope_name: str, + private_endpoint_connection_name: str, + parameters: "models.PrivateEndpointConnection", + **kwargs + ) -> Optional["models.PrivateEndpointConnection"]: + cls = kwargs.pop('cls', None) # type: ClsType[Optional["models.PrivateEndpointConnection"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self._update_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(parameters, 'PrivateEndpointConnection') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('PrivateEndpointConnection', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + _update_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + async def begin_update( + self, + resource_group_name: str, + scope_name: str, + private_endpoint_connection_name: str, + parameters: "models.PrivateEndpointConnection", + **kwargs + ) -> AsyncLROPoller["models.PrivateEndpointConnection"]: + """Approve or reject a private endpoint connection with a given name. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param private_endpoint_connection_name: The name of the private endpoint connection. + :type private_endpoint_connection_name: str + :param parameters: + :type parameters: ~azure.mgmt.hybridcompute.models.PrivateEndpointConnection + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of AsyncLROPoller that returns either PrivateEndpointConnection or the result of cls(response) + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.mgmt.hybridcompute.models.PrivateEndpointConnection] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, AsyncPollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateEndpointConnection"] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = await self._update_initial( + resource_group_name=resource_group_name, + scope_name=scope_name, + private_endpoint_connection_name=private_endpoint_connection_name, + parameters=parameters, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + deserialized = self._deserialize('PrivateEndpointConnection', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + return deserialized + + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + + if polling is True: polling_method = AsyncARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = AsyncNoPolling() + else: polling_method = polling + if cont_token: + return AsyncLROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return AsyncLROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + async def _delete_initial( + self, + resource_group_name: str, + scope_name: str, + private_endpoint_connection_name: str, + **kwargs + ) -> None: + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self._delete_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + _delete_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + async def begin_delete( + self, + resource_group_name: str, + scope_name: str, + private_endpoint_connection_name: str, + **kwargs + ) -> AsyncLROPoller[None]: + """Deletes a private endpoint connection with a given name. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param private_endpoint_connection_name: The name of the private endpoint connection. + :type private_endpoint_connection_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of AsyncLROPoller that returns either None or the result of cls(response) + :rtype: ~azure.core.polling.AsyncLROPoller[None] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, AsyncPollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType[None] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = await self._delete_initial( + resource_group_name=resource_group_name, + scope_name=scope_name, + private_endpoint_connection_name=private_endpoint_connection_name, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + if cls: + return cls(pipeline_response, None, {}) + + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + + if polling is True: polling_method = AsyncARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = AsyncNoPolling() + else: polling_method = polling + if cont_token: + return AsyncLROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return AsyncLROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + def list_by_private_link_scope( + self, + resource_group_name: str, + scope_name: str, + **kwargs + ) -> AsyncIterable["models.PrivateEndpointConnectionListResult"]: + """Gets all private endpoint connections on a private link scope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PrivateEndpointConnectionListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.hybridcompute.models.PrivateEndpointConnectionListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateEndpointConnectionListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_private_link_scope.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PrivateEndpointConnectionListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list_by_private_link_scope.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_link_resources_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_link_resources_operations.py new file mode 100644 index 0000000000..59d9100254 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_link_resources_operations.py @@ -0,0 +1,180 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.mgmt.core.exceptions import ARMErrorFormat + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class PrivateLinkResourcesOperations: + """PrivateLinkResourcesOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list_by_private_link_scope( + self, + resource_group_name: str, + scope_name: str, + **kwargs + ) -> AsyncIterable["models.PrivateLinkResourceListResult"]: + """Gets the private link resources that need to be created for a Azure Monitor PrivateLinkScope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PrivateLinkResourceListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.hybridcompute.models.PrivateLinkResourceListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateLinkResourceListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_private_link_scope.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PrivateLinkResourceListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list_by_private_link_scope.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateLinkResources'} # type: ignore + + async def get( + self, + resource_group_name: str, + scope_name: str, + group_name: str, + **kwargs + ) -> "models.PrivateLinkResource": + """Gets the private link resources that need to be created for a Azure Monitor PrivateLinkScope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param group_name: The name of the private link resource. + :type group_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: PrivateLinkResource, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.PrivateLinkResource + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateLinkResource"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'groupName': self._serialize.url("group_name", group_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('PrivateLinkResource', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateLinkResources/{groupName}'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_link_scopes_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_link_scopes_operations.py new file mode 100644 index 0000000000..dcc71ced52 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/aio/operations/_private_link_scopes_operations.py @@ -0,0 +1,611 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar, Union +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.core.polling import AsyncLROPoller, AsyncNoPolling, AsyncPollingMethod +from azure.mgmt.core.exceptions import ARMErrorFormat +from azure.mgmt.core.polling.async_arm_polling import AsyncARMPolling + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class PrivateLinkScopesOperations: + """PrivateLinkScopesOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list( + self, + **kwargs + ) -> AsyncIterable["models.HybridComputePrivateLinkScopeListResult"]: + """Gets a list of all Azure Arc PrivateLinkScopes within a subscription. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either HybridComputePrivateLinkScopeListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScopeListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScopeListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('HybridComputePrivateLinkScopeListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/subscriptions/{subscriptionId}/providers/Microsoft.HybridCompute/privateLinkScopes'} # type: ignore + + def list_by_resource_group( + self, + resource_group_name: str, + **kwargs + ) -> AsyncIterable["models.HybridComputePrivateLinkScopeListResult"]: + """Gets a list of Azure Arc PrivateLinkScopes within a resource group. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either HybridComputePrivateLinkScopeListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScopeListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScopeListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_resource_group.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('HybridComputePrivateLinkScopeListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list_by_resource_group.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes'} # type: ignore + + async def _delete_initial( + self, + resource_group_name: str, + scope_name: str, + **kwargs + ) -> None: + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self._delete_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + _delete_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + async def begin_delete( + self, + resource_group_name: str, + scope_name: str, + **kwargs + ) -> AsyncLROPoller[None]: + """Deletes a Azure Arc PrivateLinkScope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of AsyncLROPoller that returns either None or the result of cls(response) + :rtype: ~azure.core.polling.AsyncLROPoller[None] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, AsyncPollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType[None] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = await self._delete_initial( + resource_group_name=resource_group_name, + scope_name=scope_name, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + if cls: + return cls(pipeline_response, None, {}) + + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + + if polling is True: polling_method = AsyncARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = AsyncNoPolling() + else: polling_method = polling + if cont_token: + return AsyncLROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return AsyncLROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + async def get( + self, + resource_group_name: str, + scope_name: str, + **kwargs + ) -> "models.HybridComputePrivateLinkScope": + """Returns a Azure Arc PrivateLinkScope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: HybridComputePrivateLinkScope, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScope"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('HybridComputePrivateLinkScope', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + async def create_or_update( + self, + resource_group_name: str, + scope_name: str, + parameters: "models.HybridComputePrivateLinkScope", + **kwargs + ) -> "models.HybridComputePrivateLinkScope": + """Creates (or updates) a Azure Arc PrivateLinkScope. Note: You cannot specify a different value + for InstrumentationKey nor AppId in the Put operation. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param parameters: Properties that need to be specified to create or update a Azure Arc for + Servers and Clusters PrivateLinkScope. + :type parameters: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope + :keyword callable cls: A custom type or function that will be passed the direct response + :return: HybridComputePrivateLinkScope, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScope"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.create_or_update.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(parameters, 'HybridComputePrivateLinkScope') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if response.status_code == 200: + deserialized = self._deserialize('HybridComputePrivateLinkScope', pipeline_response) + + if response.status_code == 201: + deserialized = self._deserialize('HybridComputePrivateLinkScope', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + create_or_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + async def update_tags( + self, + resource_group_name: str, + scope_name: str, + private_link_scope_tags: "models.TagsResource", + **kwargs + ) -> "models.HybridComputePrivateLinkScope": + """Updates an existing PrivateLinkScope's tags. To update other fields use the CreateOrUpdate + method. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param private_link_scope_tags: Updated tag information to set into the PrivateLinkScope + instance. + :type private_link_scope_tags: ~azure.mgmt.hybridcompute.models.TagsResource + :keyword callable cls: A custom type or function that will be passed the direct response + :return: HybridComputePrivateLinkScope, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScope"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.update_tags.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(private_link_scope_tags, 'TagsResource') + body_content_kwargs['content'] = body_content + request = self._client.patch(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('HybridComputePrivateLinkScope', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + update_tags.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + async def get_validation_details( + self, + location: str, + private_link_scope_id: str, + **kwargs + ) -> "models.PrivateLinkScopeValidationDetails": + """Returns a Azure Arc PrivateLinkScope's validation details. + + :param location: The location of the target resource. + :type location: str + :param private_link_scope_id: The id (Guid) of the Azure Arc PrivateLinkScope resource. + :type private_link_scope_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: PrivateLinkScopeValidationDetails, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.PrivateLinkScopeValidationDetails + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateLinkScopeValidationDetails"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get_validation_details.metadata['url'] # type: ignore + path_format_arguments = { + 'location': self._serialize.url("location", location, 'str', min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'privateLinkScopeId': self._serialize.url("private_link_scope_id", private_link_scope_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('PrivateLinkScopeValidationDetails', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_validation_details.metadata = {'url': '/subscriptions/{subscriptionId}/providers/Microsoft.HybridCompute/locations/{location}/privateLinkScopes/{privateLinkScopeId}'} # type: ignore + + async def get_validation_details_for_machine( + self, + resource_group_name: str, + machine_name: str, + **kwargs + ) -> "models.PrivateLinkScopeValidationDetails": + """Returns a Azure Arc PrivateLinkScope's validation details for a given machine. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the target machine to get the private link scope validation + details for. + :type machine_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: PrivateLinkScopeValidationDetails, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.PrivateLinkScopeValidationDetails + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateLinkScopeValidationDetails"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get_validation_details_for_machine.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('PrivateLinkScopeValidationDetails', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_validation_details_for_machine.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/privateLinkScopes/current'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/__init__.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/__init__.py new file mode 100644 index 0000000000..1046533c5d --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/__init__.py @@ -0,0 +1,155 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +try: + from ._models_py3 import ConnectionDetail + from ._models_py3 import ErrorAdditionalInfo + from ._models_py3 import ErrorDetail + from ._models_py3 import ErrorResponse + from ._models_py3 import ExtensionTargetProperties + from ._models_py3 import HybridComputePrivateLinkScope + from ._models_py3 import HybridComputePrivateLinkScopeListResult + from ._models_py3 import HybridComputePrivateLinkScopeProperties + from ._models_py3 import Identity + from ._models_py3 import LocationData + from ._models_py3 import Machine + from ._models_py3 import MachineExtension + from ._models_py3 import MachineExtensionInstanceView + from ._models_py3 import MachineExtensionInstanceViewStatus + from ._models_py3 import MachineExtensionProperties + from ._models_py3 import MachineExtensionUpdate + from ._models_py3 import MachineExtensionUpdateProperties + from ._models_py3 import MachineExtensionUpgrade + from ._models_py3 import MachineExtensionsListResult + from ._models_py3 import MachineListResult + from ._models_py3 import MachineProperties + from ._models_py3 import MachineUpdate + from ._models_py3 import MachineUpdateProperties + from ._models_py3 import OperationListResult + from ._models_py3 import OperationValue + from ._models_py3 import OperationValueDisplay + from ._models_py3 import OsProfile + from ._models_py3 import PrivateEndpointConnection + from ._models_py3 import PrivateEndpointConnectionListResult + from ._models_py3 import PrivateEndpointConnectionProperties + from ._models_py3 import PrivateEndpointProperty + from ._models_py3 import PrivateLinkResource + from ._models_py3 import PrivateLinkResourceListResult + from ._models_py3 import PrivateLinkResourceProperties + from ._models_py3 import PrivateLinkScopeValidationDetails + from ._models_py3 import PrivateLinkScopesResource + from ._models_py3 import PrivateLinkServiceConnectionStateProperty + from ._models_py3 import ProxyResource + from ._models_py3 import Resource + from ._models_py3 import ResourceUpdate + from ._models_py3 import SystemData + from ._models_py3 import TagsResource + from ._models_py3 import TrackedResource +except (SyntaxError, ImportError): + from ._models import ConnectionDetail # type: ignore + from ._models import ErrorAdditionalInfo # type: ignore + from ._models import ErrorDetail # type: ignore + from ._models import ErrorResponse # type: ignore + from ._models import ExtensionTargetProperties # type: ignore + from ._models import HybridComputePrivateLinkScope # type: ignore + from ._models import HybridComputePrivateLinkScopeListResult # type: ignore + from ._models import HybridComputePrivateLinkScopeProperties # type: ignore + from ._models import Identity # type: ignore + from ._models import LocationData # type: ignore + from ._models import Machine # type: ignore + from ._models import MachineExtension # type: ignore + from ._models import MachineExtensionInstanceView # type: ignore + from ._models import MachineExtensionInstanceViewStatus # type: ignore + from ._models import MachineExtensionProperties # type: ignore + from ._models import MachineExtensionUpdate # type: ignore + from ._models import MachineExtensionUpdateProperties # type: ignore + from ._models import MachineExtensionUpgrade # type: ignore + from ._models import MachineExtensionsListResult # type: ignore + from ._models import MachineListResult # type: ignore + from ._models import MachineProperties # type: ignore + from ._models import MachineUpdate # type: ignore + from ._models import MachineUpdateProperties # type: ignore + from ._models import OperationListResult # type: ignore + from ._models import OperationValue # type: ignore + from ._models import OperationValueDisplay # type: ignore + from ._models import OsProfile # type: ignore + from ._models import PrivateEndpointConnection # type: ignore + from ._models import PrivateEndpointConnectionListResult # type: ignore + from ._models import PrivateEndpointConnectionProperties # type: ignore + from ._models import PrivateEndpointProperty # type: ignore + from ._models import PrivateLinkResource # type: ignore + from ._models import PrivateLinkResourceListResult # type: ignore + from ._models import PrivateLinkResourceProperties # type: ignore + from ._models import PrivateLinkScopeValidationDetails # type: ignore + from ._models import PrivateLinkScopesResource # type: ignore + from ._models import PrivateLinkServiceConnectionStateProperty # type: ignore + from ._models import ProxyResource # type: ignore + from ._models import Resource # type: ignore + from ._models import ResourceUpdate # type: ignore + from ._models import SystemData # type: ignore + from ._models import TagsResource # type: ignore + from ._models import TrackedResource # type: ignore + +from ._connected_machine_enums import ( + CreatedByType, + InstanceViewTypes, + PublicNetworkAccessType, + StatusLevelTypes, + StatusTypes, +) + +__all__ = [ + 'ConnectionDetail', + 'ErrorAdditionalInfo', + 'ErrorDetail', + 'ErrorResponse', + 'ExtensionTargetProperties', + 'HybridComputePrivateLinkScope', + 'HybridComputePrivateLinkScopeListResult', + 'HybridComputePrivateLinkScopeProperties', + 'Identity', + 'LocationData', + 'Machine', + 'MachineExtension', + 'MachineExtensionInstanceView', + 'MachineExtensionInstanceViewStatus', + 'MachineExtensionProperties', + 'MachineExtensionUpdate', + 'MachineExtensionUpdateProperties', + 'MachineExtensionUpgrade', + 'MachineExtensionsListResult', + 'MachineListResult', + 'MachineProperties', + 'MachineUpdate', + 'MachineUpdateProperties', + 'OperationListResult', + 'OperationValue', + 'OperationValueDisplay', + 'OsProfile', + 'PrivateEndpointConnection', + 'PrivateEndpointConnectionListResult', + 'PrivateEndpointConnectionProperties', + 'PrivateEndpointProperty', + 'PrivateLinkResource', + 'PrivateLinkResourceListResult', + 'PrivateLinkResourceProperties', + 'PrivateLinkScopeValidationDetails', + 'PrivateLinkScopesResource', + 'PrivateLinkServiceConnectionStateProperty', + 'ProxyResource', + 'Resource', + 'ResourceUpdate', + 'SystemData', + 'TagsResource', + 'TrackedResource', + 'CreatedByType', + 'InstanceViewTypes', + 'PublicNetworkAccessType', + 'StatusLevelTypes', + 'StatusTypes', +] diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_connected_machine_enums.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_connected_machine_enums.py new file mode 100644 index 0000000000..dec09de8f5 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_connected_machine_enums.py @@ -0,0 +1,64 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from enum import Enum, EnumMeta +from six import with_metaclass + +class _CaseInsensitiveEnumMeta(EnumMeta): + def __getitem__(self, name): + return super().__getitem__(name.upper()) + + def __getattr__(cls, name): + """Return the enum member matching `name` + We use __getattr__ instead of descriptors or inserting into the enum + class' __dict__ in order to support `name` and `value` being both + properties for enum members (which live in the class' __dict__) and + enum members themselves. + """ + try: + return cls._member_map_[name.upper()] + except KeyError: + raise AttributeError(name) + + +class CreatedByType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The type of identity that created the resource. + """ + + USER = "User" + APPLICATION = "Application" + MANAGED_IDENTITY = "ManagedIdentity" + KEY = "Key" + +class InstanceViewTypes(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + + INSTANCE_VIEW = "instanceView" + +class PublicNetworkAccessType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The network access policy to determine if Azure Arc agents can use public Azure Arc service + endpoints. Defaults to disabled (access to Azure Arc services only via private link). + """ + + ENABLED = "Enabled" #: Allows Azure Arc agents to communicate with Azure Arc services over both public (internet) and private endpoints. + DISABLED = "Disabled" #: Does not allow Azure Arc agents to communicate with Azure Arc services over public (internet) endpoints. The agents must use the private link. + +class StatusLevelTypes(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The level code. + """ + + INFO = "Info" + WARNING = "Warning" + ERROR = "Error" + +class StatusTypes(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The status of the hybrid machine agent. + """ + + CONNECTED = "Connected" + DISCONNECTED = "Disconnected" + ERROR = "Error" diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_models.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_models.py new file mode 100644 index 0000000000..c430690dd8 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_models.py @@ -0,0 +1,1601 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from azure.core.exceptions import HttpResponseError +import msrest.serialization + + +class ConnectionDetail(msrest.serialization.Model): + """ConnectionDetail. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Azure resource Id. + :vartype id: str + :ivar private_ip_address: The private endpoint connection private ip address. + :vartype private_ip_address: str + :ivar link_identifier: The private endpoint connection link identifier. + :vartype link_identifier: str + :ivar group_id: The private endpoint connection group id. + :vartype group_id: str + :ivar member_name: The private endpoint connection member name. + :vartype member_name: str + """ + + _validation = { + 'id': {'readonly': True}, + 'private_ip_address': {'readonly': True}, + 'link_identifier': {'readonly': True}, + 'group_id': {'readonly': True}, + 'member_name': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'private_ip_address': {'key': 'privateIpAddress', 'type': 'str'}, + 'link_identifier': {'key': 'linkIdentifier', 'type': 'str'}, + 'group_id': {'key': 'groupId', 'type': 'str'}, + 'member_name': {'key': 'memberName', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(ConnectionDetail, self).__init__(**kwargs) + self.id = None + self.private_ip_address = None + self.link_identifier = None + self.group_id = None + self.member_name = None + + +class ErrorAdditionalInfo(msrest.serialization.Model): + """The resource management error additional info. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar type: The additional info type. + :vartype type: str + :ivar info: The additional info. + :vartype info: object + """ + + _validation = { + 'type': {'readonly': True}, + 'info': {'readonly': True}, + } + + _attribute_map = { + 'type': {'key': 'type', 'type': 'str'}, + 'info': {'key': 'info', 'type': 'object'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorAdditionalInfo, self).__init__(**kwargs) + self.type = None + self.info = None + + +class ErrorDetail(msrest.serialization.Model): + """The error detail. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar code: The error code. + :vartype code: str + :ivar message: The error message. + :vartype message: str + :ivar target: The error target. + :vartype target: str + :ivar details: The error details. + :vartype details: list[~azure.mgmt.hybridcompute.models.ErrorDetail] + :ivar additional_info: The error additional info. + :vartype additional_info: list[~azure.mgmt.hybridcompute.models.ErrorAdditionalInfo] + """ + + _validation = { + 'code': {'readonly': True}, + 'message': {'readonly': True}, + 'target': {'readonly': True}, + 'details': {'readonly': True}, + 'additional_info': {'readonly': True}, + } + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'target': {'key': 'target', 'type': 'str'}, + 'details': {'key': 'details', 'type': '[ErrorDetail]'}, + 'additional_info': {'key': 'additionalInfo', 'type': '[ErrorAdditionalInfo]'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorDetail, self).__init__(**kwargs) + self.code = None + self.message = None + self.target = None + self.details = None + self.additional_info = None + + +class ErrorResponse(msrest.serialization.Model): + """Common error response for all Azure Resource Manager APIs to return error details for failed operations. (This also follows the OData error response format.). + + :param error: The error object. + :type error: ~azure.mgmt.hybridcompute.models.ErrorDetail + """ + + _attribute_map = { + 'error': {'key': 'error', 'type': 'ErrorDetail'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorResponse, self).__init__(**kwargs) + self.error = kwargs.get('error', None) + + +class ExtensionTargetProperties(msrest.serialization.Model): + """Describes the Machine Extension Target Version Properties. + + :param target_version: Properties for the specified Extension to Upgrade. + :type target_version: str + """ + + _attribute_map = { + 'target_version': {'key': 'targetVersion', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(ExtensionTargetProperties, self).__init__(**kwargs) + self.target_version = kwargs.get('target_version', None) + + +class PrivateLinkScopesResource(msrest.serialization.Model): + """An azure resource object. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Azure resource Id. + :vartype id: str + :ivar name: Azure resource name. + :vartype name: str + :ivar type: Azure resource type. + :vartype type: str + :param location: Required. Resource location. + :type location: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'location': {'key': 'location', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateLinkScopesResource, self).__init__(**kwargs) + self.id = None + self.name = None + self.type = None + self.location = kwargs['location'] + self.tags = kwargs.get('tags', None) + + +class HybridComputePrivateLinkScope(PrivateLinkScopesResource): + """An Azure Arc PrivateLinkScope definition. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Azure resource Id. + :vartype id: str + :ivar name: Azure resource name. + :vartype name: str + :ivar type: Azure resource type. + :vartype type: str + :param location: Required. Resource location. + :type location: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param properties: Properties that define a Azure Arc PrivateLinkScope resource. + :type properties: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScopeProperties + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'location': {'key': 'location', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'properties': {'key': 'properties', 'type': 'HybridComputePrivateLinkScopeProperties'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + **kwargs + ): + super(HybridComputePrivateLinkScope, self).__init__(**kwargs) + self.properties = kwargs.get('properties', None) + self.system_data = None + + +class HybridComputePrivateLinkScopeListResult(msrest.serialization.Model): + """Describes the list of Azure Arc PrivateLinkScope resources. + + All required parameters must be populated in order to send to Azure. + + :param value: Required. List of Azure Arc PrivateLinkScope definitions. + :type value: list[~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope] + :param next_link: The URI to get the next set of Azure Arc PrivateLinkScope definitions if too + many PrivateLinkScopes where returned in the result set. + :type next_link: str + """ + + _validation = { + 'value': {'required': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[HybridComputePrivateLinkScope]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(HybridComputePrivateLinkScopeListResult, self).__init__(**kwargs) + self.value = kwargs['value'] + self.next_link = kwargs.get('next_link', None) + + +class HybridComputePrivateLinkScopeProperties(msrest.serialization.Model): + """Properties that define a Azure Arc PrivateLinkScope resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param public_network_access: Indicates whether machines associated with the private link scope + can also use public Azure Arc service endpoints. Possible values include: "Enabled", + "Disabled". Default value: "Disabled". + :type public_network_access: str or ~azure.mgmt.hybridcompute.models.PublicNetworkAccessType + :ivar provisioning_state: Current state of this PrivateLinkScope: whether or not is has been + provisioned within the resource group it is defined. Users cannot change this value but are + able to read from it. Values will include Provisioning ,Succeeded, Canceled and Failed. + :vartype provisioning_state: str + :ivar private_link_scope_id: The Guid id of the private link scope. + :vartype private_link_scope_id: str + """ + + _validation = { + 'provisioning_state': {'readonly': True}, + 'private_link_scope_id': {'readonly': True}, + } + + _attribute_map = { + 'public_network_access': {'key': 'publicNetworkAccess', 'type': 'str'}, + 'provisioning_state': {'key': 'provisioningState', 'type': 'str'}, + 'private_link_scope_id': {'key': 'privateLinkScopeId', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(HybridComputePrivateLinkScopeProperties, self).__init__(**kwargs) + self.public_network_access = kwargs.get('public_network_access', "Disabled") + self.provisioning_state = None + self.private_link_scope_id = None + + +class Identity(msrest.serialization.Model): + """Identity for the resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar principal_id: The principal ID of resource identity. + :vartype principal_id: str + :ivar tenant_id: The tenant ID of resource. + :vartype tenant_id: str + :ivar type: The identity type. Default value: "SystemAssigned". + :vartype type: str + """ + + _validation = { + 'principal_id': {'readonly': True}, + 'tenant_id': {'readonly': True}, + 'type': {'constant': True}, + } + + _attribute_map = { + 'principal_id': {'key': 'principalId', 'type': 'str'}, + 'tenant_id': {'key': 'tenantId', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + type = "SystemAssigned" + + def __init__( + self, + **kwargs + ): + super(Identity, self).__init__(**kwargs) + self.principal_id = None + self.tenant_id = None + + +class LocationData(msrest.serialization.Model): + """Metadata pertaining to the geographic location of the resource. + + All required parameters must be populated in order to send to Azure. + + :param name: Required. A canonical name for the geographic or physical location. + :type name: str + :param city: The city or locality where the resource is located. + :type city: str + :param district: The district, state, or province where the resource is located. + :type district: str + :param country_or_region: The country or region where the resource is located. + :type country_or_region: str + """ + + _validation = { + 'name': {'required': True, 'max_length': 256, 'min_length': 0}, + } + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'city': {'key': 'city', 'type': 'str'}, + 'district': {'key': 'district', 'type': 'str'}, + 'country_or_region': {'key': 'countryOrRegion', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(LocationData, self).__init__(**kwargs) + self.name = kwargs['name'] + self.city = kwargs.get('city', None) + self.district = kwargs.get('district', None) + self.country_or_region = kwargs.get('country_or_region', None) + + +class Resource(msrest.serialization.Model): + """Common fields that are returned in the response for all Azure Resource Manager resources. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Resource, self).__init__(**kwargs) + self.id = None + self.name = None + self.type = None + + +class TrackedResource(Resource): + """The resource model definition for an Azure Resource Manager tracked top level resource which has 'tags' and a 'location'. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param location: Required. The geo-location where the resource lives. + :type location: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'location': {'key': 'location', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(TrackedResource, self).__init__(**kwargs) + self.tags = kwargs.get('tags', None) + self.location = kwargs['location'] + + +class Machine(TrackedResource): + """Describes a hybrid machine. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param location: Required. The geo-location where the resource lives. + :type location: str + :param properties: Hybrid Compute Machine properties. + :type properties: ~azure.mgmt.hybridcompute.models.MachineProperties + :param identity: Identity for the resource. + :type identity: ~azure.mgmt.hybridcompute.models.Identity + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'location': {'key': 'location', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'MachineProperties'}, + 'identity': {'key': 'identity', 'type': 'Identity'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + **kwargs + ): + super(Machine, self).__init__(**kwargs) + self.properties = kwargs.get('properties', None) + self.identity = kwargs.get('identity', None) + self.system_data = None + + +class MachineExtension(TrackedResource): + """Describes a Machine Extension. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param location: Required. The geo-location where the resource lives. + :type location: str + :param properties: Describes Machine Extension Properties. + :type properties: ~azure.mgmt.hybridcompute.models.MachineExtensionProperties + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'location': {'key': 'location', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'MachineExtensionProperties'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineExtension, self).__init__(**kwargs) + self.properties = kwargs.get('properties', None) + self.system_data = None + + +class MachineExtensionInstanceView(msrest.serialization.Model): + """Describes the Machine Extension Instance View. + + :param name: The machine extension name. + :type name: str + :param type: Specifies the type of the extension; an example is "CustomScriptExtension". + :type type: str + :param type_handler_version: Specifies the version of the script handler. + :type type_handler_version: str + :param status: Instance view status. + :type status: ~azure.mgmt.hybridcompute.models.MachineExtensionInstanceViewStatus + """ + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'type_handler_version': {'key': 'typeHandlerVersion', 'type': 'str'}, + 'status': {'key': 'status', 'type': 'MachineExtensionInstanceViewStatus'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineExtensionInstanceView, self).__init__(**kwargs) + self.name = kwargs.get('name', None) + self.type = kwargs.get('type', None) + self.type_handler_version = kwargs.get('type_handler_version', None) + self.status = kwargs.get('status', None) + + +class MachineExtensionInstanceViewStatus(msrest.serialization.Model): + """Instance view status. + + :param code: The status code. + :type code: str + :param level: The level code. Possible values include: "Info", "Warning", "Error". + :type level: str or ~azure.mgmt.hybridcompute.models.StatusLevelTypes + :param display_status: The short localizable label for the status. + :type display_status: str + :param message: The detailed status message, including for alerts and error messages. + :type message: str + :param time: The time of the status. + :type time: ~datetime.datetime + """ + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'level': {'key': 'level', 'type': 'str'}, + 'display_status': {'key': 'displayStatus', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'time': {'key': 'time', 'type': 'iso-8601'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineExtensionInstanceViewStatus, self).__init__(**kwargs) + self.code = kwargs.get('code', None) + self.level = kwargs.get('level', None) + self.display_status = kwargs.get('display_status', None) + self.message = kwargs.get('message', None) + self.time = kwargs.get('time', None) + + +class MachineExtensionProperties(msrest.serialization.Model): + """Describes the properties of a Machine Extension. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param force_update_tag: How the extension handler should be forced to update even if the + extension configuration has not changed. + :type force_update_tag: str + :param publisher: The name of the extension handler publisher. + :type publisher: str + :param type: Specifies the type of the extension; an example is "CustomScriptExtension". + :type type: str + :param type_handler_version: Specifies the version of the script handler. + :type type_handler_version: str + :param enable_auto_upgrade: Indicates whether the extension should be automatically + upgraded by the platform if there is a newer version available. + :type enable_auto_upgrade: bool + :param auto_upgrade_minor_version: Indicates whether the extension should use a newer minor + version if one is available at deployment time. Once deployed, however, the extension will not + upgrade minor versions unless redeployed, even with this property set to true. + :type auto_upgrade_minor_version: bool + :param settings: Json formatted public settings for the extension. + :type settings: object + :param protected_settings: The extension can contain either protectedSettings or + protectedSettingsFromKeyVault or no protected settings at all. + :type protected_settings: object + :ivar provisioning_state: The provisioning state, which only appears in the response. + :vartype provisioning_state: str + :param instance_view: The machine extension instance view. + :type instance_view: ~azure.mgmt.hybridcompute.models.MachineExtensionInstanceView + """ + + _validation = { + 'provisioning_state': {'readonly': True}, + } + + _attribute_map = { + 'force_update_tag': {'key': 'forceUpdateTag', 'type': 'str'}, + 'publisher': {'key': 'publisher', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'type_handler_version': {'key': 'typeHandlerVersion', 'type': 'str'}, + 'enable_auto_upgrade': {'key': 'enableAutomaticUpgrade', 'type': 'bool'}, + 'auto_upgrade_minor_version': {'key': 'autoUpgradeMinorVersion', 'type': 'bool'}, + 'settings': {'key': 'settings', 'type': 'object'}, + 'protected_settings': {'key': 'protectedSettings', 'type': 'object'}, + 'provisioning_state': {'key': 'provisioningState', 'type': 'str'}, + 'instance_view': {'key': 'instanceView', 'type': 'MachineExtensionInstanceView'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineExtensionProperties, self).__init__(**kwargs) + self.force_update_tag = kwargs.get('force_update_tag', None) + self.publisher = kwargs.get('publisher', None) + self.type = kwargs.get('type', None) + self.type_handler_version = kwargs.get('type_handler_version', None) + self.enable_auto_upgrade = kwargs.get('enable_auto_upgrade', None) + self.auto_upgrade_minor_version = kwargs.get('auto_upgrade_minor_version', None) + self.settings = kwargs.get('settings', None) + self.protected_settings = kwargs.get('protected_settings', None) + self.provisioning_state = None + self.instance_view = kwargs.get('instance_view', None) + + +class MachineExtensionsListResult(msrest.serialization.Model): + """Describes the Machine Extensions List Result. + + :param value: The list of extensions. + :type value: list[~azure.mgmt.hybridcompute.models.MachineExtension] + :param next_link: The uri to fetch the next page of machine extensions. Call ListNext() with + this to fetch the next page of extensions. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[MachineExtension]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineExtensionsListResult, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class ResourceUpdate(msrest.serialization.Model): + """The Update Resource model definition. + + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + } + + def __init__( + self, + **kwargs + ): + super(ResourceUpdate, self).__init__(**kwargs) + self.tags = kwargs.get('tags', None) + + +class MachineExtensionUpdate(ResourceUpdate): + """Describes a Machine Extension Update. + + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param properties: Describes Machine Extension Update Properties. + :type properties: ~azure.mgmt.hybridcompute.models.MachineExtensionUpdateProperties + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + 'properties': {'key': 'properties', 'type': 'MachineExtensionUpdateProperties'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineExtensionUpdate, self).__init__(**kwargs) + self.properties = kwargs.get('properties', None) + + +class MachineExtensionUpdateProperties(msrest.serialization.Model): + """Describes the properties of a Machine Extension. + + :param force_update_tag: How the extension handler should be forced to update even if the + extension configuration has not changed. + :type force_update_tag: str + :param publisher: The name of the extension handler publisher. + :type publisher: str + :param type: Specifies the type of the extension; an example is "CustomScriptExtension". + :type type: str + :param type_handler_version: Specifies the version of the script handler. + :type type_handler_version: str + :param enable_auto_upgrade: Indicates whether the extension should be automatically + upgraded by the platform if there is a newer version available. + :type enable_auto_upgrade: bool + :param auto_upgrade_minor_version: Indicates whether the extension should use a newer minor + version if one is available at deployment time. Once deployed, however, the extension will not + upgrade minor versions unless redeployed, even with this property set to true. + :type auto_upgrade_minor_version: bool + :param settings: Json formatted public settings for the extension. + :type settings: object + :param protected_settings: The extension can contain either protectedSettings or + protectedSettingsFromKeyVault or no protected settings at all. + :type protected_settings: object + """ + + _attribute_map = { + 'force_update_tag': {'key': 'forceUpdateTag', 'type': 'str'}, + 'publisher': {'key': 'publisher', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'type_handler_version': {'key': 'typeHandlerVersion', 'type': 'str'}, + 'enable_auto_upgrade': {'key': 'enableAutomaticUpgrade', 'type': 'bool'}, + 'auto_upgrade_minor_version': {'key': 'autoUpgradeMinorVersion', 'type': 'bool'}, + 'settings': {'key': 'settings', 'type': 'object'}, + 'protected_settings': {'key': 'protectedSettings', 'type': 'object'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineExtensionUpdateProperties, self).__init__(**kwargs) + self.force_update_tag = kwargs.get('force_update_tag', None) + self.publisher = kwargs.get('publisher', None) + self.type = kwargs.get('type', None) + self.type_handler_version = kwargs.get('type_handler_version', None) + self.enable_auto_upgrade = kwargs.get('enable_auto_upgrade', None) + self.auto_upgrade_minor_version = kwargs.get('auto_upgrade_minor_version', None) + self.settings = kwargs.get('settings', None) + self.protected_settings = kwargs.get('protected_settings', None) + + +class MachineExtensionUpgrade(msrest.serialization.Model): + """Describes the Machine Extension Upgrade Properties. + + :param extension_targets: Describes the Extension Target Properties. + :type extension_targets: dict[str, ~azure.mgmt.hybridcompute.models.ExtensionTargetProperties] + """ + + _attribute_map = { + 'extension_targets': {'key': 'extensionTargets', 'type': '{ExtensionTargetProperties}'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineExtensionUpgrade, self).__init__(**kwargs) + self.extension_targets = kwargs.get('extension_targets', None) + + +class MachineListResult(msrest.serialization.Model): + """The List hybrid machine operation response. + + All required parameters must be populated in order to send to Azure. + + :param value: Required. The list of hybrid machines. + :type value: list[~azure.mgmt.hybridcompute.models.Machine] + :param next_link: The URI to fetch the next page of Machines. Call ListNext() with this URI to + fetch the next page of hybrid machines. + :type next_link: str + """ + + _validation = { + 'value': {'required': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Machine]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineListResult, self).__init__(**kwargs) + self.value = kwargs['value'] + self.next_link = kwargs.get('next_link', None) + + +class MachineProperties(msrest.serialization.Model): + """Describes the properties of a hybrid machine. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param location_data: Metadata pertaining to the geographic location of the resource. + :type location_data: ~azure.mgmt.hybridcompute.models.LocationData + :ivar os_profile: Specifies the operating system settings for the hybrid machine. + :vartype os_profile: ~azure.mgmt.hybridcompute.models.OsProfile + :ivar provisioning_state: The provisioning state, which only appears in the response. + :vartype provisioning_state: str + :ivar status: The status of the hybrid machine agent. Possible values include: "Connected", + "Disconnected", "Error". + :vartype status: str or ~azure.mgmt.hybridcompute.models.StatusTypes + :ivar last_status_change: The time of the last status change. + :vartype last_status_change: ~datetime.datetime + :ivar error_details: Details about the error state. + :vartype error_details: list[~azure.mgmt.hybridcompute.models.ErrorDetail] + :ivar agent_version: The hybrid machine agent full version. + :vartype agent_version: str + :param vm_id: Specifies the hybrid machine unique ID. + :type vm_id: str + :ivar display_name: Specifies the hybrid machine display name. + :vartype display_name: str + :ivar machine_fqdn: Specifies the hybrid machine FQDN. + :vartype machine_fqdn: str + :param client_public_key: Public Key that the client provides to be used during initial + resource onboarding. + :type client_public_key: str + :ivar os_name: The Operating System running on the hybrid machine. + :vartype os_name: str + :ivar os_version: The version of Operating System running on the hybrid machine. + :vartype os_version: str + :ivar vm_uuid: Specifies the Arc Machine's unique SMBIOS ID. + :vartype vm_uuid: str + :param extensions: Machine Extensions information. + :type extensions: list[~azure.mgmt.hybridcompute.models.MachineExtensionInstanceView] + :ivar os_sku: Specifies the Operating System product SKU. + :vartype os_sku: str + :ivar domain_name: Specifies the Windows domain name. + :vartype domain_name: str + :ivar ad_fqdn: Specifies the AD fully qualified display name. + :vartype ad_fqdn: str + :ivar dns_fqdn: Specifies the DNS fully qualified display name. + :vartype dns_fqdn: str + :param private_link_scope_resource_id: The resource id of the private link scope this machine + is assigned to, if any. + :type private_link_scope_resource_id: str + :param parent_cluster_resource_id: The resource id of the parent cluster (Azure HCI) this + machine is assigned to, if any. + :type parent_cluster_resource_id: str + :ivar detected_properties: Detected properties from the machine. + :vartype detected_properties: dict[str, str] + """ + + _validation = { + 'os_profile': {'readonly': True}, + 'provisioning_state': {'readonly': True}, + 'status': {'readonly': True}, + 'last_status_change': {'readonly': True}, + 'error_details': {'readonly': True}, + 'agent_version': {'readonly': True}, + 'display_name': {'readonly': True}, + 'machine_fqdn': {'readonly': True}, + 'os_name': {'readonly': True}, + 'os_version': {'readonly': True}, + 'vm_uuid': {'readonly': True}, + 'os_sku': {'readonly': True}, + 'domain_name': {'readonly': True}, + 'ad_fqdn': {'readonly': True}, + 'dns_fqdn': {'readonly': True}, + 'detected_properties': {'readonly': True}, + } + + _attribute_map = { + 'location_data': {'key': 'locationData', 'type': 'LocationData'}, + 'os_profile': {'key': 'osProfile', 'type': 'OsProfile'}, + 'provisioning_state': {'key': 'provisioningState', 'type': 'str'}, + 'status': {'key': 'status', 'type': 'str'}, + 'last_status_change': {'key': 'lastStatusChange', 'type': 'iso-8601'}, + 'error_details': {'key': 'errorDetails', 'type': '[ErrorDetail]'}, + 'agent_version': {'key': 'agentVersion', 'type': 'str'}, + 'vm_id': {'key': 'vmId', 'type': 'str'}, + 'display_name': {'key': 'displayName', 'type': 'str'}, + 'machine_fqdn': {'key': 'machineFqdn', 'type': 'str'}, + 'client_public_key': {'key': 'clientPublicKey', 'type': 'str'}, + 'os_name': {'key': 'osName', 'type': 'str'}, + 'os_version': {'key': 'osVersion', 'type': 'str'}, + 'vm_uuid': {'key': 'vmUuid', 'type': 'str'}, + 'extensions': {'key': 'extensions', 'type': '[MachineExtensionInstanceView]'}, + 'os_sku': {'key': 'osSku', 'type': 'str'}, + 'domain_name': {'key': 'domainName', 'type': 'str'}, + 'ad_fqdn': {'key': 'adFqdn', 'type': 'str'}, + 'dns_fqdn': {'key': 'dnsFqdn', 'type': 'str'}, + 'private_link_scope_resource_id': {'key': 'privateLinkScopeResourceId', 'type': 'str'}, + 'parent_cluster_resource_id': {'key': 'parentClusterResourceId', 'type': 'str'}, + 'detected_properties': {'key': 'detectedProperties', 'type': '{str}'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineProperties, self).__init__(**kwargs) + self.location_data = kwargs.get('location_data', None) + self.os_profile = None + self.provisioning_state = None + self.status = None + self.last_status_change = None + self.error_details = None + self.agent_version = None + self.vm_id = kwargs.get('vm_id', None) + self.display_name = None + self.machine_fqdn = None + self.client_public_key = kwargs.get('client_public_key', None) + self.os_name = None + self.os_version = None + self.vm_uuid = None + self.extensions = kwargs.get('extensions', None) + self.os_sku = None + self.domain_name = None + self.ad_fqdn = None + self.dns_fqdn = None + self.private_link_scope_resource_id = kwargs.get('private_link_scope_resource_id', None) + self.parent_cluster_resource_id = kwargs.get('parent_cluster_resource_id', None) + self.detected_properties = None + + +class MachineUpdate(ResourceUpdate): + """Describes a hybrid machine Update. + + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param identity: Identity for the resource. + :type identity: ~azure.mgmt.hybridcompute.models.Identity + :param properties: Hybrid Compute Machine properties. + :type properties: ~azure.mgmt.hybridcompute.models.MachineUpdateProperties + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + 'identity': {'key': 'identity', 'type': 'Identity'}, + 'properties': {'key': 'properties', 'type': 'MachineUpdateProperties'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineUpdate, self).__init__(**kwargs) + self.identity = kwargs.get('identity', None) + self.properties = kwargs.get('properties', None) + + +class MachineUpdateProperties(msrest.serialization.Model): + """Describes the ARM updatable properties of a hybrid machine. + + :param location_data: Metadata pertaining to the geographic location of the resource. + :type location_data: ~azure.mgmt.hybridcompute.models.LocationData + :param parent_cluster_resource_id: The resource id of the parent cluster (Azure HCI) this + machine is assigned to, if any. + :type parent_cluster_resource_id: str + :param private_link_scope_resource_id: The resource id of the private link scope this machine + is assigned to, if any. + :type private_link_scope_resource_id: str + """ + + _attribute_map = { + 'location_data': {'key': 'locationData', 'type': 'LocationData'}, + 'parent_cluster_resource_id': {'key': 'parentClusterResourceId', 'type': 'str'}, + 'private_link_scope_resource_id': {'key': 'privateLinkScopeResourceId', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(MachineUpdateProperties, self).__init__(**kwargs) + self.location_data = kwargs.get('location_data', None) + self.parent_cluster_resource_id = kwargs.get('parent_cluster_resource_id', None) + self.private_link_scope_resource_id = kwargs.get('private_link_scope_resource_id', None) + + +class OperationListResult(msrest.serialization.Model): + """The List Compute Operation operation response. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar value: The list of compute operations. + :vartype value: list[~azure.mgmt.hybridcompute.models.OperationValue] + """ + + _validation = { + 'value': {'readonly': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[OperationValue]'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationListResult, self).__init__(**kwargs) + self.value = None + + +class OperationValue(msrest.serialization.Model): + """Describes the properties of a Compute Operation value. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar origin: The origin of the compute operation. + :vartype origin: str + :ivar name: The name of the compute operation. + :vartype name: str + :param display: Display properties. + :type display: ~azure.mgmt.hybridcompute.models.OperationValueDisplay + """ + + _validation = { + 'origin': {'readonly': True}, + 'name': {'readonly': True}, + } + + _attribute_map = { + 'origin': {'key': 'origin', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'display': {'key': 'display', 'type': 'OperationValueDisplay'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationValue, self).__init__(**kwargs) + self.origin = None + self.name = None + self.display = kwargs.get('display', None) + + +class OperationValueDisplay(msrest.serialization.Model): + """Describes the properties of a Hybrid Compute Operation Value Display. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar operation: The display name of the compute operation. + :vartype operation: str + :ivar resource: The display name of the resource the operation applies to. + :vartype resource: str + :ivar description: The description of the operation. + :vartype description: str + :ivar provider: The resource provider for the operation. + :vartype provider: str + """ + + _validation = { + 'operation': {'readonly': True}, + 'resource': {'readonly': True}, + 'description': {'readonly': True}, + 'provider': {'readonly': True}, + } + + _attribute_map = { + 'operation': {'key': 'operation', 'type': 'str'}, + 'resource': {'key': 'resource', 'type': 'str'}, + 'description': {'key': 'description', 'type': 'str'}, + 'provider': {'key': 'provider', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationValueDisplay, self).__init__(**kwargs) + self.operation = None + self.resource = None + self.description = None + self.provider = None + + +class OsProfile(msrest.serialization.Model): + """Specifies the operating system settings for the hybrid machine. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar computer_name: Specifies the host OS name of the hybrid machine. + :vartype computer_name: str + """ + + _validation = { + 'computer_name': {'readonly': True}, + } + + _attribute_map = { + 'computer_name': {'key': 'computerName', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OsProfile, self).__init__(**kwargs) + self.computer_name = None + + +class PrivateEndpointConnection(Resource): + """A private endpoint connection. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param properties: Resource properties. + :type properties: ~azure.mgmt.hybridcompute.models.PrivateEndpointConnectionProperties + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'PrivateEndpointConnectionProperties'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateEndpointConnection, self).__init__(**kwargs) + self.properties = kwargs.get('properties', None) + self.system_data = None + + +class PrivateEndpointConnectionListResult(msrest.serialization.Model): + """A list of private endpoint connections. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar value: Array of results. + :vartype value: list[~azure.mgmt.hybridcompute.models.PrivateEndpointConnection] + :ivar next_link: Link to retrieve next page of results. + :vartype next_link: str + """ + + _validation = { + 'value': {'readonly': True}, + 'next_link': {'readonly': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[PrivateEndpointConnection]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateEndpointConnectionListResult, self).__init__(**kwargs) + self.value = None + self.next_link = None + + +class PrivateEndpointConnectionProperties(msrest.serialization.Model): + """Properties of a private endpoint connection. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param private_endpoint: Private endpoint which the connection belongs to. + :type private_endpoint: ~azure.mgmt.hybridcompute.models.PrivateEndpointProperty + :param private_link_service_connection_state: Connection state of the private endpoint + connection. + :type private_link_service_connection_state: + ~azure.mgmt.hybridcompute.models.PrivateLinkServiceConnectionStateProperty + :ivar provisioning_state: State of the private endpoint connection. + :vartype provisioning_state: str + """ + + _validation = { + 'provisioning_state': {'readonly': True}, + } + + _attribute_map = { + 'private_endpoint': {'key': 'privateEndpoint', 'type': 'PrivateEndpointProperty'}, + 'private_link_service_connection_state': {'key': 'privateLinkServiceConnectionState', 'type': 'PrivateLinkServiceConnectionStateProperty'}, + 'provisioning_state': {'key': 'provisioningState', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateEndpointConnectionProperties, self).__init__(**kwargs) + self.private_endpoint = kwargs.get('private_endpoint', None) + self.private_link_service_connection_state = kwargs.get('private_link_service_connection_state', None) + self.provisioning_state = None + + +class PrivateEndpointProperty(msrest.serialization.Model): + """Private endpoint which the connection belongs to. + + :param id: Resource id of the private endpoint. + :type id: str + """ + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateEndpointProperty, self).__init__(**kwargs) + self.id = kwargs.get('id', None) + + +class PrivateLinkResource(Resource): + """A private link resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param properties: Resource properties. + :type properties: ~azure.mgmt.hybridcompute.models.PrivateLinkResourceProperties + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'PrivateLinkResourceProperties'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateLinkResource, self).__init__(**kwargs) + self.properties = kwargs.get('properties', None) + self.system_data = None + + +class PrivateLinkResourceListResult(msrest.serialization.Model): + """A list of private link resources. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar value: Array of results. + :vartype value: list[~azure.mgmt.hybridcompute.models.PrivateLinkResource] + :ivar next_link: Link to retrieve next page of results. + :vartype next_link: str + """ + + _validation = { + 'value': {'readonly': True}, + 'next_link': {'readonly': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[PrivateLinkResource]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateLinkResourceListResult, self).__init__(**kwargs) + self.value = None + self.next_link = None + + +class PrivateLinkResourceProperties(msrest.serialization.Model): + """Properties of a private link resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar group_id: The private link resource group id. + :vartype group_id: str + :ivar required_members: The private link resource required member names. + :vartype required_members: list[str] + :ivar required_zone_names: Required DNS zone names of the the private link resource. + :vartype required_zone_names: list[str] + """ + + _validation = { + 'group_id': {'readonly': True}, + 'required_members': {'readonly': True}, + 'required_zone_names': {'readonly': True}, + } + + _attribute_map = { + 'group_id': {'key': 'groupId', 'type': 'str'}, + 'required_members': {'key': 'requiredMembers', 'type': '[str]'}, + 'required_zone_names': {'key': 'requiredZoneNames', 'type': '[str]'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateLinkResourceProperties, self).__init__(**kwargs) + self.group_id = None + self.required_members = None + self.required_zone_names = None + + +class PrivateLinkScopeValidationDetails(msrest.serialization.Model): + """PrivateLinkScopeValidationDetails. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Azure resource Id. + :vartype id: str + :param public_network_access: Indicates whether machines associated with the private link scope + can also use public Azure Arc service endpoints. Possible values include: "Enabled", + "Disabled". Default value: "Disabled". + :type public_network_access: str or ~azure.mgmt.hybridcompute.models.PublicNetworkAccessType + :param connection_details: List of Private Endpoint Connection details. + :type connection_details: list[~azure.mgmt.hybridcompute.models.ConnectionDetail] + """ + + _validation = { + 'id': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'public_network_access': {'key': 'publicNetworkAccess', 'type': 'str'}, + 'connection_details': {'key': 'connectionDetails', 'type': '[ConnectionDetail]'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateLinkScopeValidationDetails, self).__init__(**kwargs) + self.id = None + self.public_network_access = kwargs.get('public_network_access', "Disabled") + self.connection_details = kwargs.get('connection_details', None) + + +class PrivateLinkServiceConnectionStateProperty(msrest.serialization.Model): + """State of the private endpoint connection. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :param status: Required. The private link service connection status. + :type status: str + :param description: Required. The private link service connection description. + :type description: str + :ivar actions_required: The actions required for private link service connection. + :vartype actions_required: str + """ + + _validation = { + 'status': {'required': True}, + 'description': {'required': True}, + 'actions_required': {'readonly': True}, + } + + _attribute_map = { + 'status': {'key': 'status', 'type': 'str'}, + 'description': {'key': 'description', 'type': 'str'}, + 'actions_required': {'key': 'actionsRequired', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateLinkServiceConnectionStateProperty, self).__init__(**kwargs) + self.status = kwargs['status'] + self.description = kwargs['description'] + self.actions_required = None + + +class ProxyResource(Resource): + """The resource model definition for a Azure Resource Manager proxy resource. It will not have tags and a location. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(ProxyResource, self).__init__(**kwargs) + + +class SystemData(msrest.serialization.Model): + """Metadata pertaining to creation and last modification of the resource. + + :param created_by: The identity that created the resource. + :type created_by: str + :param created_by_type: The type of identity that created the resource. Possible values + include: "User", "Application", "ManagedIdentity", "Key". + :type created_by_type: str or ~azure.mgmt.hybridcompute.models.CreatedByType + :param created_at: The timestamp of resource creation (UTC). + :type created_at: ~datetime.datetime + :param last_modified_by: The identity that last modified the resource. + :type last_modified_by: str + :param last_modified_by_type: The type of identity that last modified the resource. Possible + values include: "User", "Application", "ManagedIdentity", "Key". + :type last_modified_by_type: str or ~azure.mgmt.hybridcompute.models.CreatedByType + :param last_modified_at: The timestamp of resource last modification (UTC). + :type last_modified_at: ~datetime.datetime + """ + + _attribute_map = { + 'created_by': {'key': 'createdBy', 'type': 'str'}, + 'created_by_type': {'key': 'createdByType', 'type': 'str'}, + 'created_at': {'key': 'createdAt', 'type': 'iso-8601'}, + 'last_modified_by': {'key': 'lastModifiedBy', 'type': 'str'}, + 'last_modified_by_type': {'key': 'lastModifiedByType', 'type': 'str'}, + 'last_modified_at': {'key': 'lastModifiedAt', 'type': 'iso-8601'}, + } + + def __init__( + self, + **kwargs + ): + super(SystemData, self).__init__(**kwargs) + self.created_by = kwargs.get('created_by', None) + self.created_by_type = kwargs.get('created_by_type', None) + self.created_at = kwargs.get('created_at', None) + self.last_modified_by = kwargs.get('last_modified_by', None) + self.last_modified_by_type = kwargs.get('last_modified_by_type', None) + self.last_modified_at = kwargs.get('last_modified_at', None) + + +class TagsResource(msrest.serialization.Model): + """A container holding only the Tags for a resource, allowing the user to update the tags on a PrivateLinkScope instance. + + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + } + + def __init__( + self, + **kwargs + ): + super(TagsResource, self).__init__(**kwargs) + self.tags = kwargs.get('tags', None) diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_models_py3.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_models_py3.py new file mode 100644 index 0000000000..53262b0d28 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/models/_models_py3.py @@ -0,0 +1,1723 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +import datetime +from typing import Dict, List, Optional, Union + +from azure.core.exceptions import HttpResponseError +import msrest.serialization + +from ._connected_machine_enums import * + + +class ConnectionDetail(msrest.serialization.Model): + """ConnectionDetail. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Azure resource Id. + :vartype id: str + :ivar private_ip_address: The private endpoint connection private ip address. + :vartype private_ip_address: str + :ivar link_identifier: The private endpoint connection link identifier. + :vartype link_identifier: str + :ivar group_id: The private endpoint connection group id. + :vartype group_id: str + :ivar member_name: The private endpoint connection member name. + :vartype member_name: str + """ + + _validation = { + 'id': {'readonly': True}, + 'private_ip_address': {'readonly': True}, + 'link_identifier': {'readonly': True}, + 'group_id': {'readonly': True}, + 'member_name': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'private_ip_address': {'key': 'privateIpAddress', 'type': 'str'}, + 'link_identifier': {'key': 'linkIdentifier', 'type': 'str'}, + 'group_id': {'key': 'groupId', 'type': 'str'}, + 'member_name': {'key': 'memberName', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(ConnectionDetail, self).__init__(**kwargs) + self.id = None + self.private_ip_address = None + self.link_identifier = None + self.group_id = None + self.member_name = None + + +class ErrorAdditionalInfo(msrest.serialization.Model): + """The resource management error additional info. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar type: The additional info type. + :vartype type: str + :ivar info: The additional info. + :vartype info: object + """ + + _validation = { + 'type': {'readonly': True}, + 'info': {'readonly': True}, + } + + _attribute_map = { + 'type': {'key': 'type', 'type': 'str'}, + 'info': {'key': 'info', 'type': 'object'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorAdditionalInfo, self).__init__(**kwargs) + self.type = None + self.info = None + + +class ErrorDetail(msrest.serialization.Model): + """The error detail. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar code: The error code. + :vartype code: str + :ivar message: The error message. + :vartype message: str + :ivar target: The error target. + :vartype target: str + :ivar details: The error details. + :vartype details: list[~azure.mgmt.hybridcompute.models.ErrorDetail] + :ivar additional_info: The error additional info. + :vartype additional_info: list[~azure.mgmt.hybridcompute.models.ErrorAdditionalInfo] + """ + + _validation = { + 'code': {'readonly': True}, + 'message': {'readonly': True}, + 'target': {'readonly': True}, + 'details': {'readonly': True}, + 'additional_info': {'readonly': True}, + } + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'target': {'key': 'target', 'type': 'str'}, + 'details': {'key': 'details', 'type': '[ErrorDetail]'}, + 'additional_info': {'key': 'additionalInfo', 'type': '[ErrorAdditionalInfo]'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorDetail, self).__init__(**kwargs) + self.code = None + self.message = None + self.target = None + self.details = None + self.additional_info = None + + +class ErrorResponse(msrest.serialization.Model): + """Common error response for all Azure Resource Manager APIs to return error details for failed operations. (This also follows the OData error response format.). + + :param error: The error object. + :type error: ~azure.mgmt.hybridcompute.models.ErrorDetail + """ + + _attribute_map = { + 'error': {'key': 'error', 'type': 'ErrorDetail'}, + } + + def __init__( + self, + *, + error: Optional["ErrorDetail"] = None, + **kwargs + ): + super(ErrorResponse, self).__init__(**kwargs) + self.error = error + + +class ExtensionTargetProperties(msrest.serialization.Model): + """Describes the Machine Extension Target Version Properties. + + :param target_version: Properties for the specified Extension to Upgrade. + :type target_version: str + """ + + _attribute_map = { + 'target_version': {'key': 'targetVersion', 'type': 'str'}, + } + + def __init__( + self, + *, + target_version: Optional[str] = None, + **kwargs + ): + super(ExtensionTargetProperties, self).__init__(**kwargs) + self.target_version = target_version + + +class PrivateLinkScopesResource(msrest.serialization.Model): + """An azure resource object. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Azure resource Id. + :vartype id: str + :ivar name: Azure resource name. + :vartype name: str + :ivar type: Azure resource type. + :vartype type: str + :param location: Required. Resource location. + :type location: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'location': {'key': 'location', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + } + + def __init__( + self, + *, + location: str, + tags: Optional[Dict[str, str]] = None, + **kwargs + ): + super(PrivateLinkScopesResource, self).__init__(**kwargs) + self.id = None + self.name = None + self.type = None + self.location = location + self.tags = tags + + +class HybridComputePrivateLinkScope(PrivateLinkScopesResource): + """An Azure Arc PrivateLinkScope definition. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Azure resource Id. + :vartype id: str + :ivar name: Azure resource name. + :vartype name: str + :ivar type: Azure resource type. + :vartype type: str + :param location: Required. Resource location. + :type location: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param properties: Properties that define a Azure Arc PrivateLinkScope resource. + :type properties: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScopeProperties + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'location': {'key': 'location', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'properties': {'key': 'properties', 'type': 'HybridComputePrivateLinkScopeProperties'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + *, + location: str, + tags: Optional[Dict[str, str]] = None, + properties: Optional["HybridComputePrivateLinkScopeProperties"] = None, + **kwargs + ): + super(HybridComputePrivateLinkScope, self).__init__(location=location, tags=tags, **kwargs) + self.properties = properties + self.system_data = None + + +class HybridComputePrivateLinkScopeListResult(msrest.serialization.Model): + """Describes the list of Azure Arc PrivateLinkScope resources. + + All required parameters must be populated in order to send to Azure. + + :param value: Required. List of Azure Arc PrivateLinkScope definitions. + :type value: list[~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope] + :param next_link: The URI to get the next set of Azure Arc PrivateLinkScope definitions if too + many PrivateLinkScopes where returned in the result set. + :type next_link: str + """ + + _validation = { + 'value': {'required': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[HybridComputePrivateLinkScope]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: List["HybridComputePrivateLinkScope"], + next_link: Optional[str] = None, + **kwargs + ): + super(HybridComputePrivateLinkScopeListResult, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class HybridComputePrivateLinkScopeProperties(msrest.serialization.Model): + """Properties that define a Azure Arc PrivateLinkScope resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param public_network_access: Indicates whether machines associated with the private link scope + can also use public Azure Arc service endpoints. Possible values include: "Enabled", + "Disabled". Default value: "Disabled". + :type public_network_access: str or ~azure.mgmt.hybridcompute.models.PublicNetworkAccessType + :ivar provisioning_state: Current state of this PrivateLinkScope: whether or not is has been + provisioned within the resource group it is defined. Users cannot change this value but are + able to read from it. Values will include Provisioning ,Succeeded, Canceled and Failed. + :vartype provisioning_state: str + :ivar private_link_scope_id: The Guid id of the private link scope. + :vartype private_link_scope_id: str + """ + + _validation = { + 'provisioning_state': {'readonly': True}, + 'private_link_scope_id': {'readonly': True}, + } + + _attribute_map = { + 'public_network_access': {'key': 'publicNetworkAccess', 'type': 'str'}, + 'provisioning_state': {'key': 'provisioningState', 'type': 'str'}, + 'private_link_scope_id': {'key': 'privateLinkScopeId', 'type': 'str'}, + } + + def __init__( + self, + *, + public_network_access: Optional[Union[str, "PublicNetworkAccessType"]] = "Disabled", + **kwargs + ): + super(HybridComputePrivateLinkScopeProperties, self).__init__(**kwargs) + self.public_network_access = public_network_access + self.provisioning_state = None + self.private_link_scope_id = None + + +class Identity(msrest.serialization.Model): + """Identity for the resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar principal_id: The principal ID of resource identity. + :vartype principal_id: str + :ivar tenant_id: The tenant ID of resource. + :vartype tenant_id: str + :ivar type: The identity type. Default value: "SystemAssigned". + :vartype type: str + """ + + _validation = { + 'principal_id': {'readonly': True}, + 'tenant_id': {'readonly': True}, + 'type': {'constant': True}, + } + + _attribute_map = { + 'principal_id': {'key': 'principalId', 'type': 'str'}, + 'tenant_id': {'key': 'tenantId', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + type = "SystemAssigned" + + def __init__( + self, + **kwargs + ): + super(Identity, self).__init__(**kwargs) + self.principal_id = None + self.tenant_id = None + + +class LocationData(msrest.serialization.Model): + """Metadata pertaining to the geographic location of the resource. + + All required parameters must be populated in order to send to Azure. + + :param name: Required. A canonical name for the geographic or physical location. + :type name: str + :param city: The city or locality where the resource is located. + :type city: str + :param district: The district, state, or province where the resource is located. + :type district: str + :param country_or_region: The country or region where the resource is located. + :type country_or_region: str + """ + + _validation = { + 'name': {'required': True, 'max_length': 256, 'min_length': 0}, + } + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'city': {'key': 'city', 'type': 'str'}, + 'district': {'key': 'district', 'type': 'str'}, + 'country_or_region': {'key': 'countryOrRegion', 'type': 'str'}, + } + + def __init__( + self, + *, + name: str, + city: Optional[str] = None, + district: Optional[str] = None, + country_or_region: Optional[str] = None, + **kwargs + ): + super(LocationData, self).__init__(**kwargs) + self.name = name + self.city = city + self.district = district + self.country_or_region = country_or_region + + +class Resource(msrest.serialization.Model): + """Common fields that are returned in the response for all Azure Resource Manager resources. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Resource, self).__init__(**kwargs) + self.id = None + self.name = None + self.type = None + + +class TrackedResource(Resource): + """The resource model definition for an Azure Resource Manager tracked top level resource which has 'tags' and a 'location'. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param location: Required. The geo-location where the resource lives. + :type location: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'location': {'key': 'location', 'type': 'str'}, + } + + def __init__( + self, + *, + location: str, + tags: Optional[Dict[str, str]] = None, + **kwargs + ): + super(TrackedResource, self).__init__(**kwargs) + self.tags = tags + self.location = location + + +class Machine(TrackedResource): + """Describes a hybrid machine. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param location: Required. The geo-location where the resource lives. + :type location: str + :param properties: Hybrid Compute Machine properties. + :type properties: ~azure.mgmt.hybridcompute.models.MachineProperties + :param identity: Identity for the resource. + :type identity: ~azure.mgmt.hybridcompute.models.Identity + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'location': {'key': 'location', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'MachineProperties'}, + 'identity': {'key': 'identity', 'type': 'Identity'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + *, + location: str, + tags: Optional[Dict[str, str]] = None, + properties: Optional["MachineProperties"] = None, + identity: Optional["Identity"] = None, + **kwargs + ): + super(Machine, self).__init__(tags=tags, location=location, **kwargs) + self.properties = properties + self.identity = identity + self.system_data = None + + +class MachineExtension(TrackedResource): + """Describes a Machine Extension. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param location: Required. The geo-location where the resource lives. + :type location: str + :param properties: Describes Machine Extension Properties. + :type properties: ~azure.mgmt.hybridcompute.models.MachineExtensionProperties + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'location': {'required': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'location': {'key': 'location', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'MachineExtensionProperties'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + *, + location: str, + tags: Optional[Dict[str, str]] = None, + properties: Optional["MachineExtensionProperties"] = None, + **kwargs + ): + super(MachineExtension, self).__init__(tags=tags, location=location, **kwargs) + self.properties = properties + self.system_data = None + + +class MachineExtensionInstanceView(msrest.serialization.Model): + """Describes the Machine Extension Instance View. + + :param name: The machine extension name. + :type name: str + :param type: Specifies the type of the extension; an example is "CustomScriptExtension". + :type type: str + :param type_handler_version: Specifies the version of the script handler. + :type type_handler_version: str + :param status: Instance view status. + :type status: ~azure.mgmt.hybridcompute.models.MachineExtensionInstanceViewStatus + """ + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'type_handler_version': {'key': 'typeHandlerVersion', 'type': 'str'}, + 'status': {'key': 'status', 'type': 'MachineExtensionInstanceViewStatus'}, + } + + def __init__( + self, + *, + name: Optional[str] = None, + type: Optional[str] = None, + type_handler_version: Optional[str] = None, + status: Optional["MachineExtensionInstanceViewStatus"] = None, + **kwargs + ): + super(MachineExtensionInstanceView, self).__init__(**kwargs) + self.name = name + self.type = type + self.type_handler_version = type_handler_version + self.status = status + + +class MachineExtensionInstanceViewStatus(msrest.serialization.Model): + """Instance view status. + + :param code: The status code. + :type code: str + :param level: The level code. Possible values include: "Info", "Warning", "Error". + :type level: str or ~azure.mgmt.hybridcompute.models.StatusLevelTypes + :param display_status: The short localizable label for the status. + :type display_status: str + :param message: The detailed status message, including for alerts and error messages. + :type message: str + :param time: The time of the status. + :type time: ~datetime.datetime + """ + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'level': {'key': 'level', 'type': 'str'}, + 'display_status': {'key': 'displayStatus', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'time': {'key': 'time', 'type': 'iso-8601'}, + } + + def __init__( + self, + *, + code: Optional[str] = None, + level: Optional[Union[str, "StatusLevelTypes"]] = None, + display_status: Optional[str] = None, + message: Optional[str] = None, + time: Optional[datetime.datetime] = None, + **kwargs + ): + super(MachineExtensionInstanceViewStatus, self).__init__(**kwargs) + self.code = code + self.level = level + self.display_status = display_status + self.message = message + self.time = time + + +class MachineExtensionProperties(msrest.serialization.Model): + """Describes the properties of a Machine Extension. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param force_update_tag: How the extension handler should be forced to update even if the + extension configuration has not changed. + :type force_update_tag: str + :param publisher: The name of the extension handler publisher. + :type publisher: str + :param type: Specifies the type of the extension; an example is "CustomScriptExtension". + :type type: str + :param type_handler_version: Specifies the version of the script handler. + :type type_handler_version: str + :param enable_auto_upgrade: Indicates whether the extension should be automatically + upgraded by the platform if there is a newer version available. + :type enable_auto_upgrade: bool + :param auto_upgrade_minor_version: Indicates whether the extension should use a newer minor + version if one is available at deployment time. Once deployed, however, the extension will not + upgrade minor versions unless redeployed, even with this property set to true. + :type auto_upgrade_minor_version: bool + :param settings: Json formatted public settings for the extension. + :type settings: object + :param protected_settings: The extension can contain either protectedSettings or + protectedSettingsFromKeyVault or no protected settings at all. + :type protected_settings: object + :ivar provisioning_state: The provisioning state, which only appears in the response. + :vartype provisioning_state: str + :param instance_view: The machine extension instance view. + :type instance_view: ~azure.mgmt.hybridcompute.models.MachineExtensionInstanceView + """ + + _validation = { + 'provisioning_state': {'readonly': True}, + } + + _attribute_map = { + 'force_update_tag': {'key': 'forceUpdateTag', 'type': 'str'}, + 'publisher': {'key': 'publisher', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'type_handler_version': {'key': 'typeHandlerVersion', 'type': 'str'}, + 'enable_auto_upgrade': {'key': 'enableAutomaticUpgrade', 'type': 'bool'}, + 'auto_upgrade_minor_version': {'key': 'autoUpgradeMinorVersion', 'type': 'bool'}, + 'settings': {'key': 'settings', 'type': 'object'}, + 'protected_settings': {'key': 'protectedSettings', 'type': 'object'}, + 'provisioning_state': {'key': 'provisioningState', 'type': 'str'}, + 'instance_view': {'key': 'instanceView', 'type': 'MachineExtensionInstanceView'}, + } + + def __init__( + self, + *, + force_update_tag: Optional[str] = None, + publisher: Optional[str] = None, + type: Optional[str] = None, + type_handler_version: Optional[str] = None, + enable_auto_upgrade: Optional[bool] = None, + auto_upgrade_minor_version: Optional[bool] = None, + settings: Optional[object] = None, + protected_settings: Optional[object] = None, + instance_view: Optional["MachineExtensionInstanceView"] = None, + **kwargs + ): + super(MachineExtensionProperties, self).__init__(**kwargs) + self.force_update_tag = force_update_tag + self.publisher = publisher + self.type = type + self.type_handler_version = type_handler_version + self.enable_auto_upgrade = enable_auto_upgrade + self.auto_upgrade_minor_version = auto_upgrade_minor_version + self.settings = settings + self.protected_settings = protected_settings + self.provisioning_state = None + self.instance_view = instance_view + + +class MachineExtensionsListResult(msrest.serialization.Model): + """Describes the Machine Extensions List Result. + + :param value: The list of extensions. + :type value: list[~azure.mgmt.hybridcompute.models.MachineExtension] + :param next_link: The uri to fetch the next page of machine extensions. Call ListNext() with + this to fetch the next page of extensions. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[MachineExtension]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["MachineExtension"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(MachineExtensionsListResult, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class ResourceUpdate(msrest.serialization.Model): + """The Update Resource model definition. + + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + } + + def __init__( + self, + *, + tags: Optional[Dict[str, str]] = None, + **kwargs + ): + super(ResourceUpdate, self).__init__(**kwargs) + self.tags = tags + + +class MachineExtensionUpdate(ResourceUpdate): + """Describes a Machine Extension Update. + + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param properties: Describes Machine Extension Update Properties. + :type properties: ~azure.mgmt.hybridcompute.models.MachineExtensionUpdateProperties + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + 'properties': {'key': 'properties', 'type': 'MachineExtensionUpdateProperties'}, + } + + def __init__( + self, + *, + tags: Optional[Dict[str, str]] = None, + properties: Optional["MachineExtensionUpdateProperties"] = None, + **kwargs + ): + super(MachineExtensionUpdate, self).__init__(tags=tags, **kwargs) + self.properties = properties + + +class MachineExtensionUpdateProperties(msrest.serialization.Model): + """Describes the properties of a Machine Extension. + + :param force_update_tag: How the extension handler should be forced to update even if the + extension configuration has not changed. + :type force_update_tag: str + :param publisher: The name of the extension handler publisher. + :type publisher: str + :param type: Specifies the type of the extension; an example is "CustomScriptExtension". + :type type: str + :param type_handler_version: Specifies the version of the script handler. + :type type_handler_version: str + :param enable_auto_upgrade: Indicates whether the extension should be automatically + upgraded by the platform if there is a newer version available. + :type enable_auto_upgrade: bool + :param auto_upgrade_minor_version: Indicates whether the extension should use a newer minor + version if one is available at deployment time. Once deployed, however, the extension will not + upgrade minor versions unless redeployed, even with this property set to true. + :type auto_upgrade_minor_version: bool + :param settings: Json formatted public settings for the extension. + :type settings: object + :param protected_settings: The extension can contain either protectedSettings or + protectedSettingsFromKeyVault or no protected settings at all. + :type protected_settings: object + """ + + _attribute_map = { + 'force_update_tag': {'key': 'forceUpdateTag', 'type': 'str'}, + 'publisher': {'key': 'publisher', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'type_handler_version': {'key': 'typeHandlerVersion', 'type': 'str'}, + 'enable_auto_upgrade': {'key': 'enableAutomaticUpgrade', 'type': 'bool'}, + 'auto_upgrade_minor_version': {'key': 'autoUpgradeMinorVersion', 'type': 'bool'}, + 'settings': {'key': 'settings', 'type': 'object'}, + 'protected_settings': {'key': 'protectedSettings', 'type': 'object'}, + } + + def __init__( + self, + *, + force_update_tag: Optional[str] = None, + publisher: Optional[str] = None, + type: Optional[str] = None, + type_handler_version: Optional[str] = None, + enable_auto_upgrade: Optional[bool] = None, + auto_upgrade_minor_version: Optional[bool] = None, + settings: Optional[object] = None, + protected_settings: Optional[object] = None, + **kwargs + ): + super(MachineExtensionUpdateProperties, self).__init__(**kwargs) + self.force_update_tag = force_update_tag + self.publisher = publisher + self.type = type + self.type_handler_version = type_handler_version + self.enable_auto_upgrade = enable_auto_upgrade + self.auto_upgrade_minor_version = auto_upgrade_minor_version + self.settings = settings + self.protected_settings = protected_settings + + +class MachineExtensionUpgrade(msrest.serialization.Model): + """Describes the Machine Extension Upgrade Properties. + + :param extension_targets: Describes the Extension Target Properties. + :type extension_targets: dict[str, ~azure.mgmt.hybridcompute.models.ExtensionTargetProperties] + """ + + _attribute_map = { + 'extension_targets': {'key': 'extensionTargets', 'type': '{ExtensionTargetProperties}'}, + } + + def __init__( + self, + *, + extension_targets: Optional[Dict[str, "ExtensionTargetProperties"]] = None, + **kwargs + ): + super(MachineExtensionUpgrade, self).__init__(**kwargs) + self.extension_targets = extension_targets + + +class MachineListResult(msrest.serialization.Model): + """The List hybrid machine operation response. + + All required parameters must be populated in order to send to Azure. + + :param value: Required. The list of hybrid machines. + :type value: list[~azure.mgmt.hybridcompute.models.Machine] + :param next_link: The URI to fetch the next page of Machines. Call ListNext() with this URI to + fetch the next page of hybrid machines. + :type next_link: str + """ + + _validation = { + 'value': {'required': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Machine]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: List["Machine"], + next_link: Optional[str] = None, + **kwargs + ): + super(MachineListResult, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class MachineProperties(msrest.serialization.Model): + """Describes the properties of a hybrid machine. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param location_data: Metadata pertaining to the geographic location of the resource. + :type location_data: ~azure.mgmt.hybridcompute.models.LocationData + :ivar os_profile: Specifies the operating system settings for the hybrid machine. + :vartype os_profile: ~azure.mgmt.hybridcompute.models.OsProfile + :ivar provisioning_state: The provisioning state, which only appears in the response. + :vartype provisioning_state: str + :ivar status: The status of the hybrid machine agent. Possible values include: "Connected", + "Disconnected", "Error". + :vartype status: str or ~azure.mgmt.hybridcompute.models.StatusTypes + :ivar last_status_change: The time of the last status change. + :vartype last_status_change: ~datetime.datetime + :ivar error_details: Details about the error state. + :vartype error_details: list[~azure.mgmt.hybridcompute.models.ErrorDetail] + :ivar agent_version: The hybrid machine agent full version. + :vartype agent_version: str + :param vm_id: Specifies the hybrid machine unique ID. + :type vm_id: str + :ivar display_name: Specifies the hybrid machine display name. + :vartype display_name: str + :ivar machine_fqdn: Specifies the hybrid machine FQDN. + :vartype machine_fqdn: str + :param client_public_key: Public Key that the client provides to be used during initial + resource onboarding. + :type client_public_key: str + :ivar os_name: The Operating System running on the hybrid machine. + :vartype os_name: str + :ivar os_version: The version of Operating System running on the hybrid machine. + :vartype os_version: str + :ivar vm_uuid: Specifies the Arc Machine's unique SMBIOS ID. + :vartype vm_uuid: str + :param extensions: Machine Extensions information. + :type extensions: list[~azure.mgmt.hybridcompute.models.MachineExtensionInstanceView] + :ivar os_sku: Specifies the Operating System product SKU. + :vartype os_sku: str + :ivar domain_name: Specifies the Windows domain name. + :vartype domain_name: str + :ivar ad_fqdn: Specifies the AD fully qualified display name. + :vartype ad_fqdn: str + :ivar dns_fqdn: Specifies the DNS fully qualified display name. + :vartype dns_fqdn: str + :param private_link_scope_resource_id: The resource id of the private link scope this machine + is assigned to, if any. + :type private_link_scope_resource_id: str + :param parent_cluster_resource_id: The resource id of the parent cluster (Azure HCI) this + machine is assigned to, if any. + :type parent_cluster_resource_id: str + :ivar detected_properties: Detected properties from the machine. + :vartype detected_properties: dict[str, str] + """ + + _validation = { + 'os_profile': {'readonly': True}, + 'provisioning_state': {'readonly': True}, + 'status': {'readonly': True}, + 'last_status_change': {'readonly': True}, + 'error_details': {'readonly': True}, + 'agent_version': {'readonly': True}, + 'display_name': {'readonly': True}, + 'machine_fqdn': {'readonly': True}, + 'os_name': {'readonly': True}, + 'os_version': {'readonly': True}, + 'vm_uuid': {'readonly': True}, + 'os_sku': {'readonly': True}, + 'domain_name': {'readonly': True}, + 'ad_fqdn': {'readonly': True}, + 'dns_fqdn': {'readonly': True}, + 'detected_properties': {'readonly': True}, + } + + _attribute_map = { + 'location_data': {'key': 'locationData', 'type': 'LocationData'}, + 'os_profile': {'key': 'osProfile', 'type': 'OsProfile'}, + 'provisioning_state': {'key': 'provisioningState', 'type': 'str'}, + 'status': {'key': 'status', 'type': 'str'}, + 'last_status_change': {'key': 'lastStatusChange', 'type': 'iso-8601'}, + 'error_details': {'key': 'errorDetails', 'type': '[ErrorDetail]'}, + 'agent_version': {'key': 'agentVersion', 'type': 'str'}, + 'vm_id': {'key': 'vmId', 'type': 'str'}, + 'display_name': {'key': 'displayName', 'type': 'str'}, + 'machine_fqdn': {'key': 'machineFqdn', 'type': 'str'}, + 'client_public_key': {'key': 'clientPublicKey', 'type': 'str'}, + 'os_name': {'key': 'osName', 'type': 'str'}, + 'os_version': {'key': 'osVersion', 'type': 'str'}, + 'vm_uuid': {'key': 'vmUuid', 'type': 'str'}, + 'extensions': {'key': 'extensions', 'type': '[MachineExtensionInstanceView]'}, + 'os_sku': {'key': 'osSku', 'type': 'str'}, + 'domain_name': {'key': 'domainName', 'type': 'str'}, + 'ad_fqdn': {'key': 'adFqdn', 'type': 'str'}, + 'dns_fqdn': {'key': 'dnsFqdn', 'type': 'str'}, + 'private_link_scope_resource_id': {'key': 'privateLinkScopeResourceId', 'type': 'str'}, + 'parent_cluster_resource_id': {'key': 'parentClusterResourceId', 'type': 'str'}, + 'detected_properties': {'key': 'detectedProperties', 'type': '{str}'}, + } + + def __init__( + self, + *, + location_data: Optional["LocationData"] = None, + vm_id: Optional[str] = None, + client_public_key: Optional[str] = None, + extensions: Optional[List["MachineExtensionInstanceView"]] = None, + private_link_scope_resource_id: Optional[str] = None, + parent_cluster_resource_id: Optional[str] = None, + **kwargs + ): + super(MachineProperties, self).__init__(**kwargs) + self.location_data = location_data + self.os_profile = None + self.provisioning_state = None + self.status = None + self.last_status_change = None + self.error_details = None + self.agent_version = None + self.vm_id = vm_id + self.display_name = None + self.machine_fqdn = None + self.client_public_key = client_public_key + self.os_name = None + self.os_version = None + self.vm_uuid = None + self.extensions = extensions + self.os_sku = None + self.domain_name = None + self.ad_fqdn = None + self.dns_fqdn = None + self.private_link_scope_resource_id = private_link_scope_resource_id + self.parent_cluster_resource_id = parent_cluster_resource_id + self.detected_properties = None + + +class MachineUpdate(ResourceUpdate): + """Describes a hybrid machine Update. + + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + :param identity: Identity for the resource. + :type identity: ~azure.mgmt.hybridcompute.models.Identity + :param properties: Hybrid Compute Machine properties. + :type properties: ~azure.mgmt.hybridcompute.models.MachineUpdateProperties + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + 'identity': {'key': 'identity', 'type': 'Identity'}, + 'properties': {'key': 'properties', 'type': 'MachineUpdateProperties'}, + } + + def __init__( + self, + *, + tags: Optional[Dict[str, str]] = None, + identity: Optional["Identity"] = None, + properties: Optional["MachineUpdateProperties"] = None, + **kwargs + ): + super(MachineUpdate, self).__init__(tags=tags, **kwargs) + self.identity = identity + self.properties = properties + + +class MachineUpdateProperties(msrest.serialization.Model): + """Describes the ARM updatable properties of a hybrid machine. + + :param location_data: Metadata pertaining to the geographic location of the resource. + :type location_data: ~azure.mgmt.hybridcompute.models.LocationData + :param parent_cluster_resource_id: The resource id of the parent cluster (Azure HCI) this + machine is assigned to, if any. + :type parent_cluster_resource_id: str + :param private_link_scope_resource_id: The resource id of the private link scope this machine + is assigned to, if any. + :type private_link_scope_resource_id: str + """ + + _attribute_map = { + 'location_data': {'key': 'locationData', 'type': 'LocationData'}, + 'parent_cluster_resource_id': {'key': 'parentClusterResourceId', 'type': 'str'}, + 'private_link_scope_resource_id': {'key': 'privateLinkScopeResourceId', 'type': 'str'}, + } + + def __init__( + self, + *, + location_data: Optional["LocationData"] = None, + parent_cluster_resource_id: Optional[str] = None, + private_link_scope_resource_id: Optional[str] = None, + **kwargs + ): + super(MachineUpdateProperties, self).__init__(**kwargs) + self.location_data = location_data + self.parent_cluster_resource_id = parent_cluster_resource_id + self.private_link_scope_resource_id = private_link_scope_resource_id + + +class OperationListResult(msrest.serialization.Model): + """The List Compute Operation operation response. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar value: The list of compute operations. + :vartype value: list[~azure.mgmt.hybridcompute.models.OperationValue] + """ + + _validation = { + 'value': {'readonly': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[OperationValue]'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationListResult, self).__init__(**kwargs) + self.value = None + + +class OperationValue(msrest.serialization.Model): + """Describes the properties of a Compute Operation value. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar origin: The origin of the compute operation. + :vartype origin: str + :ivar name: The name of the compute operation. + :vartype name: str + :param display: Display properties. + :type display: ~azure.mgmt.hybridcompute.models.OperationValueDisplay + """ + + _validation = { + 'origin': {'readonly': True}, + 'name': {'readonly': True}, + } + + _attribute_map = { + 'origin': {'key': 'origin', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'display': {'key': 'display', 'type': 'OperationValueDisplay'}, + } + + def __init__( + self, + *, + display: Optional["OperationValueDisplay"] = None, + **kwargs + ): + super(OperationValue, self).__init__(**kwargs) + self.origin = None + self.name = None + self.display = display + + +class OperationValueDisplay(msrest.serialization.Model): + """Describes the properties of a Hybrid Compute Operation Value Display. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar operation: The display name of the compute operation. + :vartype operation: str + :ivar resource: The display name of the resource the operation applies to. + :vartype resource: str + :ivar description: The description of the operation. + :vartype description: str + :ivar provider: The resource provider for the operation. + :vartype provider: str + """ + + _validation = { + 'operation': {'readonly': True}, + 'resource': {'readonly': True}, + 'description': {'readonly': True}, + 'provider': {'readonly': True}, + } + + _attribute_map = { + 'operation': {'key': 'operation', 'type': 'str'}, + 'resource': {'key': 'resource', 'type': 'str'}, + 'description': {'key': 'description', 'type': 'str'}, + 'provider': {'key': 'provider', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationValueDisplay, self).__init__(**kwargs) + self.operation = None + self.resource = None + self.description = None + self.provider = None + + +class OsProfile(msrest.serialization.Model): + """Specifies the operating system settings for the hybrid machine. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar computer_name: Specifies the host OS name of the hybrid machine. + :vartype computer_name: str + """ + + _validation = { + 'computer_name': {'readonly': True}, + } + + _attribute_map = { + 'computer_name': {'key': 'computerName', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OsProfile, self).__init__(**kwargs) + self.computer_name = None + + +class PrivateEndpointConnection(Resource): + """A private endpoint connection. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param properties: Resource properties. + :type properties: ~azure.mgmt.hybridcompute.models.PrivateEndpointConnectionProperties + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'PrivateEndpointConnectionProperties'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + *, + properties: Optional["PrivateEndpointConnectionProperties"] = None, + **kwargs + ): + super(PrivateEndpointConnection, self).__init__(**kwargs) + self.properties = properties + self.system_data = None + + +class PrivateEndpointConnectionListResult(msrest.serialization.Model): + """A list of private endpoint connections. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar value: Array of results. + :vartype value: list[~azure.mgmt.hybridcompute.models.PrivateEndpointConnection] + :ivar next_link: Link to retrieve next page of results. + :vartype next_link: str + """ + + _validation = { + 'value': {'readonly': True}, + 'next_link': {'readonly': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[PrivateEndpointConnection]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateEndpointConnectionListResult, self).__init__(**kwargs) + self.value = None + self.next_link = None + + +class PrivateEndpointConnectionProperties(msrest.serialization.Model): + """Properties of a private endpoint connection. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param private_endpoint: Private endpoint which the connection belongs to. + :type private_endpoint: ~azure.mgmt.hybridcompute.models.PrivateEndpointProperty + :param private_link_service_connection_state: Connection state of the private endpoint + connection. + :type private_link_service_connection_state: + ~azure.mgmt.hybridcompute.models.PrivateLinkServiceConnectionStateProperty + :ivar provisioning_state: State of the private endpoint connection. + :vartype provisioning_state: str + """ + + _validation = { + 'provisioning_state': {'readonly': True}, + } + + _attribute_map = { + 'private_endpoint': {'key': 'privateEndpoint', 'type': 'PrivateEndpointProperty'}, + 'private_link_service_connection_state': {'key': 'privateLinkServiceConnectionState', 'type': 'PrivateLinkServiceConnectionStateProperty'}, + 'provisioning_state': {'key': 'provisioningState', 'type': 'str'}, + } + + def __init__( + self, + *, + private_endpoint: Optional["PrivateEndpointProperty"] = None, + private_link_service_connection_state: Optional["PrivateLinkServiceConnectionStateProperty"] = None, + **kwargs + ): + super(PrivateEndpointConnectionProperties, self).__init__(**kwargs) + self.private_endpoint = private_endpoint + self.private_link_service_connection_state = private_link_service_connection_state + self.provisioning_state = None + + +class PrivateEndpointProperty(msrest.serialization.Model): + """Private endpoint which the connection belongs to. + + :param id: Resource id of the private endpoint. + :type id: str + """ + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + } + + def __init__( + self, + *, + id: Optional[str] = None, + **kwargs + ): + super(PrivateEndpointProperty, self).__init__(**kwargs) + self.id = id + + +class PrivateLinkResource(Resource): + """A private link resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param properties: Resource properties. + :type properties: ~azure.mgmt.hybridcompute.models.PrivateLinkResourceProperties + :ivar system_data: The system meta data relating to this resource. + :vartype system_data: ~azure.mgmt.hybridcompute.models.SystemData + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'system_data': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'PrivateLinkResourceProperties'}, + 'system_data': {'key': 'systemData', 'type': 'SystemData'}, + } + + def __init__( + self, + *, + properties: Optional["PrivateLinkResourceProperties"] = None, + **kwargs + ): + super(PrivateLinkResource, self).__init__(**kwargs) + self.properties = properties + self.system_data = None + + +class PrivateLinkResourceListResult(msrest.serialization.Model): + """A list of private link resources. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar value: Array of results. + :vartype value: list[~azure.mgmt.hybridcompute.models.PrivateLinkResource] + :ivar next_link: Link to retrieve next page of results. + :vartype next_link: str + """ + + _validation = { + 'value': {'readonly': True}, + 'next_link': {'readonly': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[PrivateLinkResource]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateLinkResourceListResult, self).__init__(**kwargs) + self.value = None + self.next_link = None + + +class PrivateLinkResourceProperties(msrest.serialization.Model): + """Properties of a private link resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar group_id: The private link resource group id. + :vartype group_id: str + :ivar required_members: The private link resource required member names. + :vartype required_members: list[str] + :ivar required_zone_names: Required DNS zone names of the the private link resource. + :vartype required_zone_names: list[str] + """ + + _validation = { + 'group_id': {'readonly': True}, + 'required_members': {'readonly': True}, + 'required_zone_names': {'readonly': True}, + } + + _attribute_map = { + 'group_id': {'key': 'groupId', 'type': 'str'}, + 'required_members': {'key': 'requiredMembers', 'type': '[str]'}, + 'required_zone_names': {'key': 'requiredZoneNames', 'type': '[str]'}, + } + + def __init__( + self, + **kwargs + ): + super(PrivateLinkResourceProperties, self).__init__(**kwargs) + self.group_id = None + self.required_members = None + self.required_zone_names = None + + +class PrivateLinkScopeValidationDetails(msrest.serialization.Model): + """PrivateLinkScopeValidationDetails. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Azure resource Id. + :vartype id: str + :param public_network_access: Indicates whether machines associated with the private link scope + can also use public Azure Arc service endpoints. Possible values include: "Enabled", + "Disabled". Default value: "Disabled". + :type public_network_access: str or ~azure.mgmt.hybridcompute.models.PublicNetworkAccessType + :param connection_details: List of Private Endpoint Connection details. + :type connection_details: list[~azure.mgmt.hybridcompute.models.ConnectionDetail] + """ + + _validation = { + 'id': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'public_network_access': {'key': 'publicNetworkAccess', 'type': 'str'}, + 'connection_details': {'key': 'connectionDetails', 'type': '[ConnectionDetail]'}, + } + + def __init__( + self, + *, + public_network_access: Optional[Union[str, "PublicNetworkAccessType"]] = "Disabled", + connection_details: Optional[List["ConnectionDetail"]] = None, + **kwargs + ): + super(PrivateLinkScopeValidationDetails, self).__init__(**kwargs) + self.id = None + self.public_network_access = public_network_access + self.connection_details = connection_details + + +class PrivateLinkServiceConnectionStateProperty(msrest.serialization.Model): + """State of the private endpoint connection. + + Variables are only populated by the server, and will be ignored when sending a request. + + All required parameters must be populated in order to send to Azure. + + :param status: Required. The private link service connection status. + :type status: str + :param description: Required. The private link service connection description. + :type description: str + :ivar actions_required: The actions required for private link service connection. + :vartype actions_required: str + """ + + _validation = { + 'status': {'required': True}, + 'description': {'required': True}, + 'actions_required': {'readonly': True}, + } + + _attribute_map = { + 'status': {'key': 'status', 'type': 'str'}, + 'description': {'key': 'description', 'type': 'str'}, + 'actions_required': {'key': 'actionsRequired', 'type': 'str'}, + } + + def __init__( + self, + *, + status: str, + description: str, + **kwargs + ): + super(PrivateLinkServiceConnectionStateProperty, self).__init__(**kwargs) + self.status = status + self.description = description + self.actions_required = None + + +class ProxyResource(Resource): + """The resource model definition for a Azure Resource Manager proxy resource. It will not have tags and a location. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(ProxyResource, self).__init__(**kwargs) + + +class SystemData(msrest.serialization.Model): + """Metadata pertaining to creation and last modification of the resource. + + :param created_by: The identity that created the resource. + :type created_by: str + :param created_by_type: The type of identity that created the resource. Possible values + include: "User", "Application", "ManagedIdentity", "Key". + :type created_by_type: str or ~azure.mgmt.hybridcompute.models.CreatedByType + :param created_at: The timestamp of resource creation (UTC). + :type created_at: ~datetime.datetime + :param last_modified_by: The identity that last modified the resource. + :type last_modified_by: str + :param last_modified_by_type: The type of identity that last modified the resource. Possible + values include: "User", "Application", "ManagedIdentity", "Key". + :type last_modified_by_type: str or ~azure.mgmt.hybridcompute.models.CreatedByType + :param last_modified_at: The timestamp of resource last modification (UTC). + :type last_modified_at: ~datetime.datetime + """ + + _attribute_map = { + 'created_by': {'key': 'createdBy', 'type': 'str'}, + 'created_by_type': {'key': 'createdByType', 'type': 'str'}, + 'created_at': {'key': 'createdAt', 'type': 'iso-8601'}, + 'last_modified_by': {'key': 'lastModifiedBy', 'type': 'str'}, + 'last_modified_by_type': {'key': 'lastModifiedByType', 'type': 'str'}, + 'last_modified_at': {'key': 'lastModifiedAt', 'type': 'iso-8601'}, + } + + def __init__( + self, + *, + created_by: Optional[str] = None, + created_by_type: Optional[Union[str, "CreatedByType"]] = None, + created_at: Optional[datetime.datetime] = None, + last_modified_by: Optional[str] = None, + last_modified_by_type: Optional[Union[str, "CreatedByType"]] = None, + last_modified_at: Optional[datetime.datetime] = None, + **kwargs + ): + super(SystemData, self).__init__(**kwargs) + self.created_by = created_by + self.created_by_type = created_by_type + self.created_at = created_at + self.last_modified_by = last_modified_by + self.last_modified_by_type = last_modified_by_type + self.last_modified_at = last_modified_at + + +class TagsResource(msrest.serialization.Model): + """A container holding only the Tags for a resource, allowing the user to update the tags on a PrivateLinkScope instance. + + :param tags: A set of tags. Resource tags. + :type tags: dict[str, str] + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + } + + def __init__( + self, + *, + tags: Optional[Dict[str, str]] = None, + **kwargs + ): + super(TagsResource, self).__init__(**kwargs) + self.tags = tags diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/__init__.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/__init__.py new file mode 100644 index 0000000000..641a5a8b66 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/__init__.py @@ -0,0 +1,25 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._machines_operations import MachinesOperations +from ._machine_extensions_operations import MachineExtensionsOperations +from ._connected_machine_operations import ConnectedMachineOperationsMixin +from ._operations import Operations +from ._private_link_scopes_operations import PrivateLinkScopesOperations +from ._private_link_resources_operations import PrivateLinkResourcesOperations +from ._private_endpoint_connections_operations import PrivateEndpointConnectionsOperations + +__all__ = [ + 'MachinesOperations', + 'MachineExtensionsOperations', + 'ConnectedMachineOperationsMixin', + 'Operations', + 'PrivateLinkScopesOperations', + 'PrivateLinkResourcesOperations', + 'PrivateEndpointConnectionsOperations', +] diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_connected_machine_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_connected_machine_operations.py new file mode 100644 index 0000000000..a3ba7e9ea7 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_connected_machine_operations.py @@ -0,0 +1,148 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.core.polling import LROPoller, NoPolling, PollingMethod +from azure.mgmt.core.exceptions import ARMErrorFormat +from azure.mgmt.core.polling.arm_polling import ARMPolling + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Optional, TypeVar, Union + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class ConnectedMachineOperationsMixin(object): + + def _upgrade_extensions_initial( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_upgrade_parameters, # type: "models.MachineExtensionUpgrade" + **kwargs # type: Any + ): + # type: (...) -> None + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self._upgrade_extensions_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(extension_upgrade_parameters, 'MachineExtensionUpgrade') + body_content_kwargs['content'] = body_content + request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + _upgrade_extensions_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/upgradeExtensions'} # type: ignore + + def begin_upgrade_extensions( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_upgrade_parameters, # type: "models.MachineExtensionUpgrade" + **kwargs # type: Any + ): + # type: (...) -> LROPoller[None] + """The operation to Upgrade Machine Extensions. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the hybrid machine. + :type machine_name: str + :param extension_upgrade_parameters: Parameters supplied to the Upgrade Extensions operation. + :type extension_upgrade_parameters: ~azure.mgmt.hybridcompute.models.MachineExtensionUpgrade + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.PollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of LROPoller that returns either None or the result of cls(response) + :rtype: ~azure.core.polling.LROPoller[None] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, PollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType[None] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = self._upgrade_extensions_initial( + resource_group_name=resource_group_name, + machine_name=machine_name, + extension_upgrade_parameters=extension_upgrade_parameters, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + if cls: + return cls(pipeline_response, None, {}) + + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + } + + if polling is True: polling_method = ARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = NoPolling() + else: polling_method = polling + if cont_token: + return LROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return LROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_upgrade_extensions.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/upgradeExtensions'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_machine_extensions_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_machine_extensions_operations.py new file mode 100644 index 0000000000..63bc7c881c --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_machine_extensions_operations.py @@ -0,0 +1,583 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.core.polling import LROPoller, NoPolling, PollingMethod +from azure.mgmt.core.exceptions import ARMErrorFormat +from azure.mgmt.core.polling.arm_polling import ARMPolling + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar, Union + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class MachineExtensionsOperations(object): + """MachineExtensionsOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def _create_or_update_initial( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_name, # type: str + extension_parameters, # type: "models.MachineExtension" + **kwargs # type: Any + ): + # type: (...) -> Optional["models.MachineExtension"] + cls = kwargs.pop('cls', None) # type: ClsType[Optional["models.MachineExtension"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self._create_or_update_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(extension_parameters, 'MachineExtension') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + _create_or_update_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + def begin_create_or_update( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_name, # type: str + extension_parameters, # type: "models.MachineExtension" + **kwargs # type: Any + ): + # type: (...) -> LROPoller["models.MachineExtension"] + """The operation to create or update the extension. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine where the extension should be created or updated. + :type machine_name: str + :param extension_name: The name of the machine extension. + :type extension_name: str + :param extension_parameters: Parameters supplied to the Create Machine Extension operation. + :type extension_parameters: ~azure.mgmt.hybridcompute.models.MachineExtension + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.PollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of LROPoller that returns either MachineExtension or the result of cls(response) + :rtype: ~azure.core.polling.LROPoller[~azure.mgmt.hybridcompute.models.MachineExtension] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, PollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineExtension"] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = self._create_or_update_initial( + resource_group_name=resource_group_name, + machine_name=machine_name, + extension_name=extension_name, + extension_parameters=extension_parameters, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + return deserialized + + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + + if polling is True: polling_method = ARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = NoPolling() + else: polling_method = polling + if cont_token: + return LROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return LROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_create_or_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + def _update_initial( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_name, # type: str + extension_parameters, # type: "models.MachineExtensionUpdate" + **kwargs # type: Any + ): + # type: (...) -> Optional["models.MachineExtension"] + cls = kwargs.pop('cls', None) # type: ClsType[Optional["models.MachineExtension"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self._update_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(extension_parameters, 'MachineExtensionUpdate') + body_content_kwargs['content'] = body_content + request = self._client.patch(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + _update_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + def begin_update( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_name, # type: str + extension_parameters, # type: "models.MachineExtensionUpdate" + **kwargs # type: Any + ): + # type: (...) -> LROPoller["models.MachineExtension"] + """The operation to create or update the extension. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine where the extension should be created or updated. + :type machine_name: str + :param extension_name: The name of the machine extension. + :type extension_name: str + :param extension_parameters: Parameters supplied to the Create Machine Extension operation. + :type extension_parameters: ~azure.mgmt.hybridcompute.models.MachineExtensionUpdate + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.PollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of LROPoller that returns either MachineExtension or the result of cls(response) + :rtype: ~azure.core.polling.LROPoller[~azure.mgmt.hybridcompute.models.MachineExtension] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, PollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineExtension"] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = self._update_initial( + resource_group_name=resource_group_name, + machine_name=machine_name, + extension_name=extension_name, + extension_parameters=extension_parameters, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + return deserialized + + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + + if polling is True: polling_method = ARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = NoPolling() + else: polling_method = polling + if cont_token: + return LROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return LROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + def _delete_initial( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self._delete_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + _delete_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + def begin_delete( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> LROPoller[None] + """The operation to delete the extension. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine where the extension should be deleted. + :type machine_name: str + :param extension_name: The name of the machine extension. + :type extension_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.PollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of LROPoller that returns either None or the result of cls(response) + :rtype: ~azure.core.polling.LROPoller[None] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, PollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType[None] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = self._delete_initial( + resource_group_name=resource_group_name, + machine_name=machine_name, + extension_name=extension_name, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + if cls: + return cls(pipeline_response, None, {}) + + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + + if polling is True: polling_method = ARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = NoPolling() + else: polling_method = polling + if cont_token: + return LROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return LROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + def get( + self, + resource_group_name, # type: str + machine_name, # type: str + extension_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> "models.MachineExtension" + """The operation to get the extension. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine containing the extension. + :type machine_name: str + :param extension_name: The name of the machine extension. + :type extension_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: MachineExtension, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.MachineExtension + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineExtension"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'extensionName': self._serialize.url("extension_name", extension_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('MachineExtension', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions/{extensionName}'} # type: ignore + + def list( + self, + resource_group_name, # type: str + machine_name, # type: str + expand=None, # type: Optional[str] + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.MachineExtensionsListResult"] + """The operation to get all extensions of a non-Azure machine. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the machine containing the extension. + :type machine_name: str + :param expand: The expand expression to apply on the operation. + :type expand: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either MachineExtensionsListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.hybridcompute.models.MachineExtensionsListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineExtensionsListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if expand is not None: + query_parameters['$expand'] = self._serialize.query("expand", expand, 'str') + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('MachineExtensionsListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/extensions'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_machines_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_machines_operations.py new file mode 100644 index 0000000000..2c809786d6 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_machines_operations.py @@ -0,0 +1,310 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.mgmt.core.exceptions import ARMErrorFormat + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar, Union + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class MachinesOperations(object): + """MachinesOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def delete( + self, + resource_group_name, # type: str + machine_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """The operation to remove a hybrid machine identity in Azure. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the hybrid machine. + :type machine_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.delete.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}'} # type: ignore + + def get( + self, + resource_group_name, # type: str + machine_name, # type: str + expand=None, # type: Optional[Union[str, "models.InstanceViewTypes"]] + **kwargs # type: Any + ): + # type: (...) -> "models.Machine" + """Retrieves information about the model view or the instance view of a hybrid machine. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the hybrid machine. + :type machine_name: str + :param expand: The expand expression to apply on the operation. + :type expand: str or ~azure.mgmt.hybridcompute.models.InstanceViewTypes + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Machine, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.Machine + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.Machine"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + if expand is not None: + query_parameters['$expand'] = self._serialize.query("expand", expand, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('Machine', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}'} # type: ignore + + def list_by_resource_group( + self, + resource_group_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.MachineListResult"] + """Lists all the hybrid machines in the specified resource group. Use the nextLink property in the + response to get the next page of hybrid machines. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either MachineListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.hybridcompute.models.MachineListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_resource_group.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('MachineListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list_by_resource_group.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines'} # type: ignore + + def list_by_subscription( + self, + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.MachineListResult"] + """Lists all the hybrid machines in the specified subscription. Use the nextLink property in the + response to get the next page of hybrid machines. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either MachineListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.hybridcompute.models.MachineListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.MachineListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_subscription.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('MachineListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list_by_subscription.metadata = {'url': '/subscriptions/{subscriptionId}/providers/Microsoft.HybridCompute/machines'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_operations.py new file mode 100644 index 0000000000..d5605a3645 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_operations.py @@ -0,0 +1,110 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.mgmt.core.exceptions import ARMErrorFormat + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class Operations(object): + """Operations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list( + self, + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.OperationListResult"] + """Gets a list of hybrid compute operations. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either OperationListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.hybridcompute.models.OperationListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.OperationListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('OperationListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/providers/Microsoft.HybridCompute/operations'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_endpoint_connections_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_endpoint_connections_operations.py new file mode 100644 index 0000000000..48c2e53040 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_endpoint_connections_operations.py @@ -0,0 +1,442 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.core.polling import LROPoller, NoPolling, PollingMethod +from azure.mgmt.core.exceptions import ARMErrorFormat +from azure.mgmt.core.polling.arm_polling import ARMPolling + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar, Union + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class PrivateEndpointConnectionsOperations(object): + """PrivateEndpointConnectionsOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def get( + self, + resource_group_name, # type: str + scope_name, # type: str + private_endpoint_connection_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> "models.PrivateEndpointConnection" + """Gets a private endpoint connection. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param private_endpoint_connection_name: The name of the private endpoint connection. + :type private_endpoint_connection_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: PrivateEndpointConnection, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.PrivateEndpointConnection + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateEndpointConnection"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('PrivateEndpointConnection', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + def _update_initial( + self, + resource_group_name, # type: str + scope_name, # type: str + private_endpoint_connection_name, # type: str + parameters, # type: "models.PrivateEndpointConnection" + **kwargs # type: Any + ): + # type: (...) -> Optional["models.PrivateEndpointConnection"] + cls = kwargs.pop('cls', None) # type: ClsType[Optional["models.PrivateEndpointConnection"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self._update_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(parameters, 'PrivateEndpointConnection') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('PrivateEndpointConnection', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + _update_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + def begin_update( + self, + resource_group_name, # type: str + scope_name, # type: str + private_endpoint_connection_name, # type: str + parameters, # type: "models.PrivateEndpointConnection" + **kwargs # type: Any + ): + # type: (...) -> LROPoller["models.PrivateEndpointConnection"] + """Approve or reject a private endpoint connection with a given name. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param private_endpoint_connection_name: The name of the private endpoint connection. + :type private_endpoint_connection_name: str + :param parameters: + :type parameters: ~azure.mgmt.hybridcompute.models.PrivateEndpointConnection + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.PollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of LROPoller that returns either PrivateEndpointConnection or the result of cls(response) + :rtype: ~azure.core.polling.LROPoller[~azure.mgmt.hybridcompute.models.PrivateEndpointConnection] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, PollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateEndpointConnection"] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = self._update_initial( + resource_group_name=resource_group_name, + scope_name=scope_name, + private_endpoint_connection_name=private_endpoint_connection_name, + parameters=parameters, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + deserialized = self._deserialize('PrivateEndpointConnection', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + return deserialized + + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + + if polling is True: polling_method = ARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = NoPolling() + else: polling_method = polling + if cont_token: + return LROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return LROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + def _delete_initial( + self, + resource_group_name, # type: str + scope_name, # type: str + private_endpoint_connection_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self._delete_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + _delete_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + def begin_delete( + self, + resource_group_name, # type: str + scope_name, # type: str + private_endpoint_connection_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> LROPoller[None] + """Deletes a private endpoint connection with a given name. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param private_endpoint_connection_name: The name of the private endpoint connection. + :type private_endpoint_connection_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.PollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of LROPoller that returns either None or the result of cls(response) + :rtype: ~azure.core.polling.LROPoller[None] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, PollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType[None] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = self._delete_initial( + resource_group_name=resource_group_name, + scope_name=scope_name, + private_endpoint_connection_name=private_endpoint_connection_name, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + if cls: + return cls(pipeline_response, None, {}) + + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'privateEndpointConnectionName': self._serialize.url("private_endpoint_connection_name", private_endpoint_connection_name, 'str'), + } + + if polling is True: polling_method = ARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = NoPolling() + else: polling_method = polling + if cont_token: + return LROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return LROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections/{privateEndpointConnectionName}'} # type: ignore + + def list_by_private_link_scope( + self, + resource_group_name, # type: str + scope_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.PrivateEndpointConnectionListResult"] + """Gets all private endpoint connections on a private link scope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PrivateEndpointConnectionListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.hybridcompute.models.PrivateEndpointConnectionListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateEndpointConnectionListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_private_link_scope.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PrivateEndpointConnectionListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list_by_private_link_scope.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateEndpointConnections'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_link_resources_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_link_resources_operations.py new file mode 100644 index 0000000000..07efc46cf7 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_link_resources_operations.py @@ -0,0 +1,186 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.mgmt.core.exceptions import ARMErrorFormat + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class PrivateLinkResourcesOperations(object): + """PrivateLinkResourcesOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list_by_private_link_scope( + self, + resource_group_name, # type: str + scope_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.PrivateLinkResourceListResult"] + """Gets the private link resources that need to be created for a Azure Monitor PrivateLinkScope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PrivateLinkResourceListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.hybridcompute.models.PrivateLinkResourceListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateLinkResourceListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_private_link_scope.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PrivateLinkResourceListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list_by_private_link_scope.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateLinkResources'} # type: ignore + + def get( + self, + resource_group_name, # type: str + scope_name, # type: str + group_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> "models.PrivateLinkResource" + """Gets the private link resources that need to be created for a Azure Monitor PrivateLinkScope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param group_name: The name of the private link resource. + :type group_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: PrivateLinkResource, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.PrivateLinkResource + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateLinkResource"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + 'groupName': self._serialize.url("group_name", group_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('PrivateLinkResource', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}/privateLinkResources/{groupName}'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_link_scopes_operations.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_link_scopes_operations.py new file mode 100644 index 0000000000..547e69394c --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/operations/_private_link_scopes_operations.py @@ -0,0 +1,624 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.core.polling import LROPoller, NoPolling, PollingMethod +from azure.mgmt.core.exceptions import ARMErrorFormat +from azure.mgmt.core.polling.arm_polling import ARMPolling + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar, Union + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class PrivateLinkScopesOperations(object): + """PrivateLinkScopesOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.mgmt.hybridcompute.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list( + self, + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.HybridComputePrivateLinkScopeListResult"] + """Gets a list of all Azure Arc PrivateLinkScopes within a subscription. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either HybridComputePrivateLinkScopeListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScopeListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScopeListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('HybridComputePrivateLinkScopeListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/subscriptions/{subscriptionId}/providers/Microsoft.HybridCompute/privateLinkScopes'} # type: ignore + + def list_by_resource_group( + self, + resource_group_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.HybridComputePrivateLinkScopeListResult"] + """Gets a list of Azure Arc PrivateLinkScopes within a resource group. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either HybridComputePrivateLinkScopeListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScopeListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScopeListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list_by_resource_group.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('HybridComputePrivateLinkScopeListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list_by_resource_group.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes'} # type: ignore + + def _delete_initial( + self, + resource_group_name, # type: str + scope_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self._delete_initial.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 202, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + _delete_initial.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + def begin_delete( + self, + resource_group_name, # type: str + scope_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> LROPoller[None] + """Deletes a Azure Arc PrivateLinkScope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :keyword str continuation_token: A continuation token to restart a poller from a saved state. + :keyword polling: True for ARMPolling, False for no polling, or a + polling object for personal polling strategy + :paramtype polling: bool or ~azure.core.polling.PollingMethod + :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. + :return: An instance of LROPoller that returns either None or the result of cls(response) + :rtype: ~azure.core.polling.LROPoller[None] + :raises ~azure.core.exceptions.HttpResponseError: + """ + polling = kwargs.pop('polling', True) # type: Union[bool, PollingMethod] + cls = kwargs.pop('cls', None) # type: ClsType[None] + lro_delay = kwargs.pop( + 'polling_interval', + self._config.polling_interval + ) + cont_token = kwargs.pop('continuation_token', None) # type: Optional[str] + if cont_token is None: + raw_result = self._delete_initial( + resource_group_name=resource_group_name, + scope_name=scope_name, + cls=lambda x,y,z: x, + **kwargs + ) + + kwargs.pop('error_map', None) + kwargs.pop('content_type', None) + + def get_long_running_output(pipeline_response): + if cls: + return cls(pipeline_response, None, {}) + + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + + if polling is True: polling_method = ARMPolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + elif polling is False: polling_method = NoPolling() + else: polling_method = polling + if cont_token: + return LROPoller.from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output + ) + else: + return LROPoller(self._client, raw_result, get_long_running_output, polling_method) + begin_delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + def get( + self, + resource_group_name, # type: str + scope_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> "models.HybridComputePrivateLinkScope" + """Returns a Azure Arc PrivateLinkScope. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: HybridComputePrivateLinkScope, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScope"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('HybridComputePrivateLinkScope', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + def create_or_update( + self, + resource_group_name, # type: str + scope_name, # type: str + parameters, # type: "models.HybridComputePrivateLinkScope" + **kwargs # type: Any + ): + # type: (...) -> "models.HybridComputePrivateLinkScope" + """Creates (or updates) a Azure Arc PrivateLinkScope. Note: You cannot specify a different value + for InstrumentationKey nor AppId in the Put operation. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param parameters: Properties that need to be specified to create or update a Azure Arc for + Servers and Clusters PrivateLinkScope. + :type parameters: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope + :keyword callable cls: A custom type or function that will be passed the direct response + :return: HybridComputePrivateLinkScope, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScope"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.create_or_update.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(parameters, 'HybridComputePrivateLinkScope') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if response.status_code == 200: + deserialized = self._deserialize('HybridComputePrivateLinkScope', pipeline_response) + + if response.status_code == 201: + deserialized = self._deserialize('HybridComputePrivateLinkScope', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + create_or_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + def update_tags( + self, + resource_group_name, # type: str + scope_name, # type: str + private_link_scope_tags, # type: "models.TagsResource" + **kwargs # type: Any + ): + # type: (...) -> "models.HybridComputePrivateLinkScope" + """Updates an existing PrivateLinkScope's tags. To update other fields use the CreateOrUpdate + method. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param scope_name: The name of the Azure Arc PrivateLinkScope resource. + :type scope_name: str + :param private_link_scope_tags: Updated tag information to set into the PrivateLinkScope + instance. + :type private_link_scope_tags: ~azure.mgmt.hybridcompute.models.TagsResource + :keyword callable cls: A custom type or function that will be passed the direct response + :return: HybridComputePrivateLinkScope, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.HybridComputePrivateLinkScope + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.HybridComputePrivateLinkScope"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.update_tags.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'scopeName': self._serialize.url("scope_name", scope_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(private_link_scope_tags, 'TagsResource') + body_content_kwargs['content'] = body_content + request = self._client.patch(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('HybridComputePrivateLinkScope', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + update_tags.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/privateLinkScopes/{scopeName}'} # type: ignore + + def get_validation_details( + self, + location, # type: str + private_link_scope_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "models.PrivateLinkScopeValidationDetails" + """Returns a Azure Arc PrivateLinkScope's validation details. + + :param location: The location of the target resource. + :type location: str + :param private_link_scope_id: The id (Guid) of the Azure Arc PrivateLinkScope resource. + :type private_link_scope_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: PrivateLinkScopeValidationDetails, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.PrivateLinkScopeValidationDetails + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateLinkScopeValidationDetails"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get_validation_details.metadata['url'] # type: ignore + path_format_arguments = { + 'location': self._serialize.url("location", location, 'str', min_length=1), + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'privateLinkScopeId': self._serialize.url("private_link_scope_id", private_link_scope_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('PrivateLinkScopeValidationDetails', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_validation_details.metadata = {'url': '/subscriptions/{subscriptionId}/providers/Microsoft.HybridCompute/locations/{location}/privateLinkScopes/{privateLinkScopeId}'} # type: ignore + + def get_validation_details_for_machine( + self, + resource_group_name, # type: str + machine_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> "models.PrivateLinkScopeValidationDetails" + """Returns a Azure Arc PrivateLinkScope's validation details for a given machine. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param machine_name: The name of the target machine to get the private link scope validation + details for. + :type machine_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: PrivateLinkScopeValidationDetails, or the result of cls(response) + :rtype: ~azure.mgmt.hybridcompute.models.PrivateLinkScopeValidationDetails + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.PrivateLinkScopeValidationDetails"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-05-20" + accept = "application/json" + + # Construct URL + url = self.get_validation_details_for_machine.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str', min_length=1), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('PrivateLinkScopeValidationDetails', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_validation_details_for_machine.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/privateLinkScopes/current'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/py.typed b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/py.typed new file mode 100644 index 0000000000..e5aff4f83a --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/src/ssh/azext_ssh/vendored_sdks/connectedmachine/setup.py b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/setup.py new file mode 100644 index 0000000000..f0a42bc98f --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/connectedmachine/setup.py @@ -0,0 +1,37 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# coding: utf-8 + +from setuptools import setup, find_packages + +NAME = "azure-mgmt-hybridcompute" +VERSION = "1.0.0b1" + +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools + +REQUIRES = ["msrest>=0.6.18", "azure-core<2.0.0,>=1.8.2", "azure-mgmt-core<2.0.0,>=1.2.1"] + +setup( + name=NAME, + version=VERSION, + description="azure-mgmt-hybridcompute", + author_email="", + url="", + keywords=["Swagger", "ConnectedMachine"], + install_requires=REQUIRES, + packages=find_packages(), + include_package_data=True, + long_description="""\ + The Hybrid Compute Management Client. + """ +) diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/__init__.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/__init__.py new file mode 100644 index 0000000000..9d5f8048ff --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/__init__.py @@ -0,0 +1,16 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._hybrid_connectivity_management_api import HybridConnectivityManagementAPI +__all__ = ['HybridConnectivityManagementAPI'] + +try: + from ._patch import patch_sdk # type: ignore + patch_sdk() +except ImportError: + pass diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/_configuration.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/_configuration.py new file mode 100644 index 0000000000..3d6b6c9409 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/_configuration.py @@ -0,0 +1,68 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import TYPE_CHECKING + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies +from azure.mgmt.core.policies import ARMHttpLoggingPolicy + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any + + from azure.core.credentials import TokenCredential + +VERSION = "unknown" + +class HybridConnectivityManagementAPIConfiguration(Configuration): + """Configuration for HybridConnectivityManagementAPI. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.TokenCredential + """ + + def __init__( + self, + credential, # type: "TokenCredential" + subscription_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + if subscription_id is None: + raise ValueError("Parameter 'subscription_id' must not be None.") + super(HybridConnectivityManagementAPIConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.subscription_id = subscription_id + self.api_version = "2021-10-06-preview" + self.credential_scopes = kwargs.pop('credential_scopes', ['https://management.azure.com/.default']) + kwargs.setdefault('sdk_moniker', 'hybridconnectivitymanagementapi/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs # type: Any + ): + # type: (...) -> None + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or ARMHttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/_hybrid_connectivity_management_api.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/_hybrid_connectivity_management_api.py new file mode 100644 index 0000000000..7b1c37cd7e --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/_hybrid_connectivity_management_api.py @@ -0,0 +1,71 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import TYPE_CHECKING + +from azure.mgmt.core import ARMPipelineClient +from msrest import Deserializer, Serializer + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Optional + + from azure.core.credentials import TokenCredential + +from ._configuration import HybridConnectivityManagementAPIConfiguration +from .operations import Operations +from .operations import EndpointsOperations +from . import models + + +class HybridConnectivityManagementAPI(object): + """REST API for Hybrid Connectivity. + + :ivar operations: Operations operations + :vartype operations: hybrid_connectivity_management_api.operations.Operations + :ivar endpoints: EndpointsOperations operations + :vartype endpoints: hybrid_connectivity_management_api.operations.EndpointsOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.TokenCredential + :param str base_url: Service URL + """ + + def __init__( + self, + credential, # type: "TokenCredential" + subscription_id, # type: str + base_url=None, # type: Optional[str] + **kwargs # type: Any + ): + # type: (...) -> None + if not base_url: + base_url = 'https://management.azure.com' + self._config = HybridConnectivityManagementAPIConfiguration(credential, subscription_id, **kwargs) + self._client = ARMPipelineClient(base_url=base_url, config=self._config, **kwargs) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer(client_models) + self._deserialize = Deserializer(client_models) + + self.operations = Operations( + self._client, self._config, self._serialize, self._deserialize) + self.endpoints = EndpointsOperations( + self._client, self._config, self._serialize, self._deserialize) + + def close(self): + # type: () -> None + self._client.close() + + def __enter__(self): + # type: () -> HybridConnectivityManagementAPI + self._client.__enter__() + return self + + def __exit__(self, *exc_details): + # type: (Any) -> None + self._client.__exit__(*exc_details) diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/__init__.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/__init__.py new file mode 100644 index 0000000000..785b5445cc --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/__init__.py @@ -0,0 +1,10 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._hybrid_connectivity_management_api import HybridConnectivityManagementAPI +__all__ = ['HybridConnectivityManagementAPI'] diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/_configuration.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/_configuration.py new file mode 100644 index 0000000000..41f28de96b --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/_configuration.py @@ -0,0 +1,60 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any, TYPE_CHECKING + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies +from azure.mgmt.core.policies import ARMHttpLoggingPolicy + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + +VERSION = "unknown" + +class HybridConnectivityManagementAPIConfiguration(Configuration): + """Configuration for HybridConnectivityManagementAPI. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + """ + + def __init__( + self, + credential: "AsyncTokenCredential", + **kwargs: Any + ) -> None: + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + super(HybridConnectivityManagementAPIConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.api_version = "2021-10-06-preview" + self.credential_scopes = kwargs.pop('credential_scopes', ['https://management.azure.com/.default']) + kwargs.setdefault('sdk_moniker', 'hybridconnectivitymanagementapi/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs: Any + ) -> None: + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or ARMHttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/_hybrid_connectivity_management_api.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/_hybrid_connectivity_management_api.py new file mode 100644 index 0000000000..837237055a --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/_hybrid_connectivity_management_api.py @@ -0,0 +1,64 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any, Optional, TYPE_CHECKING + +from azure.mgmt.core import AsyncARMPipelineClient +from msrest import Deserializer, Serializer + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + +from ._configuration import HybridConnectivityManagementAPIConfiguration +from .operations import Operations +from .operations import EndpointsOperations +from .. import models + + +class HybridConnectivityManagementAPI(object): + """REST API for Hybrid Connectivity. + + :ivar operations: Operations operations + :vartype operations: hybrid_connectivity_management_api.aio.operations.Operations + :ivar endpoints: EndpointsOperations operations + :vartype endpoints: hybrid_connectivity_management_api.aio.operations.EndpointsOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :param str base_url: Service URL + """ + + def __init__( + self, + credential: "AsyncTokenCredential", + base_url: Optional[str] = None, + **kwargs: Any + ) -> None: + if not base_url: + base_url = 'https://management.azure.com' + self._config = HybridConnectivityManagementAPIConfiguration(credential, **kwargs) + self._client = AsyncARMPipelineClient(base_url=base_url, config=self._config, **kwargs) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer(client_models) + self._deserialize = Deserializer(client_models) + + self.operations = Operations( + self._client, self._config, self._serialize, self._deserialize) + self.endpoints = EndpointsOperations( + self._client, self._config, self._serialize, self._deserialize) + + async def close(self) -> None: + await self._client.close() + + async def __aenter__(self) -> "HybridConnectivityManagementAPI": + await self._client.__aenter__() + return self + + async def __aexit__(self, *exc_details) -> None: + await self._client.__aexit__(*exc_details) diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/__init__.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/__init__.py new file mode 100644 index 0000000000..d9149323f4 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/__init__.py @@ -0,0 +1,15 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._operations import Operations +from ._endpoints_operations import EndpointsOperations + +__all__ = [ + 'Operations', + 'EndpointsOperations', +] diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/_endpoints_operations.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/_endpoints_operations.py new file mode 100644 index 0000000000..16f77d06ff --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/_endpoints_operations.py @@ -0,0 +1,426 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.mgmt.core.exceptions import ARMErrorFormat + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class EndpointsOperations: + """EndpointsOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~hybrid_connectivity_management_api.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list( + self, + resource_uri: str, + **kwargs + ) -> AsyncIterable["models.EndpointsList"]: + """List of endpoints to the target resource. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource to + be connected. + :type resource_uri: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either EndpointsList or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~hybrid_connectivity_management_api.models.EndpointsList] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.EndpointsList"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceUri': self._serialize.url("resource_uri", resource_uri, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('EndpointsList', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/{resourceUri}/providers/Microsoft.HybridConnectivity/endpoints'} # type: ignore + + async def get( + self, + resource_uri: str, + endpoint_name: str, + **kwargs + ) -> "models.EndpointResource": + """Gets the endpoint to the resource. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource to + be connected. + :type resource_uri: str + :param endpoint_name: The endpoint name. + :type endpoint_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: EndpointResource, or the result of cls(response) + :rtype: ~hybrid_connectivity_management_api.models.EndpointResource + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.EndpointResource"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + accept = "application/json" + + # Construct URL + url = self.get.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceUri': self._serialize.url("resource_uri", resource_uri, 'str', skip_quote=True), + 'endpointName': self._serialize.url("endpoint_name", endpoint_name, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('EndpointResource', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get.metadata = {'url': '/{resourceUri}/providers/Microsoft.HybridConnectivity/endpoints/{endpointName}'} # type: ignore + + async def create_or_update( + self, + resource_uri: str, + endpoint_name: str, + endpoint_resource: "models.EndpointResource", + **kwargs + ) -> "models.EndpointResource": + """Create or update the endpoint to the target resource. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource to + be connected. + :type resource_uri: str + :param endpoint_name: The endpoint name. + :type endpoint_name: str + :param endpoint_resource: Endpoint details. + :type endpoint_resource: ~hybrid_connectivity_management_api.models.EndpointResource + :keyword callable cls: A custom type or function that will be passed the direct response + :return: EndpointResource, or the result of cls(response) + :rtype: ~hybrid_connectivity_management_api.models.EndpointResource + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.EndpointResource"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.create_or_update.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceUri': self._serialize.url("resource_uri", resource_uri, 'str', skip_quote=True), + 'endpointName': self._serialize.url("endpoint_name", endpoint_name, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(endpoint_resource, 'EndpointResource') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('EndpointResource', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + create_or_update.metadata = {'url': '/{resourceUri}/providers/Microsoft.HybridConnectivity/endpoints/{endpointName}'} # type: ignore + + async def update( + self, + resource_uri: str, + endpoint_name: str, + endpoint_resource: "models.EndpointResource", + **kwargs + ) -> "models.EndpointResource": + """Update the endpoint to the target resource. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource to + be connected. + :type resource_uri: str + :param endpoint_name: The endpoint name. + :type endpoint_name: str + :param endpoint_resource: Endpoint details. + :type endpoint_resource: ~hybrid_connectivity_management_api.models.EndpointResource + :keyword callable cls: A custom type or function that will be passed the direct response + :return: EndpointResource, or the result of cls(response) + :rtype: ~hybrid_connectivity_management_api.models.EndpointResource + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.EndpointResource"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.update.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceUri': self._serialize.url("resource_uri", resource_uri, 'str', skip_quote=True), + 'endpointName': self._serialize.url("endpoint_name", endpoint_name, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(endpoint_resource, 'EndpointResource') + body_content_kwargs['content'] = body_content + request = self._client.patch(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('EndpointResource', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + update.metadata = {'url': '/{resourceUri}/providers/Microsoft.HybridConnectivity/endpoints/{endpointName}'} # type: ignore + + async def delete( + self, + resource_uri: str, + endpoint_name: str, + **kwargs + ) -> None: + """Deletes the endpoint access to the target resource. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource to + be connected. + :type resource_uri: str + :param endpoint_name: The endpoint name. + :type endpoint_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + accept = "application/json" + + # Construct URL + url = self.delete.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceUri': self._serialize.url("resource_uri", resource_uri, 'str', skip_quote=True), + 'endpointName': self._serialize.url("endpoint_name", endpoint_name, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + if cls: + return cls(pipeline_response, None, {}) + + delete.metadata = {'url': '/{resourceUri}/providers/Microsoft.HybridConnectivity/endpoints/{endpointName}'} # type: ignore + + async def list_credentials( + self, + resource_uri: str, + endpoint_name: str, + expiresin: Optional[int] = 10800, + **kwargs + ) -> "models.EndpointAccessResource": + """Gets the endpoint access credentials to the resource. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource to + be connected. + :type resource_uri: str + :param endpoint_name: The endpoint name. + :type endpoint_name: str + :param expiresin: The is how long the endpoint access token is valid (in seconds). + :type expiresin: long + :keyword callable cls: A custom type or function that will be passed the direct response + :return: EndpointAccessResource, or the result of cls(response) + :rtype: ~hybrid_connectivity_management_api.models.EndpointAccessResource + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.EndpointAccessResource"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + accept = "application/json" + + # Construct URL + url = self.list_credentials.metadata['url'] # type: ignore + path_format_arguments = { + 'resourceUri': self._serialize.url("resource_uri", resource_uri, 'str', skip_quote=True), + 'endpointName': self._serialize.url("endpoint_name", endpoint_name, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + if expiresin is not None: + query_parameters['expiresin'] = self._serialize.query("expiresin", expiresin, 'long', maximum=10800, minimum=600) + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.post(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('EndpointAccessResource', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + list_credentials.metadata = {'url': '/{resourceUri}/providers/Microsoft.HybridConnectivity/endpoints/{endpointName}/listCredentials'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/_operations.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/_operations.py new file mode 100644 index 0000000000..e06178d99d --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/aio/operations/_operations.py @@ -0,0 +1,105 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from azure.mgmt.core.exceptions import ARMErrorFormat + +from ... import models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class Operations: + """Operations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~hybrid_connectivity_management_api.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list( + self, + **kwargs + ) -> AsyncIterable["models.OperationListResult"]: + """Lists the available Hybrid Connectivity REST API operations. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either OperationListResult or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~hybrid_connectivity_management_api.models.OperationListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.OperationListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('OperationListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/providers/Microsoft.HybridConnectivity/operations'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/__init__.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/__init__.py new file mode 100644 index 0000000000..a60914d57d --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/__init__.py @@ -0,0 +1,57 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +try: + from ._models_py3 import EndpointAccessResource + from ._models_py3 import EndpointResource + from ._models_py3 import EndpointsList + from ._models_py3 import ErrorAdditionalInfo + from ._models_py3 import ErrorDetail + from ._models_py3 import ErrorResponse + from ._models_py3 import Operation + from ._models_py3 import OperationDisplay + from ._models_py3 import OperationListResult + from ._models_py3 import ProxyResource + from ._models_py3 import Resource +except (SyntaxError, ImportError): + from ._models import EndpointAccessResource # type: ignore + from ._models import EndpointResource # type: ignore + from ._models import EndpointsList # type: ignore + from ._models import ErrorAdditionalInfo # type: ignore + from ._models import ErrorDetail # type: ignore + from ._models import ErrorResponse # type: ignore + from ._models import Operation # type: ignore + from ._models import OperationDisplay # type: ignore + from ._models import OperationListResult # type: ignore + from ._models import ProxyResource # type: ignore + from ._models import Resource # type: ignore + +from ._hybrid_connectivity_management_api_enums import ( + ActionType, + CreatedByType, + Origin, + Type, +) + +__all__ = [ + 'EndpointAccessResource', + 'EndpointResource', + 'EndpointsList', + 'ErrorAdditionalInfo', + 'ErrorDetail', + 'ErrorResponse', + 'Operation', + 'OperationDisplay', + 'OperationListResult', + 'ProxyResource', + 'Resource', + 'ActionType', + 'CreatedByType', + 'Origin', + 'Type', +] diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_hybrid_connectivity_management_api_enums.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_hybrid_connectivity_management_api_enums.py new file mode 100644 index 0000000000..fa857d49db --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_hybrid_connectivity_management_api_enums.py @@ -0,0 +1,58 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from enum import Enum, EnumMeta +from six import with_metaclass + +class _CaseInsensitiveEnumMeta(EnumMeta): + def __getitem__(self, name): + return super().__getitem__(name.upper()) + + def __getattr__(cls, name): + """Return the enum member matching `name` + We use __getattr__ instead of descriptors or inserting into the enum + class' __dict__ in order to support `name` and `value` being both + properties for enum members (which live in the class' __dict__) and + enum members themselves. + """ + try: + return cls._member_map_[name.upper()] + except KeyError: + raise AttributeError(name) + + +class ActionType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """Enum. Indicates the action type. "Internal" refers to actions that are for internal only APIs. + """ + + INTERNAL = "Internal" + +class CreatedByType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The type of identity that created the resource. + """ + + USER = "User" + APPLICATION = "Application" + MANAGED_IDENTITY = "ManagedIdentity" + KEY = "Key" + +class Origin(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The intended executor of the operation; as in Resource Based Access Control (RBAC) and audit + logs UX. Default value is "user,system" + """ + + USER = "user" + SYSTEM = "system" + USER_SYSTEM = "user,system" + +class Type(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The type of endpoint. + """ + + DEFAULT = "default" + CUSTOM = "custom" diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_models.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_models.py new file mode 100644 index 0000000000..1dd6479ee0 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_models.py @@ -0,0 +1,438 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from azure.core.exceptions import HttpResponseError +import msrest.serialization + + +class EndpointAccessResource(msrest.serialization.Model): + """The endpoint access for the target resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param namespace_name: The namespace name. + :type namespace_name: str + :param namespace_name_suffix: The suffix domain name of relay namespace. + :type namespace_name_suffix: str + :param hybrid_connection_name: Azure Relay hybrid connection name for the resource. + :type hybrid_connection_name: str + :ivar access_key: Access key for hybrid connection. + :vartype access_key: str + :param expires_on: The expiration of access key in unix time. + :type expires_on: long + """ + + _validation = { + 'namespace_name': {'max_length': 200, 'min_length': 1}, + 'namespace_name_suffix': {'max_length': 100, 'min_length': 1}, + 'access_key': {'readonly': True}, + } + + _attribute_map = { + 'namespace_name': {'key': 'relay.namespaceName', 'type': 'str'}, + 'namespace_name_suffix': {'key': 'relay.namespaceNameSuffix', 'type': 'str'}, + 'hybrid_connection_name': {'key': 'relay.hybridConnectionName', 'type': 'str'}, + 'access_key': {'key': 'relay.accessKey', 'type': 'str'}, + 'expires_on': {'key': 'relay.expiresOn', 'type': 'long'}, + } + + def __init__( + self, + **kwargs + ): + super(EndpointAccessResource, self).__init__(**kwargs) + self.namespace_name = kwargs.get('namespace_name', None) + self.namespace_name_suffix = kwargs.get('namespace_name_suffix', None) + self.hybrid_connection_name = kwargs.get('hybrid_connection_name', None) + self.access_key = None + self.expires_on = kwargs.get('expires_on', None) + + +class Resource(msrest.serialization.Model): + """Common fields that are returned in the response for all Azure Resource Manager resources. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Resource, self).__init__(**kwargs) + self.id = None + self.name = None + self.type = None + + +class EndpointResource(Resource): + """The endpoint for the target resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param type_properties_type: The type of endpoint. Possible values include: "default", + "custom". + :type type_properties_type: str or ~hybrid_connectivity_management_api.models.Type + :param resource_id: The resource Id of the connectivity endpoint (optional). + :type resource_id: str + :ivar provisioning_state: + :vartype provisioning_state: str + :param created_by: The identity that created the resource. + :type created_by: str + :param created_by_type: The type of identity that created the resource. Possible values + include: "User", "Application", "ManagedIdentity", "Key". + :type created_by_type: str or ~hybrid_connectivity_management_api.models.CreatedByType + :param created_at: The timestamp of resource creation (UTC). + :type created_at: ~datetime.datetime + :param last_modified_by: The identity that last modified the resource. + :type last_modified_by: str + :param last_modified_by_type: The type of identity that last modified the resource. Possible + values include: "User", "Application", "ManagedIdentity", "Key". + :type last_modified_by_type: str or ~hybrid_connectivity_management_api.models.CreatedByType + :param last_modified_at: The timestamp of resource last modification (UTC). + :type last_modified_at: ~datetime.datetime + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'provisioning_state': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'type_properties_type': {'key': 'properties.type', 'type': 'str'}, + 'resource_id': {'key': 'properties.resourceId', 'type': 'str'}, + 'provisioning_state': {'key': 'properties.provisioningState', 'type': 'str'}, + 'created_by': {'key': 'systemData.createdBy', 'type': 'str'}, + 'created_by_type': {'key': 'systemData.createdByType', 'type': 'str'}, + 'created_at': {'key': 'systemData.createdAt', 'type': 'iso-8601'}, + 'last_modified_by': {'key': 'systemData.lastModifiedBy', 'type': 'str'}, + 'last_modified_by_type': {'key': 'systemData.lastModifiedByType', 'type': 'str'}, + 'last_modified_at': {'key': 'systemData.lastModifiedAt', 'type': 'iso-8601'}, + } + + def __init__( + self, + **kwargs + ): + super(EndpointResource, self).__init__(**kwargs) + self.type_properties_type = kwargs.get('type_properties_type', None) + self.resource_id = kwargs.get('resource_id', None) + self.provisioning_state = None + self.created_by = kwargs.get('created_by', None) + self.created_by_type = kwargs.get('created_by_type', None) + self.created_at = kwargs.get('created_at', None) + self.last_modified_by = kwargs.get('last_modified_by', None) + self.last_modified_by_type = kwargs.get('last_modified_by_type', None) + self.last_modified_at = kwargs.get('last_modified_at', None) + + +class EndpointsList(msrest.serialization.Model): + """The list of endpoints. + + :param next_link: The link used to get the next page of endpoints list. + :type next_link: str + :param value: The list of endpoint. + :type value: list[~hybrid_connectivity_management_api.models.EndpointResource] + """ + + _attribute_map = { + 'next_link': {'key': 'nextLink', 'type': 'str'}, + 'value': {'key': 'value', 'type': '[EndpointResource]'}, + } + + def __init__( + self, + **kwargs + ): + super(EndpointsList, self).__init__(**kwargs) + self.next_link = kwargs.get('next_link', None) + self.value = kwargs.get('value', None) + + +class ErrorAdditionalInfo(msrest.serialization.Model): + """The resource management error additional info. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar type: The additional info type. + :vartype type: str + :ivar info: The additional info. + :vartype info: object + """ + + _validation = { + 'type': {'readonly': True}, + 'info': {'readonly': True}, + } + + _attribute_map = { + 'type': {'key': 'type', 'type': 'str'}, + 'info': {'key': 'info', 'type': 'object'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorAdditionalInfo, self).__init__(**kwargs) + self.type = None + self.info = None + + +class ErrorDetail(msrest.serialization.Model): + """The error detail. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar code: The error code. + :vartype code: str + :ivar message: The error message. + :vartype message: str + :ivar target: The error target. + :vartype target: str + :ivar details: The error details. + :vartype details: list[~hybrid_connectivity_management_api.models.ErrorDetail] + :ivar additional_info: The error additional info. + :vartype additional_info: list[~hybrid_connectivity_management_api.models.ErrorAdditionalInfo] + """ + + _validation = { + 'code': {'readonly': True}, + 'message': {'readonly': True}, + 'target': {'readonly': True}, + 'details': {'readonly': True}, + 'additional_info': {'readonly': True}, + } + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'target': {'key': 'target', 'type': 'str'}, + 'details': {'key': 'details', 'type': '[ErrorDetail]'}, + 'additional_info': {'key': 'additionalInfo', 'type': '[ErrorAdditionalInfo]'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorDetail, self).__init__(**kwargs) + self.code = None + self.message = None + self.target = None + self.details = None + self.additional_info = None + + +class ErrorResponse(msrest.serialization.Model): + """Common error response for all Azure Resource Manager APIs to return error details for failed operations. (This also follows the OData error response format.). + + :param error: The error object. + :type error: ~hybrid_connectivity_management_api.models.ErrorDetail + """ + + _attribute_map = { + 'error': {'key': 'error', 'type': 'ErrorDetail'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorResponse, self).__init__(**kwargs) + self.error = kwargs.get('error', None) + + +class Operation(msrest.serialization.Model): + """Details of a REST API operation, returned from the Resource Provider Operations API. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar name: The name of the operation, as per Resource-Based Access Control (RBAC). Examples: + "Microsoft.Compute/virtualMachines/write", "Microsoft.Compute/virtualMachines/capture/action". + :vartype name: str + :ivar is_data_action: Whether the operation applies to data-plane. This is "true" for data- + plane operations and "false" for ARM/control-plane operations. + :vartype is_data_action: bool + :param display: Localized display information for this particular operation. + :type display: ~hybrid_connectivity_management_api.models.OperationDisplay + :ivar origin: The intended executor of the operation; as in Resource Based Access Control + (RBAC) and audit logs UX. Default value is "user,system". Possible values include: "user", + "system", "user,system". + :vartype origin: str or ~hybrid_connectivity_management_api.models.Origin + :ivar action_type: Enum. Indicates the action type. "Internal" refers to actions that are for + internal only APIs. Possible values include: "Internal". + :vartype action_type: str or ~hybrid_connectivity_management_api.models.ActionType + """ + + _validation = { + 'name': {'readonly': True}, + 'is_data_action': {'readonly': True}, + 'origin': {'readonly': True}, + 'action_type': {'readonly': True}, + } + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'is_data_action': {'key': 'isDataAction', 'type': 'bool'}, + 'display': {'key': 'display', 'type': 'OperationDisplay'}, + 'origin': {'key': 'origin', 'type': 'str'}, + 'action_type': {'key': 'actionType', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Operation, self).__init__(**kwargs) + self.name = None + self.is_data_action = None + self.display = kwargs.get('display', None) + self.origin = None + self.action_type = None + + +class OperationDisplay(msrest.serialization.Model): + """Localized display information for this particular operation. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar provider: The localized friendly form of the resource provider name, e.g. "Microsoft + Monitoring Insights" or "Microsoft Compute". + :vartype provider: str + :ivar resource: The localized friendly name of the resource type related to this operation. + E.g. "Virtual Machines" or "Job Schedule Collections". + :vartype resource: str + :ivar operation: The concise, localized friendly name for the operation; suitable for + dropdowns. E.g. "Create or Update Virtual Machine", "Restart Virtual Machine". + :vartype operation: str + :ivar description: The short, localized friendly description of the operation; suitable for + tool tips and detailed views. + :vartype description: str + """ + + _validation = { + 'provider': {'readonly': True}, + 'resource': {'readonly': True}, + 'operation': {'readonly': True}, + 'description': {'readonly': True}, + } + + _attribute_map = { + 'provider': {'key': 'provider', 'type': 'str'}, + 'resource': {'key': 'resource', 'type': 'str'}, + 'operation': {'key': 'operation', 'type': 'str'}, + 'description': {'key': 'description', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationDisplay, self).__init__(**kwargs) + self.provider = None + self.resource = None + self.operation = None + self.description = None + + +class OperationListResult(msrest.serialization.Model): + """A list of REST API operations supported by an Azure Resource Provider. It contains an URL link to get the next set of results. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar value: List of operations supported by the resource provider. + :vartype value: list[~hybrid_connectivity_management_api.models.Operation] + :ivar next_link: URL to get the next set of operation list results (if there are any). + :vartype next_link: str + """ + + _validation = { + 'value': {'readonly': True}, + 'next_link': {'readonly': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Operation]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationListResult, self).__init__(**kwargs) + self.value = None + self.next_link = None + + +class ProxyResource(Resource): + """The resource model definition for a Azure Resource Manager proxy resource. It will not have tags and a location. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(ProxyResource, self).__init__(**kwargs) diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_models_py3.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_models_py3.py new file mode 100644 index 0000000000..9740090572 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/models/_models_py3.py @@ -0,0 +1,464 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +import datetime +from typing import List, Optional, Union + +from azure.core.exceptions import HttpResponseError +import msrest.serialization + +from ._hybrid_connectivity_management_api_enums import * + + +class EndpointAccessResource(msrest.serialization.Model): + """The endpoint access for the target resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :param namespace_name: The namespace name. + :type namespace_name: str + :param namespace_name_suffix: The suffix domain name of relay namespace. + :type namespace_name_suffix: str + :param hybrid_connection_name: Azure Relay hybrid connection name for the resource. + :type hybrid_connection_name: str + :ivar access_key: Access key for hybrid connection. + :vartype access_key: str + :param expires_on: The expiration of access key in unix time. + :type expires_on: long + """ + + _validation = { + 'namespace_name': {'max_length': 200, 'min_length': 1}, + 'namespace_name_suffix': {'max_length': 100, 'min_length': 1}, + 'access_key': {'readonly': True}, + } + + _attribute_map = { + 'namespace_name': {'key': 'relay.namespaceName', 'type': 'str'}, + 'namespace_name_suffix': {'key': 'relay.namespaceNameSuffix', 'type': 'str'}, + 'hybrid_connection_name': {'key': 'relay.hybridConnectionName', 'type': 'str'}, + 'access_key': {'key': 'relay.accessKey', 'type': 'str'}, + 'expires_on': {'key': 'relay.expiresOn', 'type': 'long'}, + } + + def __init__( + self, + *, + namespace_name: Optional[str] = None, + namespace_name_suffix: Optional[str] = None, + hybrid_connection_name: Optional[str] = None, + expires_on: Optional[int] = None, + **kwargs + ): + super(EndpointAccessResource, self).__init__(**kwargs) + self.namespace_name = namespace_name + self.namespace_name_suffix = namespace_name_suffix + self.hybrid_connection_name = hybrid_connection_name + self.access_key = None + self.expires_on = expires_on + + +class Resource(msrest.serialization.Model): + """Common fields that are returned in the response for all Azure Resource Manager resources. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Resource, self).__init__(**kwargs) + self.id = None + self.name = None + self.type = None + + +class EndpointResource(Resource): + """The endpoint for the target resource. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :param type_properties_type: The type of endpoint. Possible values include: "default", + "custom". + :type type_properties_type: str or ~hybrid_connectivity_management_api.models.Type + :param resource_id: The resource Id of the connectivity endpoint (optional). + :type resource_id: str + :ivar provisioning_state: + :vartype provisioning_state: str + :param created_by: The identity that created the resource. + :type created_by: str + :param created_by_type: The type of identity that created the resource. Possible values + include: "User", "Application", "ManagedIdentity", "Key". + :type created_by_type: str or ~hybrid_connectivity_management_api.models.CreatedByType + :param created_at: The timestamp of resource creation (UTC). + :type created_at: ~datetime.datetime + :param last_modified_by: The identity that last modified the resource. + :type last_modified_by: str + :param last_modified_by_type: The type of identity that last modified the resource. Possible + values include: "User", "Application", "ManagedIdentity", "Key". + :type last_modified_by_type: str or ~hybrid_connectivity_management_api.models.CreatedByType + :param last_modified_at: The timestamp of resource last modification (UTC). + :type last_modified_at: ~datetime.datetime + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + 'provisioning_state': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + 'type_properties_type': {'key': 'properties.type', 'type': 'str'}, + 'resource_id': {'key': 'properties.resourceId', 'type': 'str'}, + 'provisioning_state': {'key': 'properties.provisioningState', 'type': 'str'}, + 'created_by': {'key': 'systemData.createdBy', 'type': 'str'}, + 'created_by_type': {'key': 'systemData.createdByType', 'type': 'str'}, + 'created_at': {'key': 'systemData.createdAt', 'type': 'iso-8601'}, + 'last_modified_by': {'key': 'systemData.lastModifiedBy', 'type': 'str'}, + 'last_modified_by_type': {'key': 'systemData.lastModifiedByType', 'type': 'str'}, + 'last_modified_at': {'key': 'systemData.lastModifiedAt', 'type': 'iso-8601'}, + } + + def __init__( + self, + *, + type_properties_type: Optional[Union[str, "Type"]] = None, + resource_id: Optional[str] = None, + created_by: Optional[str] = None, + created_by_type: Optional[Union[str, "CreatedByType"]] = None, + created_at: Optional[datetime.datetime] = None, + last_modified_by: Optional[str] = None, + last_modified_by_type: Optional[Union[str, "CreatedByType"]] = None, + last_modified_at: Optional[datetime.datetime] = None, + **kwargs + ): + super(EndpointResource, self).__init__(**kwargs) + self.type_properties_type = type_properties_type + self.resource_id = resource_id + self.provisioning_state = None + self.created_by = created_by + self.created_by_type = created_by_type + self.created_at = created_at + self.last_modified_by = last_modified_by + self.last_modified_by_type = last_modified_by_type + self.last_modified_at = last_modified_at + + +class EndpointsList(msrest.serialization.Model): + """The list of endpoints. + + :param next_link: The link used to get the next page of endpoints list. + :type next_link: str + :param value: The list of endpoint. + :type value: list[~hybrid_connectivity_management_api.models.EndpointResource] + """ + + _attribute_map = { + 'next_link': {'key': 'nextLink', 'type': 'str'}, + 'value': {'key': 'value', 'type': '[EndpointResource]'}, + } + + def __init__( + self, + *, + next_link: Optional[str] = None, + value: Optional[List["EndpointResource"]] = None, + **kwargs + ): + super(EndpointsList, self).__init__(**kwargs) + self.next_link = next_link + self.value = value + + +class ErrorAdditionalInfo(msrest.serialization.Model): + """The resource management error additional info. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar type: The additional info type. + :vartype type: str + :ivar info: The additional info. + :vartype info: object + """ + + _validation = { + 'type': {'readonly': True}, + 'info': {'readonly': True}, + } + + _attribute_map = { + 'type': {'key': 'type', 'type': 'str'}, + 'info': {'key': 'info', 'type': 'object'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorAdditionalInfo, self).__init__(**kwargs) + self.type = None + self.info = None + + +class ErrorDetail(msrest.serialization.Model): + """The error detail. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar code: The error code. + :vartype code: str + :ivar message: The error message. + :vartype message: str + :ivar target: The error target. + :vartype target: str + :ivar details: The error details. + :vartype details: list[~hybrid_connectivity_management_api.models.ErrorDetail] + :ivar additional_info: The error additional info. + :vartype additional_info: list[~hybrid_connectivity_management_api.models.ErrorAdditionalInfo] + """ + + _validation = { + 'code': {'readonly': True}, + 'message': {'readonly': True}, + 'target': {'readonly': True}, + 'details': {'readonly': True}, + 'additional_info': {'readonly': True}, + } + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'target': {'key': 'target', 'type': 'str'}, + 'details': {'key': 'details', 'type': '[ErrorDetail]'}, + 'additional_info': {'key': 'additionalInfo', 'type': '[ErrorAdditionalInfo]'}, + } + + def __init__( + self, + **kwargs + ): + super(ErrorDetail, self).__init__(**kwargs) + self.code = None + self.message = None + self.target = None + self.details = None + self.additional_info = None + + +class ErrorResponse(msrest.serialization.Model): + """Common error response for all Azure Resource Manager APIs to return error details for failed operations. (This also follows the OData error response format.). + + :param error: The error object. + :type error: ~hybrid_connectivity_management_api.models.ErrorDetail + """ + + _attribute_map = { + 'error': {'key': 'error', 'type': 'ErrorDetail'}, + } + + def __init__( + self, + *, + error: Optional["ErrorDetail"] = None, + **kwargs + ): + super(ErrorResponse, self).__init__(**kwargs) + self.error = error + + +class Operation(msrest.serialization.Model): + """Details of a REST API operation, returned from the Resource Provider Operations API. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar name: The name of the operation, as per Resource-Based Access Control (RBAC). Examples: + "Microsoft.Compute/virtualMachines/write", "Microsoft.Compute/virtualMachines/capture/action". + :vartype name: str + :ivar is_data_action: Whether the operation applies to data-plane. This is "true" for data- + plane operations and "false" for ARM/control-plane operations. + :vartype is_data_action: bool + :param display: Localized display information for this particular operation. + :type display: ~hybrid_connectivity_management_api.models.OperationDisplay + :ivar origin: The intended executor of the operation; as in Resource Based Access Control + (RBAC) and audit logs UX. Default value is "user,system". Possible values include: "user", + "system", "user,system". + :vartype origin: str or ~hybrid_connectivity_management_api.models.Origin + :ivar action_type: Enum. Indicates the action type. "Internal" refers to actions that are for + internal only APIs. Possible values include: "Internal". + :vartype action_type: str or ~hybrid_connectivity_management_api.models.ActionType + """ + + _validation = { + 'name': {'readonly': True}, + 'is_data_action': {'readonly': True}, + 'origin': {'readonly': True}, + 'action_type': {'readonly': True}, + } + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'is_data_action': {'key': 'isDataAction', 'type': 'bool'}, + 'display': {'key': 'display', 'type': 'OperationDisplay'}, + 'origin': {'key': 'origin', 'type': 'str'}, + 'action_type': {'key': 'actionType', 'type': 'str'}, + } + + def __init__( + self, + *, + display: Optional["OperationDisplay"] = None, + **kwargs + ): + super(Operation, self).__init__(**kwargs) + self.name = None + self.is_data_action = None + self.display = display + self.origin = None + self.action_type = None + + +class OperationDisplay(msrest.serialization.Model): + """Localized display information for this particular operation. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar provider: The localized friendly form of the resource provider name, e.g. "Microsoft + Monitoring Insights" or "Microsoft Compute". + :vartype provider: str + :ivar resource: The localized friendly name of the resource type related to this operation. + E.g. "Virtual Machines" or "Job Schedule Collections". + :vartype resource: str + :ivar operation: The concise, localized friendly name for the operation; suitable for + dropdowns. E.g. "Create or Update Virtual Machine", "Restart Virtual Machine". + :vartype operation: str + :ivar description: The short, localized friendly description of the operation; suitable for + tool tips and detailed views. + :vartype description: str + """ + + _validation = { + 'provider': {'readonly': True}, + 'resource': {'readonly': True}, + 'operation': {'readonly': True}, + 'description': {'readonly': True}, + } + + _attribute_map = { + 'provider': {'key': 'provider', 'type': 'str'}, + 'resource': {'key': 'resource', 'type': 'str'}, + 'operation': {'key': 'operation', 'type': 'str'}, + 'description': {'key': 'description', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationDisplay, self).__init__(**kwargs) + self.provider = None + self.resource = None + self.operation = None + self.description = None + + +class OperationListResult(msrest.serialization.Model): + """A list of REST API operations supported by an Azure Resource Provider. It contains an URL link to get the next set of results. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar value: List of operations supported by the resource provider. + :vartype value: list[~hybrid_connectivity_management_api.models.Operation] + :ivar next_link: URL to get the next set of operation list results (if there are any). + :vartype next_link: str + """ + + _validation = { + 'value': {'readonly': True}, + 'next_link': {'readonly': True}, + } + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Operation]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationListResult, self).__init__(**kwargs) + self.value = None + self.next_link = None + + +class ProxyResource(Resource): + """The resource model definition for a Azure Resource Manager proxy resource. It will not have tags and a location. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + """ + + _validation = { + 'id': {'readonly': True}, + 'name': {'readonly': True}, + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(ProxyResource, self).__init__(**kwargs) diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/__init__.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/__init__.py new file mode 100644 index 0000000000..d9149323f4 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/__init__.py @@ -0,0 +1,15 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._operations import Operations +from ._endpoints_operations import EndpointsOperations + +__all__ = [ + 'Operations', + 'EndpointsOperations', +] diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/_endpoints_operations.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/_endpoints_operations.py new file mode 100644 index 0000000000..d591c41d54 --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/_endpoints_operations.py @@ -0,0 +1,185 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.mgmt.core.exceptions import ARMErrorFormat + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class EndpointsOperations(object): + """EndpointsOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~hybrid_connectivity_management_api.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def create_or_update( + self, + resource_group_name, # type: str + machine_name, # type: str + endpoint_name, # type: str + endpoint_resource, # type: "models.EndpointResource" + **kwargs # type: Any + ): + # type: (...) -> "models.EndpointResource" + """Create or update the endpoint to the target resource. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource to + be connected. + :type resource_uri: str + :param endpoint_name: The endpoint name. + :type endpoint_name: str + :param endpoint_resource: Endpoint details. + :type endpoint_resource: ~hybrid_connectivity_management_api.models.EndpointResource + :keyword callable cls: A custom type or function that will be passed the direct response + :return: EndpointResource, or the result of cls(response) + :rtype: ~hybrid_connectivity_management_api.models.EndpointResource + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.EndpointResource"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.create_or_update.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'endpointName': self._serialize.url("endpoint_name", endpoint_name, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(endpoint_resource, 'EndpointResource') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('EndpointResource', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + create_or_update.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/providers/Microsoft.HybridConnectivity/endpoints/{endpointName}'} # type: ignore + + def list_credentials( + self, + resource_group_name, # type: str + machine_name, # type: str + endpoint_name, # type: str + expiresin=10800, # type: Optional[int] + **kwargs # type: Any + ): + # type: (...) -> "models.EndpointAccessResource" + """Gets the endpoint access credentials to the resource. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource to + be connected. + :type resource_uri: str + :param endpoint_name: The endpoint name. + :type endpoint_name: str + :param expiresin: The is how long the endpoint access token is valid (in seconds). + :type expiresin: long + :keyword callable cls: A custom type or function that will be passed the direct response + :return: EndpointAccessResource, or the result of cls(response) + :rtype: ~hybrid_connectivity_management_api.models.EndpointAccessResource + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.EndpointAccessResource"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + accept = "application/json" + + # Construct URL + url = self.list_credentials.metadata['url'] # type: ignore + path_format_arguments = { + 'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str', min_length=1), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), + 'machineName': self._serialize.url("machine_name", machine_name, 'str'), + 'endpointName': self._serialize.url("endpoint_name", endpoint_name, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + if expiresin is not None: + query_parameters['expiresin'] = self._serialize.query("expiresin", expiresin, 'long', maximum=10800, minimum=600) + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.post(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize(models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('EndpointAccessResource', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + list_credentials.metadata = {'url': '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.HybridCompute/machines/{machineName}/providers/Microsoft.HybridConnectivity/endpoints/{endpointName}/listCredentials'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/_operations.py b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/_operations.py new file mode 100644 index 0000000000..02d52e6a4f --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/operations/_operations.py @@ -0,0 +1,110 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse +from azure.mgmt.core.exceptions import ARMErrorFormat + +from .. import models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class Operations(object): + """Operations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~hybrid_connectivity_management_api.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def list( + self, + **kwargs # type: Any + ): + # type: (...) -> Iterable["models.OperationListResult"] + """Lists the available Hybrid Connectivity REST API operations. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either OperationListResult or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~hybrid_connectivity_management_api.models.OperationListResult] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["models.OperationListResult"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-06-preview" + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.list.metadata['url'] # type: ignore + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('OperationListResult', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + error = self._deserialize(models.ErrorResponse, response) + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + list.metadata = {'url': '/providers/Microsoft.HybridConnectivity/operations'} # type: ignore diff --git a/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/py.typed b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/py.typed new file mode 100644 index 0000000000..e5aff4f83a --- /dev/null +++ b/src/ssh/azext_ssh/vendored_sdks/hybridconnectivity/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/src/ssh/setup.py b/src/ssh/setup.py index 1814001980..acf6f7c6c1 100644 --- a/src/ssh/setup.py +++ b/src/ssh/setup.py @@ -7,7 +7,7 @@ from setuptools import setup, find_packages -VERSION = "1.0.1" +VERSION = "1.1.0" CLASSIFIERS = [ 'Development Status :: 4 - Beta', @@ -22,7 +22,8 @@ CLASSIFIERS = [ ] DEPENDENCIES = [ - 'cryptography' + 'cryptography', + 'oschmod==0.3.12' ] setup(