From d867f98f134db21e115fd4dce38d5ff3cc9ee347 Mon Sep 17 00:00:00 2001 From: Atharva Mulmuley Date: Tue, 5 Oct 2021 03:18:13 -0700 Subject: [PATCH] Arc Platform GA changes (#3880) * replaced existing GA sdk with 2021-10-01 GA sdk * removed aio, made changes for listclusteruser, moved proxy command to ga * added track-2 sdk * made changes to use v1.3.016682 of CSP and tested the changes on windows * updated csp to 1.3.017131 * updated history.srt and setup.py * lint fix * changed csp storage endpoint to cdn * updated HISTORY.srt * updated setup.py * disabled proxy command in fairfax and bumped version to 1.2.0 * added exception telemetry * minor --- src/connectedk8s/HISTORY.rst | 7 + .../azext_connectedk8s/_constants.py | 9 +- .../azext_connectedk8s/commands.py | 4 +- src/connectedk8s/azext_connectedk8s/custom.py | 15 +- .../vendored_sdks/_configuration.py | 2 +- .../vendored_sdks/_metadata.json | 104 ------------ .../vendored_sdks/_version.py | 2 +- .../vendored_sdks/models/__init__.py | 14 ++ .../_connected_kubernetes_client_enums.py | 7 + .../vendored_sdks/models/_models.py | 141 ++++++++++++++++- .../vendored_sdks/models/_models_py3.py | 148 +++++++++++++++++- .../_connected_cluster_operations.py | 105 +++++++++++-- .../vendored_sdks/operations/_operations.py | 2 +- .../azext_connectedk8s/vendored_sdks/py.typed | 1 - src/connectedk8s/setup.py | 2 +- 15 files changed, 417 insertions(+), 146 deletions(-) delete mode 100644 src/connectedk8s/azext_connectedk8s/vendored_sdks/_metadata.json delete mode 100644 src/connectedk8s/azext_connectedk8s/vendored_sdks/py.typed diff --git a/src/connectedk8s/HISTORY.rst b/src/connectedk8s/HISTORY.rst index 63f1d0ef81d..f4e4636f31f 100644 --- a/src/connectedk8s/HISTORY.rst +++ b/src/connectedk8s/HISTORY.rst @@ -2,6 +2,13 @@ Release History =============== +1.2.0 +++++++ + +* Updated CSP version to 1.3.017131 +* Updated GA SDK to 2021-10-01 +* Updated CSP endpoint to CDN +* Disabled proxy command in fairfax 1.1.11 ++++++ diff --git a/src/connectedk8s/azext_connectedk8s/_constants.py b/src/connectedk8s/azext_connectedk8s/_constants.py index 273473b921a..2e8791c17c8 100644 --- a/src/connectedk8s/azext_connectedk8s/_constants.py +++ b/src/connectedk8s/azext_connectedk8s/_constants.py @@ -111,16 +111,17 @@ Cannot_Create_ClusterRoleBindings_Fault_Type = 'Cannot create cluster role bindings on this Kubernets cluster' CC_Provider_Namespace_Not_Registered_Fault_Type = "Connected Cluster Provider MS.K8 namespace not registered" Default_Namespace_Does_Not_Exist_Fault_Type = "The default namespace defined in the kubeconfig doesn't exist on the kubernetes cluster." -CLIENT_PROXY_VERSION = '1.1.0' +ClusterConnect_Not_Present_Fault_Type = "cluster-connect-feature-unavailable" +CLIENT_PROXY_VERSION = '1.3.017131' API_SERVER_PORT = 47011 CLIENT_PROXY_PORT = 47010 CLIENTPROXY_CLIENT_ID = '04b07795-8ddb-461a-bbee-02f9e1bf7b46' API_CALL_RETRIES = 200 DEFAULT_REQUEST_TIMEOUT = 10 # seconds -RELEASE_DATE_WINDOWS = 'release12-03-21' -RELEASE_DATE_LINUX = 'release12-03-21' +RELEASE_DATE_WINDOWS = 'release13-09-21' +RELEASE_DATE_LINUX = 'release13-09-21' CSP_REFRESH_TIME = 300 # URL constants -CSP_Storage_Url = "https://k8sconnectcsp.blob.core.windows.net" +CSP_Storage_Url = "https://k8sconnectcsp.azureedge.net" HELM_STORAGE_URL = "https://k8connecthelm.azureedge.net" HELM_VERSION = 'v3.6.3' diff --git a/src/connectedk8s/azext_connectedk8s/commands.py b/src/connectedk8s/azext_connectedk8s/commands.py index 6c79422d655..fdd90e19442 100644 --- a/src/connectedk8s/azext_connectedk8s/commands.py +++ b/src/connectedk8s/azext_connectedk8s/commands.py @@ -29,6 +29,8 @@ def load_command_table(self, _): g.custom_command('disable-features', 'disable_features', is_preview=True) g.custom_command('list', 'list_connectedk8s', table_transformer=connectedk8s_list_table_format) g.custom_show_command('show', 'get_connectedk8s', table_transformer=connectedk8s_show_table_format) + g.custom_command('proxy', 'client_side_proxy_wrapper') with self.command_group('connectedk8s', connectedk8s_sdk_prev, client_factory=cf_connected_cluster_prev_2021_04_01) as g: - g.custom_command('proxy', 'client_side_proxy_wrapper', is_preview=True) + pass + # use this block for using preview sdk client for a command diff --git a/src/connectedk8s/azext_connectedk8s/custom.py b/src/connectedk8s/azext_connectedk8s/custom.py index ce43e94a003..6cc93b252d9 100644 --- a/src/connectedk8s/azext_connectedk8s/custom.py +++ b/src/connectedk8s/azext_connectedk8s/custom.py @@ -41,8 +41,7 @@ import azext_connectedk8s._constants as consts import azext_connectedk8s._utils as utils from glob import glob -from .vendored_sdks.models import ConnectedCluster, ConnectedClusterIdentity -from .vendored_sdks.preview_2021_04_01.models import ListClusterUserCredentialsProperties +from .vendored_sdks.models import ConnectedCluster, ConnectedClusterIdentity, ListClusterUserCredentialProperties from threading import Timer, Thread import sys import hashlib @@ -1599,11 +1598,17 @@ def client_side_proxy_wrapper(cmd, context_name=None, api_server_port=consts.API_SERVER_PORT): + cloud = send_cloud_telemetry(cmd) + if cloud == consts.Azure_USGovCloudName: + telemetry.set_debug_info('User tried proxy command in fairfax') + telemetry.set_exception(exception='Proxy command is not present yet in fairfax cloud.', fault_type=consts.ClusterConnect_Not_Present_Fault_Type, + summary=f'User tried proxy command in fairfax.') + raise ClientRequestError(f'Cluster Connect feature is not yet available in {consts.Azure_USGovCloudName}') + client_proxy_port = consts.CLIENT_PROXY_PORT if int(client_proxy_port) == int(api_server_port): raise ClientRequestError('Proxy uses port 47010 internally.', recommendation='Please pass some other unused port through --port option.') - cloud = send_cloud_telemetry(cmd) args = [] operating_system = platform.system() proc_name = f'arcProxy{operating_system}' @@ -1852,11 +1857,11 @@ def client_side_proxy(cmd, # Fetching hybrid connection details from Userrp try: - list_prop = ListClusterUserCredentialsProperties( + list_prop = ListClusterUserCredentialProperties( authentication_method=auth_method, client_proxy=True ) - response = client.list_cluster_user_credentials(resource_group_name, cluster_name, list_prop) + response = client.list_cluster_user_credential(resource_group_name, cluster_name, list_prop) except Exception as e: if flag == 1: clientproxy_process.terminate() diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/_configuration.py b/src/connectedk8s/azext_connectedk8s/vendored_sdks/_configuration.py index 94b86be667a..e19d63e4e4c 100644 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/_configuration.py +++ b/src/connectedk8s/azext_connectedk8s/vendored_sdks/_configuration.py @@ -48,7 +48,7 @@ def __init__( self.credential = credential self.subscription_id = subscription_id - self.api_version = "2021-03-01" + self.api_version = "2021-10-01" self.credential_scopes = kwargs.pop('credential_scopes', ['https://management.azure.com/.default']) kwargs.setdefault('sdk_moniker', 'mgmt-hybridkubernetes/{}'.format(VERSION)) self._configure(**kwargs) diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/_metadata.json b/src/connectedk8s/azext_connectedk8s/vendored_sdks/_metadata.json deleted file mode 100644 index f76dc3a23ee..00000000000 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/_metadata.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "chosen_version": "2021-03-01", - "total_api_version_list": ["2021-03-01"], - "client": { - "name": "ConnectedKubernetesClient", - "filename": "_connected_kubernetes_client", - "description": "Azure Connected Cluster Resource Provider API for adopting any Kubernetes Cluster.", - "base_url": "\u0027https://management.azure.com\u0027", - "custom_base_url": null, - "azure_arm": true, - "has_lro_operations": true, - "client_side_validation": false, - "sync_imports": "{\"typing\": {\"azurecore\": {\"azure.core.credentials\": [\"TokenCredential\"]}}, \"regular\": {\"azurecore\": {\"azure.profiles\": [\"KnownProfiles\", \"ProfileDefinition\"], \"azure.profiles.multiapiclient\": [\"MultiApiClientMixin\"], \"msrest\": [\"Deserializer\", \"Serializer\"], \"azure.mgmt.core\": [\"ARMPipelineClient\"]}, \"local\": {\"._configuration\": [\"ConnectedKubernetesClientConfiguration\"]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\", \"Optional\"]}, \"azurecore\": {\"azure.core.pipeline.transport\": [\"HttpRequest\", \"HttpResponse\"]}}}", - "async_imports": "{\"typing\": {\"azurecore\": {\"azure.core.credentials_async\": [\"AsyncTokenCredential\"]}}, \"regular\": {\"azurecore\": {\"azure.profiles\": [\"KnownProfiles\", \"ProfileDefinition\"], \"azure.profiles.multiapiclient\": [\"MultiApiClientMixin\"], \"msrest\": [\"Deserializer\", \"Serializer\"], \"azure.mgmt.core\": [\"AsyncARMPipelineClient\"]}, \"local\": {\"._configuration\": [\"ConnectedKubernetesClientConfiguration\"]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\", \"Optional\"]}, \"azurecore\": {\"azure.core.pipeline.transport\": [\"AsyncHttpResponse\", \"HttpRequest\"]}}}" - }, - "global_parameters": { - "sync": { - "credential": { - "signature": "credential, # type: \"TokenCredential\"", - "description": "Credential needed for the client to connect to Azure.", - "docstring_type": "~azure.core.credentials.TokenCredential", - "required": true - }, - "subscription_id": { - "signature": "subscription_id, # type: str", - "description": "The ID of the target subscription.", - "docstring_type": "str", - "required": true - } - }, - "async": { - "credential": { - "signature": "credential: \"AsyncTokenCredential\",", - "description": "Credential needed for the client to connect to Azure.", - "docstring_type": "~azure.core.credentials_async.AsyncTokenCredential", - "required": true - }, - "subscription_id": { - "signature": "subscription_id: str,", - "description": "The ID of the target subscription.", - "docstring_type": "str", - "required": true - } - }, - "constant": { - }, - "call": "credential, subscription_id", - "service_client_specific": { - "sync": { - "api_version": { - "signature": "api_version=None, # type: Optional[str]", - "description": "API version to use if no profile is provided, or if missing in profile.", - "docstring_type": "str", - "required": false - }, - "base_url": { - "signature": "base_url=None, # type: Optional[str]", - "description": "Service URL", - "docstring_type": "str", - "required": false - }, - "profile": { - "signature": "profile=KnownProfiles.default, # type: KnownProfiles", - "description": "A profile definition, from KnownProfiles to dict.", - "docstring_type": "azure.profiles.KnownProfiles", - "required": false - } - }, - "async": { - "api_version": { - "signature": "api_version: Optional[str] = None,", - "description": "API version to use if no profile is provided, or if missing in profile.", - "docstring_type": "str", - "required": false - }, - "base_url": { - "signature": "base_url: Optional[str] = None,", - "description": "Service URL", - "docstring_type": "str", - "required": false - }, - "profile": { - "signature": "profile: KnownProfiles = KnownProfiles.default,", - "description": "A profile definition, from KnownProfiles to dict.", - "docstring_type": "azure.profiles.KnownProfiles", - "required": false - } - } - } - }, - "config": { - "credential": true, - "credential_scopes": ["https://management.azure.com/.default"], - "credential_default_policy_type": "BearerTokenCredentialPolicy", - "credential_default_policy_type_has_async_version": true, - "credential_key_header_name": null, - "sync_imports": "{\"regular\": {\"azurecore\": {\"azure.core.configuration\": [\"Configuration\"], \"azure.core.pipeline\": [\"policies\"], \"azure.mgmt.core.policies\": [\"ARMHttpLoggingPolicy\"]}, \"local\": {\"._version\": [\"VERSION\"]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\"]}}, \"typing\": {\"azurecore\": {\"azure.core.credentials\": [\"TokenCredential\"]}}}", - "async_imports": "{\"regular\": {\"azurecore\": {\"azure.core.configuration\": [\"Configuration\"], \"azure.core.pipeline\": [\"policies\"], \"azure.mgmt.core.policies\": [\"ARMHttpLoggingPolicy\"]}, \"local\": {\".._version\": [\"VERSION\"]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\"]}}, \"typing\": {\"azurecore\": {\"azure.core.credentials_async\": [\"AsyncTokenCredential\"]}}}" - }, - "operation_groups": { - "connected_cluster": "ConnectedClusterOperations", - "operations": "Operations" - } -} \ No newline at end of file diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/_version.py b/src/connectedk8s/azext_connectedk8s/vendored_sdks/_version.py index c47f66669f1..e5754a47ce6 100644 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/_version.py +++ b/src/connectedk8s/azext_connectedk8s/vendored_sdks/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "1.0.0" +VERSION = "1.0.0b1" diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/__init__.py b/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/__init__.py index 2c3091d2c8b..85af76a7c2f 100644 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/__init__.py +++ b/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/__init__.py @@ -11,9 +11,13 @@ from ._models_py3 import ConnectedClusterIdentity from ._models_py3 import ConnectedClusterList from ._models_py3 import ConnectedClusterPatch + from ._models_py3 import CredentialResult + from ._models_py3 import CredentialResults from ._models_py3 import ErrorAdditionalInfo from ._models_py3 import ErrorDetail from ._models_py3 import ErrorResponse + from ._models_py3 import HybridConnectionConfig + from ._models_py3 import ListClusterUserCredentialProperties from ._models_py3 import Operation from ._models_py3 import OperationDisplay from ._models_py3 import OperationList @@ -25,9 +29,13 @@ from ._models import ConnectedClusterIdentity # type: ignore from ._models import ConnectedClusterList # type: ignore from ._models import ConnectedClusterPatch # type: ignore + from ._models import CredentialResult # type: ignore + from ._models import CredentialResults # type: ignore from ._models import ErrorAdditionalInfo # type: ignore from ._models import ErrorDetail # type: ignore from ._models import ErrorResponse # type: ignore + from ._models import HybridConnectionConfig # type: ignore + from ._models import ListClusterUserCredentialProperties # type: ignore from ._models import Operation # type: ignore from ._models import OperationDisplay # type: ignore from ._models import OperationList # type: ignore @@ -36,6 +44,7 @@ from ._models import TrackedResource # type: ignore from ._connected_kubernetes_client_enums import ( + AuthenticationMethod, ConnectivityStatus, CreatedByType, LastModifiedByType, @@ -48,15 +57,20 @@ 'ConnectedClusterIdentity', 'ConnectedClusterList', 'ConnectedClusterPatch', + 'CredentialResult', + 'CredentialResults', 'ErrorAdditionalInfo', 'ErrorDetail', 'ErrorResponse', + 'HybridConnectionConfig', + 'ListClusterUserCredentialProperties', 'Operation', 'OperationDisplay', 'OperationList', 'Resource', 'SystemData', 'TrackedResource', + 'AuthenticationMethod', 'ConnectivityStatus', 'CreatedByType', 'LastModifiedByType', diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_connected_kubernetes_client_enums.py b/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_connected_kubernetes_client_enums.py index 84f185bf193..a58b19c6b6c 100644 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_connected_kubernetes_client_enums.py +++ b/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_connected_kubernetes_client_enums.py @@ -26,6 +26,13 @@ def __getattr__(cls, name): raise AttributeError(name) +class AuthenticationMethod(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The mode of client authentication. + """ + + TOKEN = "Token" + AAD = "AAD" + class ConnectivityStatus(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): """Represents the connectivity status of the connected cluster. """ diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_models.py b/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_models.py index 030d3aba956..5d3e787ba82 100644 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_models.py +++ b/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_models.py @@ -281,12 +281,12 @@ class ConnectedClusterPatch(msrest.serialization.Model): :type tags: dict[str, str] :param properties: Describes the connected cluster resource properties that can be updated during PATCH operation. - :type properties: str + :type properties: any """ _attribute_map = { 'tags': {'key': 'tags', 'type': '{str}'}, - 'properties': {'key': 'properties', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'object'}, } def __init__( @@ -298,6 +298,67 @@ def __init__( self.properties = kwargs.get('properties', None) +class CredentialResult(msrest.serialization.Model): + """The credential result response. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar name: The name of the credential. + :vartype name: str + :ivar value: Base64-encoded Kubernetes configuration file. + :vartype value: bytearray + """ + + _validation = { + 'name': {'readonly': True}, + 'value': {'readonly': True}, + } + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'value': {'key': 'value', 'type': 'bytearray'}, + } + + def __init__( + self, + **kwargs + ): + super(CredentialResult, self).__init__(**kwargs) + self.name = None + self.value = None + + +class CredentialResults(msrest.serialization.Model): + """The list of credential result response. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar hybrid_connection_config: Contains the REP (rendezvous endpoint) and “Sender” access + token. + :vartype hybrid_connection_config: ~connected_kubernetes_client.models.HybridConnectionConfig + :ivar kubeconfigs: Base64-encoded Kubernetes configuration file. + :vartype kubeconfigs: list[~connected_kubernetes_client.models.CredentialResult] + """ + + _validation = { + 'hybrid_connection_config': {'readonly': True}, + 'kubeconfigs': {'readonly': True}, + } + + _attribute_map = { + 'hybrid_connection_config': {'key': 'hybridConnectionConfig', 'type': 'HybridConnectionConfig'}, + 'kubeconfigs': {'key': 'kubeconfigs', 'type': '[CredentialResult]'}, + } + + def __init__( + self, + **kwargs + ): + super(CredentialResults, self).__init__(**kwargs) + self.hybrid_connection_config = None + self.kubeconfigs = None + + class ErrorAdditionalInfo(msrest.serialization.Model): """The resource management error additional info. @@ -306,7 +367,7 @@ class ErrorAdditionalInfo(msrest.serialization.Model): :ivar type: The additional info type. :vartype type: str :ivar info: The additional info. - :vartype info: str + :vartype info: any """ _validation = { @@ -316,7 +377,7 @@ class ErrorAdditionalInfo(msrest.serialization.Model): _attribute_map = { 'type': {'key': 'type', 'type': 'str'}, - 'info': {'key': 'info', 'type': 'str'}, + 'info': {'key': 'info', 'type': 'object'}, } def __init__( @@ -392,6 +453,78 @@ def __init__( self.error = kwargs.get('error', None) +class HybridConnectionConfig(msrest.serialization.Model): + """Contains the REP (rendezvous endpoint) and “Sender” access token. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar expiration_time: Timestamp when this token will be expired. + :vartype expiration_time: long + :ivar hybrid_connection_name: Name of the connection. + :vartype hybrid_connection_name: str + :ivar relay: Name of the relay. + :vartype relay: str + :ivar token: Sender access token. + :vartype token: str + """ + + _validation = { + 'expiration_time': {'readonly': True}, + 'hybrid_connection_name': {'readonly': True}, + 'relay': {'readonly': True}, + 'token': {'readonly': True}, + } + + _attribute_map = { + 'expiration_time': {'key': 'expirationTime', 'type': 'long'}, + 'hybrid_connection_name': {'key': 'hybridConnectionName', 'type': 'str'}, + 'relay': {'key': 'relay', 'type': 'str'}, + 'token': {'key': 'token', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(HybridConnectionConfig, self).__init__(**kwargs) + self.expiration_time = None + self.hybrid_connection_name = None + self.relay = None + self.token = None + + +class ListClusterUserCredentialProperties(msrest.serialization.Model): + """ListClusterUserCredentialProperties. + + All required parameters must be populated in order to send to Azure. + + :param authentication_method: Required. The mode of client authentication. Possible values + include: "Token", "AAD". + :type authentication_method: str or ~connected_kubernetes_client.models.AuthenticationMethod + :param client_proxy: Required. Boolean value to indicate whether the request is for client side + proxy or not. + :type client_proxy: bool + """ + + _validation = { + 'authentication_method': {'required': True}, + 'client_proxy': {'required': True}, + } + + _attribute_map = { + 'authentication_method': {'key': 'authenticationMethod', 'type': 'str'}, + 'client_proxy': {'key': 'clientProxy', 'type': 'bool'}, + } + + def __init__( + self, + **kwargs + ): + super(ListClusterUserCredentialProperties, self).__init__(**kwargs) + self.authentication_method = kwargs['authentication_method'] + self.client_proxy = kwargs['client_proxy'] + + class Operation(msrest.serialization.Model): """The Connected cluster API operation. diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_models_py3.py b/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_models_py3.py index 90e1b0bd198..d1208982d77 100644 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_models_py3.py +++ b/src/connectedk8s/azext_connectedk8s/vendored_sdks/models/_models_py3.py @@ -7,7 +7,7 @@ # -------------------------------------------------------------------------- import datetime -from typing import Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union from azure.core.exceptions import HttpResponseError import msrest.serialization @@ -302,19 +302,19 @@ class ConnectedClusterPatch(msrest.serialization.Model): :type tags: dict[str, str] :param properties: Describes the connected cluster resource properties that can be updated during PATCH operation. - :type properties: str + :type properties: any """ _attribute_map = { 'tags': {'key': 'tags', 'type': '{str}'}, - 'properties': {'key': 'properties', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'object'}, } def __init__( self, *, tags: Optional[Dict[str, str]] = None, - properties: Optional[str] = None, + properties: Optional[Any] = None, **kwargs ): super(ConnectedClusterPatch, self).__init__(**kwargs) @@ -322,6 +322,67 @@ def __init__( self.properties = properties +class CredentialResult(msrest.serialization.Model): + """The credential result response. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar name: The name of the credential. + :vartype name: str + :ivar value: Base64-encoded Kubernetes configuration file. + :vartype value: bytearray + """ + + _validation = { + 'name': {'readonly': True}, + 'value': {'readonly': True}, + } + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'value': {'key': 'value', 'type': 'bytearray'}, + } + + def __init__( + self, + **kwargs + ): + super(CredentialResult, self).__init__(**kwargs) + self.name = None + self.value = None + + +class CredentialResults(msrest.serialization.Model): + """The list of credential result response. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar hybrid_connection_config: Contains the REP (rendezvous endpoint) and “Sender” access + token. + :vartype hybrid_connection_config: ~connected_kubernetes_client.models.HybridConnectionConfig + :ivar kubeconfigs: Base64-encoded Kubernetes configuration file. + :vartype kubeconfigs: list[~connected_kubernetes_client.models.CredentialResult] + """ + + _validation = { + 'hybrid_connection_config': {'readonly': True}, + 'kubeconfigs': {'readonly': True}, + } + + _attribute_map = { + 'hybrid_connection_config': {'key': 'hybridConnectionConfig', 'type': 'HybridConnectionConfig'}, + 'kubeconfigs': {'key': 'kubeconfigs', 'type': '[CredentialResult]'}, + } + + def __init__( + self, + **kwargs + ): + super(CredentialResults, self).__init__(**kwargs) + self.hybrid_connection_config = None + self.kubeconfigs = None + + class ErrorAdditionalInfo(msrest.serialization.Model): """The resource management error additional info. @@ -330,7 +391,7 @@ class ErrorAdditionalInfo(msrest.serialization.Model): :ivar type: The additional info type. :vartype type: str :ivar info: The additional info. - :vartype info: str + :vartype info: any """ _validation = { @@ -340,7 +401,7 @@ class ErrorAdditionalInfo(msrest.serialization.Model): _attribute_map = { 'type': {'key': 'type', 'type': 'str'}, - 'info': {'key': 'info', 'type': 'str'}, + 'info': {'key': 'info', 'type': 'object'}, } def __init__( @@ -418,6 +479,81 @@ def __init__( self.error = error +class HybridConnectionConfig(msrest.serialization.Model): + """Contains the REP (rendezvous endpoint) and “Sender” access token. + + Variables are only populated by the server, and will be ignored when sending a request. + + :ivar expiration_time: Timestamp when this token will be expired. + :vartype expiration_time: long + :ivar hybrid_connection_name: Name of the connection. + :vartype hybrid_connection_name: str + :ivar relay: Name of the relay. + :vartype relay: str + :ivar token: Sender access token. + :vartype token: str + """ + + _validation = { + 'expiration_time': {'readonly': True}, + 'hybrid_connection_name': {'readonly': True}, + 'relay': {'readonly': True}, + 'token': {'readonly': True}, + } + + _attribute_map = { + 'expiration_time': {'key': 'expirationTime', 'type': 'long'}, + 'hybrid_connection_name': {'key': 'hybridConnectionName', 'type': 'str'}, + 'relay': {'key': 'relay', 'type': 'str'}, + 'token': {'key': 'token', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(HybridConnectionConfig, self).__init__(**kwargs) + self.expiration_time = None + self.hybrid_connection_name = None + self.relay = None + self.token = None + + +class ListClusterUserCredentialProperties(msrest.serialization.Model): + """ListClusterUserCredentialProperties. + + All required parameters must be populated in order to send to Azure. + + :param authentication_method: Required. The mode of client authentication. Possible values + include: "Token", "AAD". + :type authentication_method: str or ~connected_kubernetes_client.models.AuthenticationMethod + :param client_proxy: Required. Boolean value to indicate whether the request is for client side + proxy or not. + :type client_proxy: bool + """ + + _validation = { + 'authentication_method': {'required': True}, + 'client_proxy': {'required': True}, + } + + _attribute_map = { + 'authentication_method': {'key': 'authenticationMethod', 'type': 'str'}, + 'client_proxy': {'key': 'clientProxy', 'type': 'bool'}, + } + + def __init__( + self, + *, + authentication_method: Union[str, "AuthenticationMethod"], + client_proxy: bool, + **kwargs + ): + super(ListClusterUserCredentialProperties, self).__init__(**kwargs) + self.authentication_method = authentication_method + self.client_proxy = client_proxy + + class Operation(msrest.serialization.Model): """The Connected cluster API operation. diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/operations/_connected_cluster_operations.py b/src/connectedk8s/azext_connectedk8s/vendored_sdks/operations/_connected_cluster_operations.py index 9efeb126fea..2d0390d45d7 100644 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/operations/_connected_cluster_operations.py +++ b/src/connectedk8s/azext_connectedk8s/vendored_sdks/operations/_connected_cluster_operations.py @@ -60,7 +60,7 @@ def _create_initial( 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2021-03-01" + api_version = "2021-10-01" content_type = kwargs.pop("content_type", "application/json") accept = "application/json" @@ -68,7 +68,7 @@ def _create_initial( url = self._create_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, pattern=r'^[-\w\._\(\)]+$'), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), 'clusterName': self._serialize.url("cluster_name", cluster_name, 'str'), } url = self._client.format_url(url, **path_format_arguments) @@ -127,8 +127,8 @@ def begin_create( :type connected_cluster: ~connected_kubernetes_client.models.ConnectedCluster :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: Pass in True if you'd like the ARMPolling polling method, - False for no polling, or your own initialized polling object for a personal polling strategy. + :keyword polling: By default, your polling method will be ARMPolling. + Pass in False for this operation to not poll, or pass in your own initialized polling object for a 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 ConnectedCluster or the result of cls(response) @@ -163,7 +163,7 @@ def get_long_running_output(pipeline_response): 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, pattern=r'^[-\w\._\(\)]+$'), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), 'clusterName': self._serialize.url("cluster_name", cluster_name, 'str'), } @@ -209,7 +209,7 @@ def update( 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2021-03-01" + api_version = "2021-10-01" content_type = kwargs.pop("content_type", "application/json") accept = "application/json" @@ -217,7 +217,7 @@ def update( url = self.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, pattern=r'^[-\w\._\(\)]+$'), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), 'clusterName': self._serialize.url("cluster_name", cluster_name, 'str'), } url = self._client.format_url(url, **path_format_arguments) @@ -277,14 +277,14 @@ def get( 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2021-03-01" + api_version = "2021-10-01" 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, pattern=r'^[-\w\._\(\)]+$'), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), 'clusterName': self._serialize.url("cluster_name", cluster_name, 'str'), } url = self._client.format_url(url, **path_format_arguments) @@ -326,14 +326,14 @@ def _delete_initial( 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2021-03-01" + api_version = "2021-10-01" 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, pattern=r'^[-\w\._\(\)]+$'), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), 'clusterName': self._serialize.url("cluster_name", cluster_name, 'str'), } url = self._client.format_url(url, **path_format_arguments) @@ -377,8 +377,8 @@ def begin_delete( :type cluster_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: Pass in True if you'd like the ARMPolling polling method, - False for no polling, or your own initialized polling object for a personal polling strategy. + :keyword polling: By default, your polling method will be ARMPolling. + Pass in False for this operation to not poll, or pass in your own initialized polling object for a 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) @@ -409,7 +409,7 @@ def get_long_running_output(pipeline_response): 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, pattern=r'^[-\w\._\(\)]+$'), + 'resourceGroupName': self._serialize.url("resource_group_name", resource_group_name, 'str', max_length=90, min_length=1), 'clusterName': self._serialize.url("cluster_name", cluster_name, 'str'), } @@ -427,6 +427,77 @@ def get_long_running_output(pipeline_response): return LROPoller(self._client, raw_result, get_long_running_output, polling_method) begin_delete.metadata = {'url': '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Kubernetes/connectedClusters/{clusterName}'} # type: ignore + def list_cluster_user_credential( + self, + resource_group_name, # type: str + cluster_name, # type: str + properties, # type: "_models.ListClusterUserCredentialProperties" + **kwargs # type: Any + ): + # type: (...) -> "_models.CredentialResults" + """Gets cluster user credentials of a connected cluster. + + Gets cluster user credentials of the connected cluster with a specified resource group and + name. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + :type resource_group_name: str + :param cluster_name: The name of the Kubernetes cluster on which get is called. + :type cluster_name: str + :param properties: ListClusterUserCredential properties. + :type properties: ~connected_kubernetes_client.models.ListClusterUserCredentialProperties + :keyword callable cls: A custom type or function that will be passed the direct response + :return: CredentialResults, or the result of cls(response) + :rtype: ~connected_kubernetes_client.models.CredentialResults + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.CredentialResults"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + api_version = "2021-10-01" + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.list_cluster_user_credential.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), + 'clusterName': self._serialize.url("cluster_name", cluster_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(properties, 'ListClusterUserCredentialProperties') + 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 [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize.failsafe_deserialize(_models.ErrorResponse, response) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + deserialized = self._deserialize('CredentialResults', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + list_cluster_user_credential.metadata = {'url': '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Kubernetes/connectedClusters/{clusterName}/listClusterUserCredential'} # type: ignore + def list_by_resource_group( self, resource_group_name, # type: str @@ -449,7 +520,7 @@ def list_by_resource_group( 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2021-03-01" + api_version = "2021-10-01" accept = "application/json" def prepare_request(next_link=None): @@ -462,7 +533,7 @@ def prepare_request(next_link=None): 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, pattern=r'^[-\w\._\(\)]+$'), + '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 @@ -520,7 +591,7 @@ def list_by_subscription( 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2021-03-01" + api_version = "2021-10-01" accept = "application/json" def prepare_request(next_link=None): diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/operations/_operations.py b/src/connectedk8s/azext_connectedk8s/vendored_sdks/operations/_operations.py index 4effb139b9c..aa3d1b47789 100644 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/operations/_operations.py +++ b/src/connectedk8s/azext_connectedk8s/vendored_sdks/operations/_operations.py @@ -62,7 +62,7 @@ def get( 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError } error_map.update(kwargs.pop('error_map', {})) - api_version = "2021-03-01" + api_version = "2021-10-01" accept = "application/json" def prepare_request(next_link=None): diff --git a/src/connectedk8s/azext_connectedk8s/vendored_sdks/py.typed b/src/connectedk8s/azext_connectedk8s/vendored_sdks/py.typed deleted file mode 100644 index e5aff4f83af..00000000000 --- a/src/connectedk8s/azext_connectedk8s/vendored_sdks/py.typed +++ /dev/null @@ -1 +0,0 @@ -# Marker file for PEP 561. \ No newline at end of file diff --git a/src/connectedk8s/setup.py b/src/connectedk8s/setup.py index d99a5b6bfcf..6223f2dd686 100644 --- a/src/connectedk8s/setup.py +++ b/src/connectedk8s/setup.py @@ -17,7 +17,7 @@ # TODO: Confirm this is the right version number you want and it matches your # HISTORY.rst entry. -VERSION = '1.1.11' +VERSION = '1.2.0' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers