Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch to 2019-04-01 api version and enable windows agent pool #612

Merged
merged 6 commits into from
Apr 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we still writing these import statements with the version hard-coded? This should be using the CLI's profile mechanisms and cmd.get_models(...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, we haven't refactored the code, but should be done in near future. Since it is aks-preview, we should be ok to use the hard-coded version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can refer this PR to refactor Azure/azure-cli#8331

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