Skip to content

Commit

Permalink
switch to 2019-04-01 api version and enable windows agent pool (Azure…
Browse files Browse the repository at this point in the history
…#612)

* fixing az support for agent pools and mc

* vendor in 2019-04-01 SDK

* enableing windows profile

* merge the latest official SDK

* add secure prompt for windows admin password

* fixing warnings
  • Loading branch information
Xiaofang Zhang authored and tamirkamara committed May 3, 2019
1 parent 5f7e499 commit 859275d
Show file tree
Hide file tree
Showing 70 changed files with 5,333 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/aks-preview/azext_aks_preview/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ContainerServiceCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
register_resource_type('latest', CUSTOM_MGMT_AKS_PREVIEW, '2019-02-01')
register_resource_type('latest', CUSTOM_MGMT_AKS_PREVIEW, '2019-04-01')

acs_custom = CliCommandType(operations_tmpl='azext_aks_preview.custom#{}')
super(ContainerServiceCommandsLoader, self).__init__(cli_ctx=cli_ctx,
Expand Down
2 changes: 1 addition & 1 deletion src/aks-preview/azext_aks_preview/_completers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from azure.cli.core.decorators import Completer

# pylint: disable=line-too-long
from azext_aks_preview.vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ContainerServiceVMSizeTypes
from azext_aks_preview.vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ContainerServiceVMSizeTypes


@Completer
Expand Down
6 changes: 6 additions & 0 deletions src/aks-preview/azext_aks_preview/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@
- name: --admin-username -u
type: string
short-summary: User account to create on node VMs for SSH access.
- name: --windows-admin-username
type: string
short-summary: User account to create on windows node VMs.
- name: --windows-admin-password
type: string
short-summary: User account password to use on windows node VMs.
- name: --aad-client-app-id
type: string
short-summary: (PREVIEW) The ID of an Azure Active Directory client application of type "Native". This
Expand Down
2 changes: 2 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def load_arguments(self, _):
c.argument('name', validator=validate_linux_host_name)
c.argument('kubernetes_version', completer=get_k8s_versions_completion_list)
c.argument('admin_username', options_list=['--admin-username', '-u'], default='azureuser')
c.argument('windows_admin_username', options_list=['--windows-admin-username'])
c.argument('windows_admin_password', options_list=['--windows-admin-password'])
c.argument('dns_name_prefix', options_list=['--dns-name-prefix', '-p'])
c.argument('generate_ssh_keys', action='store_true', validator=validate_create_parameters)
c.argument('node_vm_size', options_list=['--node-vm-size', '-s'], completer=get_vm_size_completion_list)
Expand Down
50 changes: 37 additions & 13 deletions src/aks-preview/azext_aks_preview/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from ipaddress import ip_network
from knack.log import get_logger
from knack.util import CLIError
from knack.prompting import prompt_pass, NoTTYException
import dateutil.parser # pylint: disable=import-error
from dateutil.relativedelta import relativedelta # pylint: disable=import-error
from msrestazure.azure_exceptions import CloudError
Expand All @@ -29,17 +30,18 @@
KeyCredential,
ServicePrincipalCreateParameters,
GetObjectsParameters)
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ContainerServiceLinuxProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ContainerServiceNetworkProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ManagedClusterServicePrincipalProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ContainerServiceSshConfiguration
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ContainerServiceSshPublicKey
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ManagedCluster
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ManagedClusterAADProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ManagedClusterAddonProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ManagedClusterAgentPoolProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import AgentPool
from .vendored_sdks.azure_mgmt_preview_aks.v2019_02_01.models import ContainerServiceStorageProfileTypes
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ContainerServiceLinuxProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ManagedClusterWindowsProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ContainerServiceNetworkProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ManagedClusterServicePrincipalProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ContainerServiceSshConfiguration
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ContainerServiceSshPublicKey
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ManagedCluster
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ManagedClusterAADProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ManagedClusterAddonProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ManagedClusterAgentPoolProfile
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import AgentPool
from .vendored_sdks.azure_mgmt_preview_aks.v2019_04_01.models import ContainerServiceStorageProfileTypes
from ._client_factory import cf_resource_groups
from ._client_factory import get_auth_management_client
from ._client_factory import get_graph_rbac_management_client
Expand Down Expand Up @@ -344,10 +346,13 @@ def _trim_nodepoolname(nodepool_name):


# pylint: disable=too-many-statements
# pylint: disable=too-many-branches
def aks_create(cmd, client, resource_group_name, name, ssh_key_value, # pylint: disable=too-many-locals
dns_name_prefix=None,
location=None,
admin_username="azureuser",
windows_admin_username=None,
windows_admin_password=None,
kubernetes_version='',
node_vm_size="Standard_DS2_v2",
node_osdisk_size=0,
Expand Down Expand Up @@ -421,6 +426,19 @@ def aks_create(cmd, client, resource_group_name, name, ssh_key_value, # pylint:
public_keys=[ContainerServiceSshPublicKey(key_data=ssh_key_value)])
linux_profile = ContainerServiceLinuxProfile(admin_username=admin_username, ssh=ssh_config)

windows_profile = None

if windows_admin_username:
if windows_admin_password is None:
try:
windows_admin_password = prompt_pass(msg='windows-admin-password: ', confirm=True)
except NoTTYException:
raise CLIError('Please specify both username and password in non-interactive mode.')

windows_profile = ManagedClusterWindowsProfile(
admin_username=windows_admin_username,
admin_password=windows_admin_password)

principal_obj = _ensure_aks_service_principal(cmd.cli_ctx,
service_principal=service_principal, client_secret=client_secret,
subscription_id=subscription_id, dns_name_prefix=dns_name_prefix,
Expand Down Expand Up @@ -482,6 +500,7 @@ def aks_create(cmd, client, resource_group_name, name, ssh_key_value, # pylint:
enable_rbac=False if disable_rbac else True,
agent_pool_profiles=[agent_pool_profile],
linux_profile=linux_profile,
windows_profile=windows_profile,
service_principal_profile=service_principal_profile,
network_profile=network_profile,
addon_profiles=addon_profiles,
Expand Down Expand Up @@ -960,7 +979,7 @@ def _check_cluster_autoscaler_flag(enable_cluster_autoscaler,

def _create_client_secret():
# Add a special character to satsify AAD SP secret requirements
special_chars = '!#$%&*-+_.:;<>=?@][^}{|~)('
special_chars = '!#$%&*-+_.:;<>=?@][^}{|~'
special_char = special_chars[ord(os.urandom(1)) % len(special_chars)]
client_secret = binascii.b2a_hex(os.urandom(10)).decode('utf-8') + special_char
return client_secret
Expand Down Expand Up @@ -1015,7 +1034,12 @@ def aks_agentpool_scale(cmd, client, resource_group_name, cluster_name,
node_count=3,
no_wait=False):
instance = client.get(resource_group_name, cluster_name, nodepool_name)
instance.count = int(node_count) # pylint: disable=no-member
new_node_count = int(node_count)
if new_node_count == 0:
raise CLIError("Can't scale down to 0 node.")
if new_node_count == instance.count:
raise CLIError("The new node count is the same as the current node count.")
instance.count = new_node_count # pylint: disable=no-member
return sdk_no_wait(no_wait, client.create_or_update, resource_group_name, cluster_name, nodepool_name, instance)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class ContainerServiceClient(MultiApiClientMixin, SDKClient):
_PROFILE_TAG: {
'open_shift_managed_clusters': '2018-09-30-preview',
'container_services': '2017-07-01',
'managed_clusters': '2019-02-01',
'managed_clusters': '2019-04-01',
'operations': '2018-03-31',
None: DEFAULT_API_VERSION
}},
Expand Down Expand Up @@ -109,6 +109,7 @@ def models(cls, api_version=DEFAULT_API_VERSION):
* 2018-08-01-preview: :mod:`v2018_08_01_preview.models<azure.mgmt.containerservice.v2018_08_01_preview.models>`
* 2018-09-30-preview: :mod:`v2018_09_30_preview.models<azure.mgmt.containerservice.v2018_09_30_preview.models>`
* 2019-02-01: :mod:`v2019_02_01_.models<azure.mgmt.containerservice.v2019_02_01.models>`
* 2019-04-01: :mod:`v2019_04_01_.models<azure.mgmt.containerservice.v2019_04_01.models>`
"""
if api_version == '2017-07-01':
from .v2017_07_01 import models
Expand All @@ -125,17 +126,23 @@ def models(cls, api_version=DEFAULT_API_VERSION):
elif api_version == '2019-02-01':
from .v2019_02_01 import models
return models
elif api_version == '2019-04-01':
from .v2019_04_01 import models
return models
raise NotImplementedError("APIVersion {} is not available".format(api_version))

@property
def agent_pools(self):
"""Instance depends on the API version:
* 2019-02-01: :class:`AgentPoolsOperations<azure.mgmt.containerservice.v2019_02_01.operations.AgentPoolsOperations>`
* 2019-04-01: :class:`AgentPoolsOperations<azure.mgmt.containerservice.v2019_04_01.operations.AgentPoolsOperations>`
"""
api_version = self._get_api_version('agent_pools')
if api_version == '2019-02-01':
from .v2019_02_01.operations import AgentPoolsOperations as OperationClass
elif api_version == '2019-04-01':
from .v2019_04_01.operations import AgentPoolsOperations as OperationClass
else:
raise NotImplementedError("APIVersion {} is not available".format(api_version))
return OperationClass(self._client, self.config, Serializer(self._models_dict(api_version)), Deserializer(self._models_dict(api_version)))
Expand All @@ -160,6 +167,7 @@ def managed_clusters(self):
* 2018-03-31: :class:`ManagedClustersOperations<azure.mgmt.containerservice.v2018_03_31.operations.ManagedClustersOperations>`
* 2018-08-01-preview: :class:`ManagedClustersOperations<azure.mgmt.containerservice.v2018_08_01_preview.operations.ManagedClustersOperations>`
* 2019-02-01: :class:`ManagedClustersOperations<azure.mgmt.containerservice.v2019_02_01.operations.ManagedClustersOperations>`
* 2019-04-01: :class:`ManagedClustersOperations<azure.mgmt.containerservice.v2019_04_01.operations.ManagedClustersOperations>`
"""
api_version = self._get_api_version('managed_clusters')
if api_version == '2018-03-31':
Expand All @@ -168,6 +176,8 @@ def managed_clusters(self):
from .v2018_08_01_preview.operations import ManagedClustersOperations as OperationClass
elif api_version == '2019-02-01':
from .v2019_02_01.operations import ManagedClustersOperations as OperationClass
elif api_version == '2019-04-01':
from .v2019_04_01.operations import ManagedClustersOperations as OperationClass
else:
raise NotImplementedError("APIVersion {} is not available".format(api_version))
return OperationClass(self._client, self.config, Serializer(self._models_dict(api_version)), Deserializer(self._models_dict(api_version)))
Expand All @@ -192,6 +202,7 @@ def operations(self):
* 2018-03-31: :class:`Operations<azure.mgmt.containerservice.v2018_03_31.operations.Operations>`
* 2018-08-01-preview: :class:`Operations<azure.mgmt.containerservice.v2018_08_01_preview.operations.Operations>`
* 2019-02-01: :class:`Operations<azure.mgmt.containerservice.v2019_02_01.operations.Operations>`
* 2019-04-01: :class:`Operations<azure.mgmt.containerservice.v2019_04_01.operations.Operations>`
"""
api_version = self._get_api_version('operations')
if api_version == '2018-03-31':
Expand All @@ -200,6 +211,8 @@ def operations(self):
from .v2018_08_01_preview.operations import Operations as OperationClass
elif api_version == '2019-02-01':
from .v2019_02_01.operations import Operations as OperationClass
elif api_version == '2019-04-01':
from .v2019_04_01.operations import Operations as OperationClass
else:
raise NotImplementedError("APIVersion {} is not available".format(api_version))
return OperationClass(self._client, self.config, Serializer(self._models_dict(api_version)), Deserializer(self._models_dict(api_version)))
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
from .v2018_08_01_preview.models import *
from .v2018_09_30_preview.models import *
from .v2019_02_01.models import *
from .v2019_04_01.models import *
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ class ContainerServiceClient(SDKClient):
:vartype config: ContainerServiceClientConfiguration
:ivar operations: Operations operations
:vartype operations: azure.mgmt.containerservice.v2019_02_01.operations.Operations
:vartype operations: azure.mgmt.containerservice.v2019_04_01.operations.Operations
:ivar managed_clusters: ManagedClusters operations
:vartype managed_clusters: azure.mgmt.containerservice.v2019_02_01.operations.ManagedClustersOperations
:vartype managed_clusters: azure.mgmt.containerservice.v2019_04_01.operations.ManagedClustersOperations
:ivar agent_pools: AgentPools operations
:vartype agent_pools: azure.mgmt.containerservice.v2019_02_01.operations.AgentPoolsOperations
:vartype agent_pools: azure.mgmt.containerservice.v2019_04_01.operations.AgentPoolsOperations
:param credentials: Credentials needed for the client to connect to Azure.
:type credentials: :mod:`A msrestazure Credentials
Expand All @@ -83,7 +83,7 @@ def __init__(
super(ContainerServiceClient, self).__init__(self.config.credentials, self.config)

client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
self.api_version = '2019-02-01'
self.api_version = '2019-04-01'
self._serialize = Serializer(client_models)
self._deserialize = Deserializer(client_models)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 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 .container_service_client import ContainerServiceClient
from .version import VERSION

__all__ = ['ContainerServiceClient']

__version__ = VERSION

Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# 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 msrest.service_client import SDKClient
from msrest import Serializer, Deserializer
from msrestazure import AzureConfiguration
from .version import VERSION
from .operations.operations import Operations
from .operations.managed_clusters_operations import ManagedClustersOperations
from .operations.agent_pools_operations import AgentPoolsOperations
from . import models


class ContainerServiceClientConfiguration(AzureConfiguration):
"""Configuration for ContainerServiceClient
Note that all parameters used to create this instance are saved as instance
attributes.
:param credentials: Credentials needed for the client to connect to Azure.
:type credentials: :mod:`A msrestazure Credentials
object<msrestazure.azure_active_directory>`
:param subscription_id: Subscription credentials which uniquely identify
Microsoft Azure subscription. The subscription ID forms part of the URI
for every service call.
:type subscription_id: str
:param str base_url: Service URL
"""

def __init__(
self, credentials, subscription_id, base_url=None):

if credentials is None:
raise ValueError("Parameter 'credentials' must not be None.")
if subscription_id is None:
raise ValueError("Parameter 'subscription_id' must not be None.")
if not base_url:
base_url = 'https://management.azure.com'

super(ContainerServiceClientConfiguration, self).__init__(base_url)

self.add_user_agent('azure-mgmt-containerservice/{}'.format(VERSION))
self.add_user_agent('Azure-SDK-For-Python')

self.credentials = credentials
self.subscription_id = subscription_id


class ContainerServiceClient(SDKClient):
"""The Container Service Client.
:ivar config: Configuration for client.
:vartype config: ContainerServiceClientConfiguration
:ivar operations: Operations operations
:vartype operations: azure.mgmt.containerservice.v2019_04_01.operations.Operations
:ivar managed_clusters: ManagedClusters operations
:vartype managed_clusters: azure.mgmt.containerservice.v2019_04_01.operations.ManagedClustersOperations
:ivar agent_pools: AgentPools operations
:vartype agent_pools: azure.mgmt.containerservice.v2019_04_01.operations.AgentPoolsOperations
:param credentials: Credentials needed for the client to connect to Azure.
:type credentials: :mod:`A msrestazure Credentials
object<msrestazure.azure_active_directory>`
:param subscription_id: Subscription credentials which uniquely identify
Microsoft Azure subscription. The subscription ID forms part of the URI
for every service call.
:type subscription_id: str
:param str base_url: Service URL
"""

def __init__(
self, credentials, subscription_id, base_url=None):

self.config = ContainerServiceClientConfiguration(credentials, subscription_id, base_url)
super(ContainerServiceClient, self).__init__(self.config.credentials, self.config)

client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}
self.api_version = '2019-04-01'
self._serialize = Serializer(client_models)
self._deserialize = Deserializer(client_models)

self.operations = Operations(
self._client, self.config, self._serialize, self._deserialize)
self.managed_clusters = ManagedClustersOperations(
self._client, self.config, self._serialize, self._deserialize)
self.agent_pools = AgentPoolsOperations(
self._client, self.config, self._serialize, self._deserialize)
Loading

0 comments on commit 859275d

Please sign in to comment.