Hello community,

here is the log from the commit of package azure-cli-acs for openSUSE:Factory 
checked in at 2018-05-13 16:01:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/azure-cli-acs (Old)
 and      /work/SRC/openSUSE:Factory/.azure-cli-acs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "azure-cli-acs"

Sun May 13 16:01:01 2018 rev:3 rq:600030 version:2.0.31

Changes:
--------
--- /work/SRC/openSUSE:Factory/azure-cli-acs/azure-cli-acs.changes      
2018-02-14 09:29:35.603890581 +0100
+++ /work/SRC/openSUSE:Factory/.azure-cli-acs.new/azure-cli-acs.changes 
2018-05-13 16:01:04.647060819 +0200
@@ -1,0 +2,8 @@
+Tue Apr 17 13:32:03 UTC 2018 - adrian.glaub...@suse.com
+
+- New upstream release
+  + Version 2.0.31
+- Move LICENSE.txt from %doc to %license section
+- Update Requires from setup.py
+
+-------------------------------------------------------------------

Old:
----
  azure-cli-acs-2.0.25.tar.gz

New:
----
  azure-cli-acs-2.0.31.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ azure-cli-acs.spec ++++++
--- /var/tmp/diff_new_pack.HImciI/_old  2018-05-13 16:01:05.379034114 +0200
+++ /var/tmp/diff_new_pack.HImciI/_new  2018-05-13 16:01:05.383033968 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           azure-cli-acs
-Version:        2.0.25
+Version:        2.0.31
 Release:        0
 Summary:        Microsoft Azure CLI 'acs' Command Module
 License:        MIT
@@ -35,14 +35,15 @@
 Requires:       azure-cli-core
 Requires:       azure-cli-nspkg
 Requires:       python3-PyYAML
-Requires:       python3-azure-graphrbac >= 0.31.0
-Requires:       python3-azure-mgmt-authorization >= 0.30.0
-Requires:       python3-azure-mgmt-compute >= 3.1.0rc3
-Requires:       python3-azure-mgmt-containerservice >= 3.0.0
+Requires:       python3-azure-graphrbac >= 0.40.0
+Requires:       python3-azure-mgmt-authorization >= 0.40.0
+Requires:       python3-azure-mgmt-compute >= 4.0.0rc1
+Requires:       python3-azure-mgmt-containerservice >= 3.0.1
 Requires:       python3-azure-nspkg
 Requires:       python3-paramiko
 Requires:       python3-scp
 Requires:       python3-six
+Requires:       python3-sshtunnel
 Conflicts:      azure-cli < 2.0.0
 
 BuildArch:      noarch
@@ -71,7 +72,8 @@
 
 %files
 %defattr(-,root,root,-)
-%doc HISTORY.rst LICENSE.txt README.rst
+%doc HISTORY.rst README.rst
+%license LICENSE.txt
 %{python3_sitelib}/azure/cli/command_modules/acs
 %{python3_sitelib}/azure_cli_acs-*.egg-info
 

++++++ azure-cli-acs-2.0.25.tar.gz -> azure-cli-acs-2.0.31.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-acs-2.0.25/HISTORY.rst 
new/azure-cli-acs-2.0.31/HISTORY.rst
--- old/azure-cli-acs-2.0.25/HISTORY.rst        2018-01-26 17:12:23.000000000 
+0100
+++ new/azure-cli-acs-2.0.31/HISTORY.rst        2018-04-06 19:33:13.000000000 
+0200
@@ -3,6 +3,45 @@
 Release History
 ===============
 
+2.0.31
+++++++
+
+* `sdist` is now compatible with wheel 0.31.0
+
+2.0.30
+++++++
+* Minor fixes
+* aks created spn will be valid for 5 years
+
+2.0.29
+++++++
+* fix a certificate verification error for `az aks install-cli` in Cloud Shell 
/ PS
+
+2.0.28
+++++++
+* Support Autorest 3.0 based SDKs
+* warn the user that `az aks browse` won't work in Azure Cloud Shell
+* add `aks upgrade-connector` command to upgrade an existing connector
+* `kubectl` config files are more readable block-style YAML
+
+2.0.27
+++++++
+* use the virtual-kubelet-for-aks helm chart for `aks install-connector` by 
default
+* fix the service principal insufficient permission to create ACI container 
group issue
+* add --aci-container-group, --location, --image-tag optional parameters for 
`aks install-connector`
+* remove deprecation notice from `aks get-versions`
+
+2.0.26
+++++++
+* rename `aks get-versions` to `aks get-upgrades` in the interest of accuracy
+* reimplement `aks get-versions` to show Kubernetes versions available for 
`aks create`
+* `aks create` defaults to letting the server choose the version of Kubernetes
+* update help messages referring to the service principal generated by AKS
+* `aks create` VM node size default changed from "Standard_D1_v2" to 
"Standard_DS1_v2"
+* improve reliability when locating the dashboard pod for `az aks browse`
+* `aks get-credentials` handles UnicodeDecodeError when loading Kubernetes 
configuration files
+* add a message to `az aks install-cli` to help get `kubectl.exe` in the 
search PATH
+
 2.0.25
 ++++++
 * clarify `--disable-browser` argument
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-acs-2.0.25/PKG-INFO 
new/azure-cli-acs-2.0.31/PKG-INFO
--- old/azure-cli-acs-2.0.25/PKG-INFO   2018-01-26 17:12:48.000000000 +0100
+++ new/azure-cli-acs-2.0.31/PKG-INFO   2018-04-06 19:33:32.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: azure-cli-acs
-Version: 2.0.25
+Version: 2.0.31
 Summary: Microsoft Azure Command-Line Tools ACS Command Module
 Home-page: https://github.com/Azure/azure-cli
 Author: Microsoft Corporation
 Author-email: azpy...@microsoft.com
 License: MIT
+Description-Content-Type: UNKNOWN
 Description: Microsoft Azure CLI 'acs' Command Module
         ========================================
         
@@ -18,6 +19,45 @@
         Release History
         ===============
         
+        2.0.31
+        ++++++
+        
+        * `sdist` is now compatible with wheel 0.31.0
+        
+        2.0.30
+        ++++++
+        * Minor fixes
+        * aks created spn will be valid for 5 years
+        
+        2.0.29
+        ++++++
+        * fix a certificate verification error for `az aks install-cli` in 
Cloud Shell / PS
+        
+        2.0.28
+        ++++++
+        * Support Autorest 3.0 based SDKs
+        * warn the user that `az aks browse` won't work in Azure Cloud Shell
+        * add `aks upgrade-connector` command to upgrade an existing connector
+        * `kubectl` config files are more readable block-style YAML
+        
+        2.0.27
+        ++++++
+        * use the virtual-kubelet-for-aks helm chart for `aks 
install-connector` by default
+        * fix the service principal insufficient permission to create ACI 
container group issue
+        * add --aci-container-group, --location, --image-tag optional 
parameters for `aks install-connector`
+        * remove deprecation notice from `aks get-versions`
+        
+        2.0.26
+        ++++++
+        * rename `aks get-versions` to `aks get-upgrades` in the interest of 
accuracy
+        * reimplement `aks get-versions` to show Kubernetes versions available 
for `aks create`
+        * `aks create` defaults to letting the server choose the version of 
Kubernetes
+        * update help messages referring to the service principal generated by 
AKS
+        * `aks create` VM node size default changed from "Standard_D1_v2" to 
"Standard_DS1_v2"
+        * improve reliability when locating the dashboard pod for `az aks 
browse`
+        * `aks get-credentials` handles UnicodeDecodeError when loading 
Kubernetes configuration files
+        * add a message to `az aks install-cli` to help get `kubectl.exe` in 
the search PATH
+        
         2.0.25
         ++++++
         * clarify `--disable-browser` argument
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_client_factory.py 
new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_client_factory.py
--- old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_client_factory.py   
2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_client_factory.py   
2018-04-06 19:33:13.000000000 +0200
@@ -3,13 +3,11 @@
 # Licensed under the MIT License. See License.txt in the project root for 
license information.
 # 
--------------------------------------------------------------------------------------------
 
-from azure.cli.core.commands.client_factory import configure_common_settings
 from azure.cli.core.commands.client_factory import get_mgmt_service_client
+from azure.cli.core.profiles import ResourceType
 
 
 def cf_compute_service(cli_ctx, *_):
-    from azure.cli.core.profiles import ResourceType
-
     return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_COMPUTE)
 
 
@@ -21,6 +19,10 @@
     return get_container_service_client(cli_ctx).managed_clusters
 
 
+def cf_resource_groups(cli_ctx, *_):
+    return get_mgmt_service_client(cli_ctx, 
ResourceType.MGMT_RESOURCE_RESOURCES).resource_groups
+
+
 def get_auth_management_client(cli_ctx, scope=None, **_):
     import re
     from azure.mgmt.authorization import AuthorizationManagementClient
@@ -41,6 +43,7 @@
 
 
 def get_graph_rbac_management_client(cli_ctx, **_):
+    from azure.cli.core.commands.client_factory import 
configure_common_settings
     from azure.cli.core._profile import Profile
     from azure.graphrbac import GraphRbacManagementClient
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_completers.py 
new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_completers.py
--- old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_completers.py       
2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_completers.py       
2018-04-06 19:33:13.000000000 +0200
@@ -5,22 +5,80 @@
 
 from azure.cli.core.commands.parameters import 
get_one_of_subscription_locations
 from azure.cli.core.decorators import Completer
-from azure.mgmt.containerservice.models import ContainerServiceVMSizeTypes
 
-from ._client_factory import cf_compute_service
+
+@Completer
+def get_k8s_upgrades_completion_list(cmd, prefix, namespace, **kwargs):  # 
pylint: disable=unused-argument
+    """Return Kubernetes versions available for upgrading an existing 
cluster."""
+    resource_group = getattr(namespace, 'resource_group_name', None)
+    name = getattr(namespace, 'name', None)
+    return get_k8s_upgrades(cmd.cli_ctx, resource_group, name) if 
resource_group and name else None
+
+
+def get_k8s_upgrades(cli_ctx, resource_group, name):
+    from ._client_factory import cf_managed_clusters
+
+    results = cf_managed_clusters(cli_ctx).get_upgrade_profile(resource_group, 
name).as_dict()
+    return results['control_plane_profile']['upgrades']
+
+
+@Completer
+def get_k8s_versions_completion_list(cmd, prefix, namespace, **kwargs):  # 
pylint: disable=unused-argument
+    """Return Kubernetes versions available for provisioning a new cluster."""
+    location = _get_location(cmd.cli_ctx, namespace)
+    return get_k8s_versions(cmd.cli_ctx, location) if location else None
+
+
+def get_k8s_versions(cli_ctx, location):
+    """Return a list of Kubernetes versions available for a new cluster."""
+    from ._client_factory import cf_container_services
+    from jmespath import search
+
+    results = cf_container_services(cli_ctx).list_orchestrators(location, 
resource_type='managedClusters').as_dict()
+    # Flatten all the "orchestrator_version" fields into one array
+    return search('orchestrators[*].orchestrator_version', results)
 
 
 @Completer
 def get_vm_size_completion_list(cmd, prefix, namespace, **kwargs):  # pylint: 
disable=unused-argument
     """Return the intersection of the VM sizes allowed by the ACS SDK with 
those returned by the Compute Service."""
-    try:
-        location = namespace.location
-    except AttributeError:
-        # TODO: try the resource group's default location before falling back 
to this
-        location = get_one_of_subscription_locations(cmd.cli_ctx)
+    from azure.mgmt.containerservice.models import ContainerServiceVMSizeTypes
+
+    location = _get_location(cmd.cli_ctx, namespace)
     result = get_vm_sizes(cmd.cli_ctx, location)
-    return sorted(set(r.name for r in result) & set(c.value for c in 
ContainerServiceVMSizeTypes))
+    return set(r.name for r in result) & set(c.value for c in 
ContainerServiceVMSizeTypes)
 
 
 def get_vm_sizes(cli_ctx, location):
-    return 
list(cf_compute_service(cli_ctx).virtual_machine_sizes.list(location))
+    from ._client_factory import cf_compute_service
+
+    return cf_compute_service(cli_ctx).virtual_machine_sizes.list(location)
+
+
+def _get_location(cli_ctx, namespace):
+    """
+    Return an Azure location by using an explicit `--location` argument, then 
by `--resource-group`, and
+    finally by the subscription if neither argument was provided.
+    """
+    location = None
+    if getattr(namespace, 'location', None):
+        location = namespace.location
+    elif getattr(namespace, 'resource_group_name', None):
+        location = _get_location_from_resource_group(cli_ctx, 
namespace.resource_group_name)
+    if not location:
+        location = get_one_of_subscription_locations(cli_ctx)
+    return location
+
+
+def _get_location_from_resource_group(cli_ctx, resource_group_name):
+    from ._client_factory import cf_resource_groups
+    from msrestazure.azure_exceptions import CloudError
+
+    try:
+        rg = cf_resource_groups(cli_ctx).get(resource_group_name)
+        return rg.location
+    except CloudError as err:
+        # Print a warning if the user hit [TAB] but the `--resource-group` 
argument was incorrect.
+        # For example: "Warning: Resource group 'bogus' could not be found."
+        from argcomplete import warn
+        warn('Warning: {}'.format(err.message))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_format.py 
new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_format.py
--- old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_format.py   
2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_format.py   
2018-04-06 19:33:13.000000000 +0200
@@ -17,38 +17,66 @@
 
 
 def _aks_table_format(result):
-    # put results in an ordered dict so the headers are predictable
-    table_row = OrderedDict()
-    for k in ['name', 'location', 'resourceGroup', 'kubernetesVersion', 
'provisioningState', 'fqdn']:
-        table_row[k] = result.get(k)
-    return table_row
-
-
-def aks_get_versions_table_format(result):
-    """Format get-versions upgrade results as a summary for display with "-o 
table"."""
-    master = result.get('controlPlaneProfile', {})
-    result['masterVersion'] = master.get('kubernetesVersion', 'unknown')
-    master_upgrades = master.get('upgrades', [])
-    result['masterUpgrades'] = ', '.join(master_upgrades) if master_upgrades 
else 'None available'
-
-    agents = result.get('agentPoolProfiles', [])
-    versions, upgrades = [], []
-    for agent in agents:
-        version = agent.get('kubernetesVersion', 'unknown')
-        agent_upgrades = agent.get('upgrades', [])
-        upgrade = ', '.join(agent_upgrades) if agent_upgrades else 'None 
available'
-        name = agent.get('name')
-        if name:  # multiple agent pools, presumably
-            version = "{}: {}".format(name, version)
-            upgrade = "{}: {}".format(name, upgrades)
-        versions.append(version)
-        upgrades.append(upgrade)
-
-    result['nodePoolVersion'] = ', '.join(versions)
-    result['nodePoolUpgrades'] = ', '.join(upgrades)
-
-    # put results in an ordered dict so the headers are predictable
-    table_row = OrderedDict()
-    for k in ['name', 'resourceGroup', 'masterVersion', 'masterUpgrades', 
'nodePoolVersion', 'nodePoolUpgrades']:
-        table_row[k] = result.get(k)
-    return [table_row]
+    from jmespath import compile as compile_jmes, Options
+
+    parsed = compile_jmes("""{
+        name: name,
+        location: location,
+        resourceGroup: resourceGroup,
+        kubernetesVersion: kubernetesVersion,
+        provisioningState: provisioningState,
+        fqdn: fqdn
+    }""")
+    # use ordered dicts so headers are predictable
+    return parsed.search(result, Options(dict_cls=OrderedDict))
+
+
+def aks_upgrades_table_format(result):
+    """Format get-upgrades results as a summary for display with "-o table"."""
+    from jmespath import compile as compile_jmes, Options
+
+    # This expression assumes there is one node pool, and that the master and 
nodes upgrade in lockstep.
+    parsed = compile_jmes("""{
+        name: name,
+        resourceGroup: resourceGroup,
+        masterVersion: controlPlaneProfile.kubernetesVersion || `unknown`,
+        nodePoolVersion: agentPoolProfiles[0].kubernetesVersion || `unknown`,
+        upgrades: controlPlaneProfile.upgrades || [`None available`] | 
sort_versions(@) | join(`, `, @)
+    }""")
+    # use ordered dicts so headers are predictable
+    return parsed.search(result, Options(dict_cls=OrderedDict, 
custom_functions=_custom_functions()))
+
+
+def aks_versions_table_format(result):
+    """Format get-versions results as a summary for display with "-o table"."""
+    from jmespath import compile as compile_jmes, Options
+
+    parsed = compile_jmes("""orchestrators[].{
+        kubernetesVersion: orchestratorVersion,
+        upgrades: upgrades[].orchestratorVersion || [`None available`] | 
sort_versions(@) | join(`, `, @)
+    }""")
+    # use ordered dicts so headers are predictable
+    results = parsed.search(result, Options(dict_cls=OrderedDict, 
custom_functions=_custom_functions()))
+    return sorted(results, key=lambda x: 
version_to_tuple(x.get('kubernetesVersion')), reverse=True)
+
+
+def version_to_tuple(v):
+    """Quick-and-dirty sort function to handle simple semantic versions like 
1.7.12 or 1.8.7."""
+    return tuple(map(int, (v.split('.'))))
+
+
+def _custom_functions():
+
+    from jmespath import functions
+
+    class CustomFunctions(functions.Functions):  # pylint: 
disable=too-few-public-methods
+
+        @functions.signature({'types': ['array']})
+        def _func_sort_versions(self, s):  # pylint: disable=no-self-use
+            """Custom JMESPath `sort_versions` function that sorts an array of 
strings as software versions."""
+            try:
+                return sorted(s, key=version_to_tuple)
+            except (TypeError, ValueError):  # if it wasn't sortable, return 
the input so the pipeline continues
+                return s
+
+    return CustomFunctions()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_help.py 
new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_help.py
--- old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_help.py     
2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_help.py     
2018-04-06 19:33:13.000000000 +0200
@@ -7,7 +7,8 @@
 
 from knack.help_files import helps
 
-SERVICE_PRINCIPAL_CACHE = os.path.join('$HOME', '.azure', 
'acsServicePrincipal.json')
+ACS_SERVICE_PRINCIPAL_CACHE = os.path.join('$HOME', '.azure', 
'acsServicePrincipal.json')
+AKS_SERVICE_PRINCIPAL_CACHE = os.path.join('$HOME', '.azure', 
'aksServicePrincipal.json')
 
 
 # ACS command help
@@ -64,7 +65,7 @@
                 }}]'
         - name: Create a DCOS cluster with agent-profiles specified from a 
file.
           text: az acs create -g MyResourceGroup -n MyContainerService 
--agent-profiles MyAgentProfiles.json
-""".format(sp_cache=SERVICE_PRINCIPAL_CACHE)
+""".format(sp_cache=ACS_SERVICE_PRINCIPAL_CACHE)
 
 helps['acs dcos'] = """
     type: group
@@ -144,7 +145,7 @@
         - name: --service-principal
           type: string
           short-summary: Service principal used for authentication to Azure 
APIs.
-          long-summary:  If not specified, a new service principal with the 
contributor role is created and cached at
+          long-summary:  If not specified, a new service principal is created 
and cached at
                          {sp_cache} to be used by subsequent `az aks` commands.
         - name: --client-secret
           type: string
@@ -166,7 +167,9 @@
           short-summary: Size in GB of the OS disk for each node in the node 
pool.
         - name: --kubernetes-version -k
           type: string
-          short-summary: Version of Kubernetes to use for creating the 
cluster, such as "1.7.7" or "1.8.2".
+          short-summary: Version of Kubernetes to use for creating the 
cluster, such as "1.7.12" or "1.8.7".
+          populator-commands:
+          - "`az aks get-versions`"
         - name: --ssh-key-value
           type: string
           short-summary: Public key path or key contents to install on node 
VMs for SSH access. For example,
@@ -178,10 +181,10 @@
         - name: Create a Kubernetes cluster with an existing SSH public key.
           text: az aks create -g MyResourceGroup -n MyManagedCluster 
--ssh-key-value /path/to/publickey
         - name: Create a Kubernetes cluster with a specific version.
-          text: az aks create -g MyResourceGroup -n MyManagedCluster 
--kubernetes-version 1.8.1
+          text: az aks create -g MyResourceGroup -n MyManagedCluster 
--kubernetes-version 1.8.7
         - name: Create a Kubernetes cluster with a larger node pool.
           text: az aks create -g MyResourceGroup -n MyManagedCluster 
--node-count 7
-""".format(sp_cache=SERVICE_PRINCIPAL_CACHE)
+""".format(sp_cache=AKS_SERVICE_PRINCIPAL_CACHE)
 
 helps['aks delete'] = """
     type: command
@@ -200,9 +203,14 @@
           short-summary: Kubernetes configuration file to update. Use "-" to 
print YAML to stdout instead.
 """
 
+helps['aks get-upgrades'] = """
+    type: command
+    short-summary: Get the upgrade versions available for a managed Kubernetes 
cluster.
+"""
+
 helps['aks get-versions'] = """
     type: command
-    short-summary: Get versions available to upgrade a managed Kubernetes 
cluster.
+    short-summary: Get the versions available for creating a managed 
Kubernetes cluster.
 """
 
 helps['aks install-cli'] = """
@@ -212,7 +220,7 @@
 
 helps['aks install-connector'] = """
     type: command
-    short-summary: Install the Azure Container Instances (ACI) Connector on a 
managed Kubernetes cluster.
+    short-summary: Install the ACI Connector on a managed Kubernetes cluster.
     parameters:
         - name: --chart-url
           type: string
@@ -226,34 +234,46 @@
         - name: --service-principal
           type: string
           short-summary: Service principal used for authentication to Azure 
APIs.
-          long-summary:  If not specified, a new service principal with the 
contributor role is created and cached at
-                         {sp_cache} to be used by subsequent `az aks` commands.
+          long-summary:  If not specified, use the AKS service principal 
defined in the file
+                         /etc/kubernetes/azure.json on the node which runs the 
virtual kubelet pod.
         - name: --client-secret
           type: string
           short-summary: Secret associated with the service principal. This 
argument is required if
                          `--service-principal` is specified.
+        - name: --image-tag
+          type: string
+          short-summary: The image tag of the virtual kubelet. Use 'latest' if 
it is not specified
+        - name: --aci-resource-group
+          type: string
+          short-summary: The resource group to create the ACI container 
groups. Use the MC_*
+                         resource group if it is not specified.
+        - name: --location
+          type: string
+          short-summary: The location to create the ACI container groups. Use 
the location of the MC_*
+                         resource group if it is not specified.
     examples:
         - name: Install the ACI Connector for Linux to a managed Kubernetes 
cluster.
           text: |-
             az aks install-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
-              --connector-name MyConnector
+              --connector-name aci-connector
         - name: Install the ACI Connector for Windows to a managed Kubernetes 
cluster.
           text: |-
             az aks install-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
-               --connector-name MyConnector --os-type Windows
+               --connector-name aci-connector --os-type Windows
         - name: Install the ACI Connector for both Windows and Linux to a 
managed Kubernetes cluster.
           text: |-
             az aks install-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
-              --connector-name MyConnector --os-type Both
-        - name: Install the ACI Connector using a specific service principal.
+              --connector-name aci-connector --os-type Both
+        - name: Install the ACI Connector using a specific service principal 
in a specific resource group.
           text: |-
             az aks install-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
-              --connector-name MyConnector --service-principal <SPN_ID> 
--client-secret <SPN_SECRET>
-        - name: Install the ACI Connector from a custom Helm chart.
+              --connector-name aci-connector --service-principal <SPN_ID> 
--client-secret <SPN_SECRET> \\
+              --aci-resource-group <ACI resource group>
+        - name: Install the ACI Connector from a custom Helm chart with custom 
tag.
           text: |-
             az aks install-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
-              --connector-name MyConnector --chart-url <CustomURL>
-""".format(sp_cache=SERVICE_PRINCIPAL_CACHE)
+              --connector-name aci-connector --chart-url <CustomURL> 
--image-tag <VirtualKubeletImageTag>
+""".format(sp_cache=AKS_SERVICE_PRINCIPAL_CACHE)
 
 helps['aks list'] = """
     type: command
@@ -301,9 +321,66 @@
     parameters:
         - name: --kubernetes-version -k
           type: string
-          short-summary: Version of Kubernetes to upgrade the cluster to, such 
as "1.7.7" or "1.8.2".
+          short-summary: Version of Kubernetes to upgrade the cluster to, such 
as "1.7.12" or "1.8.7".
           populator-commands:
-          - "`az aks get-versions`"
+          - "`az aks get-upgrades`"
+"""
+
+helps['aks upgrade-connector'] = """
+    type: command
+    short-summary: Upgrade the ACI Connector on a managed Kubernetes cluster.
+    parameters:
+        - name: --chart-url
+          type: string
+          short-summary: URL of a Helm chart that installs ACI Connector.
+        - name: --connector-name
+          type: string
+          short-summary: Name of the ACI Connector.
+        - name: --os-type
+          type: string
+          short-summary: Install support for deploying ACIs of this operating 
system type.
+        - name: --service-principal
+          type: string
+          short-summary: Service principal used for authentication to Azure 
APIs.
+          long-summary:  If not specified, use the AKS service principal 
defined in the file
+                         /etc/kubernetes/azure.json on the node which runs the 
virtual kubelet pod.
+        - name: --client-secret
+          type: string
+          short-summary: Secret associated with the service principal. This 
argument is required if
+                         `--service-principal` is specified.
+        - name: --image-tag
+          type: string
+          short-summary: The image tag of the virtual kubelet. Use 'latest' if 
it is not specified
+        - name: --aci-resource-group
+          type: string
+          short-summary: The resource group to create the ACI container 
groups. Use the MC_*
+                         resource group if it is not specified.
+        - name: --location
+          type: string
+          short-summary: The location to create the ACI container groups. Use 
the location of the MC_*
+                         resource group if it is not specified.
+    examples:
+        - name: Upgrade the ACI Connector for Linux to a managed Kubernetes 
cluster.
+          text: |-
+            az aks upgrade-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
+              --connector-name aci-connector
+        - name: Upgrade the ACI Connector for Windows to a managed Kubernetes 
cluster.
+          text: |-
+            az aks upgrade-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
+               --connector-name aci-connector --os-type Windows
+        - name: Upgrade the ACI Connector for both Windows and Linux to a 
managed Kubernetes cluster.
+          text: |-
+            az aks upgrade-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
+              --connector-name aci-connector --os-type Both
+        - name: Upgrade the ACI Connector to use a specific service principal 
in a specific resource group.
+          text: |-
+            az aks upgrade-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
+              --connector-name aci-connector --service-principal <SPN_ID> 
--client-secret <SPN_SECRET> \\
+              --aci-resource-group <ACI resource group>
+        - name: Upgrade the ACI Connector from a custom Helm chart with custom 
tag.
+          text: |-
+            az aks upgrade-connector --name MyManagedCluster --resource-group 
MyResourceGroup \\
+              --connector-name aci-connector --chart-url <CustomURL> 
--image-tag <VirtualKubeletImageTag>
 """
 
 helps['aks wait'] = """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_params.py 
new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_params.py
--- old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_params.py   
2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_params.py   
2018-04-06 19:33:13.000000000 +0200
@@ -13,7 +13,8 @@
     file_type, get_enum_type, get_resource_name_completion_list, name_type, 
tags_type)
 from azure.cli.core.commands.validators import validate_file_or_dict
 
-from ._completers import get_vm_size_completion_list
+from ._completers import (
+    get_vm_size_completion_list, get_k8s_versions_completion_list, 
get_k8s_upgrades_completion_list)
 from ._validators import (
     validate_create_parameters, validate_k8s_client_version, 
validate_k8s_version, validate_linux_host_name,
     validate_list_of_integers, validate_ssh_key, validate_connector_name)
@@ -21,7 +22,7 @@
 
 aci_connector_os_type = ['Windows', 'Linux', 'Both']
 
-aci_connector_chart_url = 
'https://github.com/virtual-kubelet/virtual-kubelet/raw/master/charts/virtual-kubelet-0.1.0.tgz'
+aci_connector_chart_url = 
'https://github.com/virtual-kubelet/virtual-kubelet/raw/master/charts/virtual-kubelet-for-aks-0.1.3.tgz'
 
 orchestrator_types = ["Custom", "DCOS", "Kubernetes", "Swarm", "DockerCE"]
 
@@ -149,6 +150,7 @@
 
     with self.argument_context('aks create') as c:
         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('dns_name_prefix', options_list=['--dns-name-prefix', '-p'])
         c.argument('generate_ssh_keys', action='store_true', 
validator=validate_create_parameters)
@@ -166,10 +168,12 @@
         c.argument('install_location', 
default=_get_default_install_location('kubectl'))
 
     with self.argument_context('aks install-connector') as c:
+        c.argument('aci_resource_group', help='The resource group to create 
the ACI container groups')
         c.argument('chart_url', default=aci_connector_chart_url, help='URL to 
the chart')
-        c.argument('client_secret',
-                   help='Client secret to use with the service principal for 
making calls to Azure APIs')
+        c.argument('client_secret', help='Client secret to use with the 
service principal for making calls to Azure APIs')
         c.argument('connector_name', help='The name for the ACI Connector', 
validator=validate_connector_name)
+        c.argument('image_tag', help='The image tag of the virtual kubelet')
+        c.argument('location', help='The location to create the ACI container 
groups')
         c.argument('os_type', get_enum_type(aci_connector_os_type), help='The 
OS type of the connector')
         c.argument('service_principal',
                    help='Service principal for making calls into Azure APIs. 
If not set, auto generate a new service principal of Contributor role, and save 
it locally for reusing')
@@ -180,6 +184,19 @@
                    help='Mention if you want to drain/uncordon your 
aci-connector to move your applications')
         c.argument('os_type', get_enum_type(aci_connector_os_type), help='The 
OS type of the connector')
 
+    with self.argument_context('aks upgrade') as c:
+        c.argument('kubernetes_version', 
completer=get_k8s_upgrades_completion_list)
+
+    with self.argument_context('aks upgrade-connector') as c:
+        c.argument('aci_resource_group')
+        c.argument('chart_url', default=aci_connector_chart_url)
+        c.argument('client_secret')
+        c.argument('connector_name', validator=validate_connector_name)
+        c.argument('image_tag')
+        c.argument('location')
+        c.argument('os_type', get_enum_type(aci_connector_os_type))
+        c.argument('service_principal')
+
 
 def _get_default_install_location(exe_name):
     system = platform.system()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_validators.py 
new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_validators.py
--- old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/_validators.py       
2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/_validators.py       
2018-04-06 19:33:13.000000000 +0200
@@ -59,7 +59,7 @@
 
 
 def validate_list_of_integers(string):
-    # extract comma separated list of integers
+    # extract comma-separated list of integers
     return list(map(int, string.split(',')))
 
 
@@ -71,14 +71,16 @@
 
 
 def validate_k8s_version(namespace):
-    """Validates a string as a possible Kubernetes version."""
-    k8s_release_regex = re.compile(r'^[v|V]?(\d+\.\d+\.\d+.*)$')
-    found = k8s_release_regex.findall(namespace.kubernetes_version)
-    if found:
-        namespace.kubernetes_version = found[0]
-    else:
-        raise CLIError('--kubernetes-version should be the full version 
number, '
-                       'such as "1.7.7" or "1.8.1"')
+    """Validates a string as a possible Kubernetes version. An empty string is 
also valid, which tells the server
+    to use its default version."""
+    if namespace.kubernetes_version:
+        k8s_release_regex = re.compile(r'^[v|V]?(\d+\.\d+\.\d+.*)$')
+        found = k8s_release_regex.findall(namespace.kubernetes_version)
+        if found:
+            namespace.kubernetes_version = found[0]
+        else:
+            raise CLIError('--kubernetes-version should be the full version 
number, '
+                           'such as "1.7.12" or "1.8.7"')
 
 
 def validate_k8s_client_version(namespace):
@@ -89,7 +91,7 @@
         namespace.client_version = found[0]
     else:
         raise CLIError('--client-version should be the full version number '
-                       '(such as "1.7.7" or "1.8.1") or "latest"')
+                       '(such as "1.7.12" or "1.8.7") or "latest"')
 
 
 def validate_linux_host_name(namespace):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/commands.py 
new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/commands.py
--- old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/commands.py  
2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/commands.py  
2018-04-06 19:33:13.000000000 +0200
@@ -9,9 +9,10 @@
 
 from ._client_factory import cf_container_services
 from ._client_factory import cf_managed_clusters
-from ._format import aks_get_versions_table_format
 from ._format import aks_list_table_format
 from ._format import aks_show_table_format
+from ._format import aks_upgrades_table_format
+from ._format import aks_versions_table_format
 
 
 def load_command_table(self, _):
@@ -31,7 +32,7 @@
     # ACS base commands
     with self.command_group('acs', container_services_sdk, 
client_factory=cf_container_services) as g:
         g.custom_command('browse', 'acs_browse')
-        g.custom_command('create', 'acs_create', no_wait_param='no_wait',
+        g.custom_command('create', 'acs_create', supports_no_wait=True,
                          table_transformer=deployment_validate_table_format)
         g.command('delete', 'delete', confirmation=True)
         g.custom_command('list', 'list_container_services')
@@ -54,17 +55,21 @@
     # AKS commands
     with self.command_group('aks', managed_clusters_sdk, 
client_factory=cf_managed_clusters) as g:
         g.custom_command('browse', 'aks_browse')
-        g.custom_command('create', 'aks_create', no_wait_param='no_wait')
-        g.command('delete', 'delete', no_wait_param='raw', confirmation=True)
+        g.custom_command('create', 'aks_create', supports_no_wait=True)
+        g.command('delete', 'delete', supports_no_wait=True, confirmation=True)
         g.custom_command('get-credentials', 'aks_get_credentials')
-        g.command('get-versions', 'get_upgrade_profile', 
table_transformer=aks_get_versions_table_format)
+        g.command('get-upgrades', 'get_upgrade_profile', 
table_transformer=aks_upgrades_table_format)
         g.custom_command('install-cli', 'k8s_install_cli', client_factory=None)
         g.custom_command('install-connector', 'k8s_install_connector')
         g.custom_command('list', 'aks_list', 
table_transformer=aks_list_table_format)
         g.custom_command('remove-connector', 'k8s_uninstall_connector')
-        g.custom_command('scale', 'aks_scale', no_wait_param='no_wait')
+        g.custom_command('scale', 'aks_scale', supports_no_wait=True)
         g.custom_command('show', 'aks_show', 
table_transformer=aks_show_table_format)
-        g.custom_command('upgrade', 'aks_upgrade', no_wait_param='no_wait',
+        g.custom_command('upgrade', 'aks_upgrade', supports_no_wait=True,
                          confirmation='Kubernetes may be unavailable during 
cluster upgrades.\n' +
                          'Are you sure you want to perform this operation?')
+        g.custom_command('upgrade-connector', 'k8s_upgrade_connector')
         g.generic_wait_command('wait')
+
+    with self.command_group('aks', container_services_sdk, 
client_factory=cf_container_services) as g:
+        g.custom_command('get-versions', 'aks_get_versions', 
table_transformer=aks_versions_table_format)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/custom.py 
new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/custom.py
--- old/azure-cli-acs-2.0.25/azure/cli/command_modules/acs/custom.py    
2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure/cli/command_modules/acs/custom.py    
2018-04-06 19:33:13.000000000 +0200
@@ -24,15 +24,14 @@
 import time
 import uuid
 import webbrowser
-import yaml
-import dateutil.parser
-from dateutil.relativedelta import relativedelta
 from six.moves.urllib.request import urlopen  # pylint: disable=import-error
 from six.moves.urllib.error import URLError  # pylint: disable=import-error
 
+import yaml
+import dateutil.parser
+from dateutil.relativedelta import relativedelta
 from knack.log import get_logger
 from knack.util import CLIError
-
 from msrestazure.azure_exceptions import CloudError
 
 from azure.cli.command_modules.acs import acs_client, proxy
@@ -41,14 +40,13 @@
 from azure.cli.core._profile import Profile
 from azure.cli.core.commands.client_factory import get_mgmt_service_client
 from azure.cli.core.keys import is_valid_ssh_rsa_public_key
-from azure.cli.core.profiles import ResourceType
-from azure.cli.core.util import shell_safe_json_parse, truncate_text
+from azure.cli.core.util import in_cloud_console, shell_safe_json_parse, 
truncate_text, sdk_no_wait
 from azure.graphrbac.models import (ApplicationCreateParameters,
                                     PasswordCredential,
                                     KeyCredential,
                                     ServicePrincipalCreateParameters,
                                     GetObjectsParameters)
-from azure.mgmt.authorization.models import RoleAssignmentProperties
+from azure.mgmt.authorization.models import RoleAssignmentCreateParameters
 from azure.mgmt.containerservice.models import ContainerServiceAgentPoolProfile
 from azure.mgmt.containerservice.models import ContainerServiceLinuxProfile
 from azure.mgmt.containerservice.models import 
ContainerServiceOrchestratorTypes
@@ -58,9 +56,10 @@
 from azure.mgmt.containerservice.models import 
ContainerServiceStorageProfileTypes
 from azure.mgmt.containerservice.models import ManagedCluster
 
+from ._client_factory import cf_container_services
+from ._client_factory import cf_resource_groups
 from ._client_factory import get_auth_management_client
 from ._client_factory import get_graph_rbac_management_client
-from ._client_factory import cf_container_services
 
 logger = get_logger(__name__)
 
@@ -84,10 +83,6 @@
     return None
 
 
-def _resource_client_factory(cli_ctx):
-    return get_mgmt_service_client(cli_ctx, 
ResourceType.MGMT_RESOURCE_RESOURCES)
-
-
 def wait_then_open(url):
     """
     Waits for a bit then opens a URL.  Useful for waiting for a proxy to come 
up, and then open the URL.
@@ -238,8 +233,11 @@
 
 
 def _ssl_context():
-    if sys.version_info < (3, 4):
-        return ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+    if sys.version_info < (3, 4) or (in_cloud_console() and platform.system() 
== 'Windows'):
+        try:
+            return ssl.SSLContext(ssl.PROTOCOL_TLS)  # added in python 2.7.13 
and 3.6
+        except AttributeError:
+            return ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 
     return ssl.create_default_context()
 
@@ -311,66 +309,98 @@
                  os.stat(install_location).st_mode | stat.S_IXUSR | 
stat.S_IXGRP | stat.S_IXOTH)
     except IOError as ex:
         raise CLIError('Connection error while attempting to download client 
({})'.format(ex))
+    logger.warning('Please ensure that %s is in your search PATH, so the `%s` 
command can be found.',
+                   os.path.dirname(install_location), 
os.path.basename(install_location))
 
 
 def k8s_install_connector(cmd, client, name, resource_group_name, 
connector_name,
                           location=None, service_principal=None, 
client_secret=None,
-                          chart_url=None, os_type='Linux'):
+                          chart_url=None, os_type='Linux', image_tag=None, 
aci_resource_group=None):
+    _k8s_install_or_upgrade_connector("install", cmd, client, name, 
resource_group_name, connector_name,
+                                      location, service_principal, 
client_secret, chart_url, os_type,
+                                      image_tag, aci_resource_group)
+
+
+def k8s_upgrade_connector(cmd, client, name, resource_group_name, 
connector_name,
+                          location=None, service_principal=None, 
client_secret=None,
+                          chart_url=None, os_type='Linux', image_tag=None, 
aci_resource_group=None):
+    _k8s_install_or_upgrade_connector("upgrade", cmd, client, name, 
resource_group_name, connector_name,
+                                      location, service_principal, 
client_secret, chart_url, os_type,
+                                      image_tag, aci_resource_group)
+
+
+def _k8s_install_or_upgrade_connector(helm_cmd, cmd, client, name, 
resource_group_name, connector_name,
+                                      location, service_principal, 
client_secret, chart_url, os_type,
+                                      image_tag, aci_resource_group):
     from subprocess import PIPE, Popen
     helm_not_installed = 'Helm not detected, please verify if it is installed.'
     node_prefix = 'virtual-kubelet-' + connector_name.lower()
     url_chart = chart_url
+    if image_tag is None:
+        image_tag = 'latest'
     # Check if Helm is installed locally
     try:
         Popen(["helm"], stdout=PIPE, stderr=PIPE)
     except OSError:
         raise CLIError(helm_not_installed)
+    # If SPN is specified, the secret should also be specified
+    if service_principal is not None and client_secret is None:
+        raise CLIError('--client-secret must be specified when 
--service-principal is specified')
     # Validate if the RG exists
-    groups = _resource_client_factory(cmd.cli_ctx).resource_groups
+    groups = cf_resource_groups(cmd.cli_ctx)
+    if aci_resource_group is None:
+        aci_resource_group = resource_group_name
     # Just do the get, we don't need the result, it will error out if the 
group doesn't exist.
-    rgkaci = groups.get(resource_group_name)
+    rgkaci = groups.get(aci_resource_group)
     # Auto assign the location
     if location is None:
         location = rgkaci.location  # pylint:disable=no-member
+    # Validate the location upon the ACI avaiable regions
+    _validate_aci_location(location)
     # Get the credentials from a AKS instance
     _, browse_path = tempfile.mkstemp()
     aks_get_credentials(cmd, client, resource_group_name, name, admin=False, 
path=browse_path)
     subscription_id = _get_subscription_id(cmd.cli_ctx)
-    dns_name_prefix = _get_default_dns_prefix(connector_name, 
resource_group_name, subscription_id)
-    # Ensure that the SPN exists
-    principal_obj = _ensure_aks_service_principal(cmd.cli_ctx, 
service_principal, client_secret, subscription_id,
-                                                  dns_name_prefix, location, 
connector_name)
-    client_secret = principal_obj.get('client_secret')
-    service_principal = principal_obj.get('service_principal')
     # Get the TenantID
     profile = Profile(cli_ctx=cmd.cli_ctx)
     _, _, tenant_id = profile.get_login_credentials()
     # Check if we want the linux connector
     if os_type.lower() in ['linux', 'both']:
-        _helm_install_aci_connector(url_chart, connector_name, 
service_principal, client_secret,
-                                    subscription_id, tenant_id, rgkaci.name, 
location,
-                                    node_prefix + '-linux', 'Linux')
+        _helm_install_or_upgrade_aci_connector(helm_cmd, image_tag, url_chart, 
connector_name, service_principal,
+                                               client_secret, subscription_id, 
tenant_id, rgkaci.name, location,
+                                               node_prefix + '-linux', 'Linux')
 
     # Check if we want the windows connector
     if os_type.lower() in ['windows', 'both']:
-        _helm_install_aci_connector(url_chart, connector_name, 
service_principal, client_secret,
-                                    subscription_id, tenant_id, rgkaci.name, 
location,
-                                    node_prefix + '-win', 'Windows')
+        _helm_install_or_upgrade_aci_connector(helm_cmd, image_tag, url_chart, 
connector_name, service_principal,
+                                               client_secret, subscription_id, 
tenant_id, rgkaci.name, location,
+                                               node_prefix + '-win', 'Windows')
 
 
-def _helm_install_aci_connector(url_chart, connector_name, service_principal, 
client_secret,
-                                subscription_id, tenant_id, 
aci_resource_group, aci_region,
-                                node_name, os_type):
-    image_tag = 'latest'
+def _helm_install_or_upgrade_aci_connector(helm_cmd, image_tag, url_chart, 
connector_name, service_principal,
+                                           client_secret, subscription_id, 
tenant_id, aci_resource_group,
+                                           aci_region, node_name, os_type):
     node_taint = 'azure.com/aci'
     helm_release_name = connector_name.lower() + "-" + os_type.lower()
     logger.warning("Deploying the ACI connector for '%s' using Helm", os_type)
     try:
-        subprocess.call(["helm", "install", url_chart, "--name", 
helm_release_name, "--set", "env.azureClientId=" +
-                         service_principal + ",env.azureClientKey=" + 
client_secret + ",env.azureSubscriptionId=" +
-                         subscription_id + ",env.azureTenantId=" + tenant_id + 
",env.aciResourceGroup=" +
-                         aci_resource_group + ",env.aciRegion=" + aci_region + 
",image.tag=" + image_tag +
-                         ",env.nodeName=" + node_name + ",env.nodeTaint=" + 
node_taint + ",env.nodeOsType=" + os_type])
+        values = 
('env.nodeName={},env.nodeTaint={},env.nodeOsType={},image.tag={},' +
+                  'env.aciResourceGroup={},env.aciRegion={}').format(
+                      node_name, node_taint, os_type, image_tag, 
aci_resource_group, aci_region)
+
+        if service_principal:
+            values += ",env.azureClientId=" + service_principal
+        if client_secret:
+            values += ",env.azureClientKey=" + client_secret
+        if subscription_id:
+            values += ",env.azureSubscriptionId=" + subscription_id
+        if tenant_id:
+            values += ",env.azureTenantId=" + tenant_id
+
+        if helm_cmd == "install":
+            subprocess.call(["helm", "install", url_chart, "--name", 
helm_release_name, "--set", values])
+        elif helm_cmd == "upgrade":
+            subprocess.call(["helm", "upgrade", helm_release_name, url_chart, 
"--set", values])
     except subprocess.CalledProcessError as err:
         raise CLIError('Could not deploy the ACI connector Chart: 
{}'.format(err))
 
@@ -409,7 +439,7 @@
 
         try:
             drain_node = subprocess.check_output(
-                ['kubectl', 'drain', node_name, '--force'],
+                ['kubectl', 'drain', node_name, '--force', 
'--delete-local-data'],
                 universal_newlines=True)
 
             if not drain_node:
@@ -419,6 +449,14 @@
             raise CLIError('Could not find the node, make sure you' +
                            ' are using the correct --os-type option: 
{}'.format(err))
 
+        try:
+            subprocess.check_output(
+                ['kubectl', 'delete', 'node', node_name],
+                universal_newlines=True)
+        except subprocess.CalledProcessError as err:
+            raise CLIError('Could not delete the node, make sure you' +
+                           ' are using the correct --os-type option: 
{}'.format(err))
+
     logger.warning("Undeploying the '%s' using Helm", helm_release_name)
     try:
         subprocess.call(['helm', 'del', helm_release_name, '--purge'])
@@ -431,7 +469,11 @@
     hook = cli_ctx.get_progress_controller(True)
     hook.add(messsage='Creating service principal', value=0, total_val=1.0)
     logger.info('Creating service principal')
-    result = create_application(rbac_client.applications, name, url, [url], 
password=client_secret)
+    # always create application with 5 years expiration
+    start_date = datetime.datetime.utcnow()
+    end_date = start_date + relativedelta(years=5)
+    result = create_application(rbac_client.applications, name, url, [url], 
password=client_secret,
+                                start_date=start_date, end_date=end_date)
     service_principal = result.app_id  # pylint: disable=no-member
     for x in range(0, 10):
         hook.add(message='Creating service principal', value=0.1 * x, 
total_val=1.0)
@@ -708,7 +750,7 @@
     if not dns_name_prefix:
         dns_name_prefix = _get_default_dns_prefix(name, resource_group_name, 
subscription_id)
 
-    groups = _resource_client_factory(cmd.cli_ctx).resource_groups
+    groups = cf_resource_groups(cmd.cli_ctx)
     # Just do the get, we don't need the result, it will error out if the 
group doesn't exist.
     rg = groups.get(resource_group_name)
     if location is None:
@@ -864,7 +906,7 @@
         logger.info(json.dumps(template, indent=2))
         logger.info('==== END TEMPLATE ====')
         return smc.validate(resource_group_name, deployment_name, properties)
-    return smc.create_or_update(resource_group_name, deployment_name, 
properties, raw=no_wait)
+    return sdk_no_wait(no_wait, smc.create_or_update, resource_group_name, 
deployment_name, properties)
 
 
 def k8s_get_credentials(cmd, client, name, resource_group_name,
@@ -924,28 +966,22 @@
                 existing[key].append(i)
 
 
-def merge_kubernetes_configurations(existing_file, addition_file):
+def load_kubernetes_configuration(filename):
     try:
-        with open(existing_file) as stream:
-            existing = yaml.safe_load(stream)
+        with open(filename) as stream:
+            return yaml.safe_load(stream)
     except (IOError, OSError) as ex:
         if getattr(ex, 'errno', 0) == errno.ENOENT:
-            raise CLIError('{} does not exist'.format(existing_file))
+            raise CLIError('{} does not exist'.format(filename))
         else:
             raise
-    except yaml.parser.ParserError as ex:
-        raise CLIError('Error parsing {} ({})'.format(existing_file, str(ex)))
+    except (yaml.parser.ParserError, UnicodeDecodeError) as ex:
+        raise CLIError('Error parsing {} ({})'.format(filename, str(ex)))
 
-    try:
-        with open(addition_file) as stream:
-            addition = yaml.safe_load(stream)
-    except (IOError, OSError) as ex:
-        if getattr(ex, 'errno', 0) == errno.ENOENT:
-            raise CLIError('{} does not exist'.format(existing_file))
-        else:
-            raise
-    except yaml.parser.ParserError as ex:
-        raise CLIError('Error parsing {} ({})'.format(addition_file, str(ex)))
+
+def merge_kubernetes_configurations(existing_file, addition_file):
+    existing = load_kubernetes_configuration(existing_file)
+    addition = load_kubernetes_configuration(addition_file)
 
     if addition is None:
         raise CLIError('failed to load additional configuration from 
{}'.format(addition_file))
@@ -959,7 +995,7 @@
         existing['current-context'] = addition['current-context']
 
     with open(existing_file, 'w+') as stream:
-        yaml.dump(existing, stream, default_flow_style=True)
+        yaml.dump(existing, stream, default_flow_style=False)
 
     current_context = addition.get('current-context', 'UNKNOWN')
     msg = 'Merged "{}" as current context in {}'.format(current_context, 
existing_file)
@@ -1110,9 +1146,11 @@
     password_creds = None
     key_creds = None
     if password:
-        password_creds = [PasswordCredential(start_date, end_date, 
str(uuid.uuid4()), password)]
+        password_creds = [PasswordCredential(start_date=start_date, 
end_date=end_date,
+                                             key_id=str(uuid.uuid4()), 
value=password)]
     elif key_value:
-        key_creds = [KeyCredential(start_date, end_date, key_value, 
str(uuid.uuid4()), key_usage, key_type)]
+        key_creds = [KeyCredential(start_date=start_date, end_date=end_date, 
value=key_value,
+                                   key_id=str(uuid.uuid4()), usage=key_usage, 
type=key_type)]
 
     return (password_creds, key_creds)
 
@@ -1151,10 +1189,10 @@
 
     role_id = _resolve_role_id(role, scope, definitions_client)
     object_id = _resolve_object_id(cli_ctx, assignee) if resolve_assignee else 
assignee
-    properties = RoleAssignmentProperties(role_id, object_id)
+    parameters = RoleAssignmentCreateParameters(role_definition_id=role_id, 
principal_id=object_id)
     assignment_name = uuid.uuid4()
     custom_headers = None
-    return assignments_client.create(scope, assignment_name, properties, 
custom_headers=custom_headers)
+    return assignments_client.create(scope, assignment_name, parameters, 
custom_headers=custom_headers)
 
 
 def _build_role_scope(resource_group_name, scope, subscription_id):
@@ -1220,6 +1258,9 @@
 
 
 def aks_browse(cmd, client, resource_group_name, name, disable_browser=False):
+    if in_cloud_console():
+        raise CLIError('This command requires a web browser, which is not 
supported in Azure Cloud Shell.')
+
     if not which('kubectl'):
         raise CLIError('Can not find kubectl executable in PATH')
 
@@ -1236,8 +1277,8 @@
     except subprocess.CalledProcessError as err:
         raise CLIError('Could not find dashboard pod: {}'.format(err))
     if dashboard_pod:
-        # remove the "pods/" prefix from the name
-        dashboard_pod = str(dashboard_pod)[5:].strip()
+        # remove any "pods/" or "pod/" prefix from the name
+        dashboard_pod = str(dashboard_pod).split('/')[-1].strip()
     else:
         raise CLIError("Couldn't find the Kubernetes dashboard pod.")
     # launch kubectl port-forward locally to access the remote dashboard
@@ -1253,8 +1294,8 @@
                dns_name_prefix=None,
                location=None,
                admin_username="azureuser",
-               kubernetes_version="1.7.7",
-               node_vm_size="Standard_D1_v2",
+               kubernetes_version='',
+               node_vm_size="Standard_DS1_v2",
                node_osdisk_size=0,
                node_count=3,
                service_principal=None, client_secret=None,
@@ -1272,7 +1313,7 @@
     if not dns_name_prefix:
         dns_name_prefix = _get_default_dns_prefix(name, resource_group_name, 
subscription_id)
 
-    groups = _resource_client_factory(cmd.cli_ctx).resource_groups
+    groups = cf_resource_groups(cmd.cli_ctx)
     # Just do the get, we don't need the result, it will error out if the 
group doesn't exist.
     rg = groups.get(resource_group_name)
     if location is None:
@@ -1314,8 +1355,8 @@
     retry_exception = Exception(None)
     for _ in range(0, max_retry):
         try:
-            return client.create_or_update(
-                resource_group_name=resource_group_name, resource_name=name, 
parameters=mc, raw=no_wait)
+            return sdk_no_wait(no_wait, client.create_or_update,
+                               resource_group_name=resource_group_name, 
resource_name=name, parameters=mc)
         except CloudError as ex:
             retry_exception = ex
             if 'not found in Active Directory tenant' in ex.message:
@@ -1325,6 +1366,10 @@
     raise retry_exception
 
 
+def aks_get_versions(cmd, client, location):
+    return client.list_orchestrators(location, resource_type='managedClusters')
+
+
 def aks_get_credentials(cmd, client, resource_group_name, name, admin=False,
                         path=os.path.join(os.path.expanduser('~'), '.kube', 
'config')):
     access_profile = client.get_access_profiles(
@@ -1359,7 +1404,7 @@
     # null out the service principal because otherwise validation complains
     instance.service_principal_profile = None
 
-    return client.create_or_update(resource_group_name, name, instance, 
raw=no_wait)
+    return sdk_no_wait(no_wait, client.create_or_update, resource_group_name, 
name, instance)
 
 
 def aks_upgrade(cmd, client, resource_group_name, name, kubernetes_version, 
no_wait=False, **kwargs):  # pylint: disable=unused-argument
@@ -1369,7 +1414,7 @@
     # null out the service principal because otherwise validation complains
     instance.service_principal_profile = None
 
-    return client.create_or_update(resource_group_name, name, instance, 
raw=no_wait)
+    return sdk_no_wait(no_wait, client.create_or_update, resource_group_name, 
name, instance)
 
 
 def _ensure_aks_service_principal(cli_ctx,
@@ -1506,3 +1551,19 @@
             if getattr(managed_cluster.service_principal_profile, attr, None) 
is None:
                 delattr(managed_cluster.service_principal_profile, attr)
     return managed_clusters
+
+
+def _validate_aci_location(location):
+    """
+    Validate the Azure Container Instance location
+    """
+    aci_locations = [
+        "westus",
+        "eastus",
+        "westeurope",
+        "southeastasia",
+    ]
+    norm_location = location.replace(" ", "").lower()
+    if norm_location not in aci_locations:
+        raise CLIError('Azure Container Instance is not available at location 
"{}".'.format(location) +
+                       ' The available locations are 
"{}"'.format(','.join(aci_locations)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-acs-2.0.25/azure_cli_acs.egg-info/PKG-INFO 
new/azure-cli-acs-2.0.31/azure_cli_acs.egg-info/PKG-INFO
--- old/azure-cli-acs-2.0.25/azure_cli_acs.egg-info/PKG-INFO    2018-01-26 
17:12:47.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure_cli_acs.egg-info/PKG-INFO    2018-04-06 
19:33:32.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: azure-cli-acs
-Version: 2.0.25
+Version: 2.0.31
 Summary: Microsoft Azure Command-Line Tools ACS Command Module
 Home-page: https://github.com/Azure/azure-cli
 Author: Microsoft Corporation
 Author-email: azpy...@microsoft.com
 License: MIT
+Description-Content-Type: UNKNOWN
 Description: Microsoft Azure CLI 'acs' Command Module
         ========================================
         
@@ -18,6 +19,45 @@
         Release History
         ===============
         
+        2.0.31
+        ++++++
+        
+        * `sdist` is now compatible with wheel 0.31.0
+        
+        2.0.30
+        ++++++
+        * Minor fixes
+        * aks created spn will be valid for 5 years
+        
+        2.0.29
+        ++++++
+        * fix a certificate verification error for `az aks install-cli` in 
Cloud Shell / PS
+        
+        2.0.28
+        ++++++
+        * Support Autorest 3.0 based SDKs
+        * warn the user that `az aks browse` won't work in Azure Cloud Shell
+        * add `aks upgrade-connector` command to upgrade an existing connector
+        * `kubectl` config files are more readable block-style YAML
+        
+        2.0.27
+        ++++++
+        * use the virtual-kubelet-for-aks helm chart for `aks 
install-connector` by default
+        * fix the service principal insufficient permission to create ACI 
container group issue
+        * add --aci-container-group, --location, --image-tag optional 
parameters for `aks install-connector`
+        * remove deprecation notice from `aks get-versions`
+        
+        2.0.26
+        ++++++
+        * rename `aks get-versions` to `aks get-upgrades` in the interest of 
accuracy
+        * reimplement `aks get-versions` to show Kubernetes versions available 
for `aks create`
+        * `aks create` defaults to letting the server choose the version of 
Kubernetes
+        * update help messages referring to the service principal generated by 
AKS
+        * `aks create` VM node size default changed from "Standard_D1_v2" to 
"Standard_DS1_v2"
+        * improve reliability when locating the dashboard pod for `az aks 
browse`
+        * `aks get-credentials` handles UnicodeDecodeError when loading 
Kubernetes configuration files
+        * add a message to `az aks install-cli` to help get `kubectl.exe` in 
the search PATH
+        
         2.0.25
         ++++++
         * clarify `--disable-browser` argument
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-acs-2.0.25/azure_cli_acs.egg-info/requires.txt 
new/azure-cli-acs-2.0.31/azure_cli_acs.egg-info/requires.txt
--- old/azure-cli-acs-2.0.25/azure_cli_acs.egg-info/requires.txt        
2018-01-26 17:12:47.000000000 +0100
+++ new/azure-cli-acs-2.0.31/azure_cli_acs.egg-info/requires.txt        
2018-04-06 19:33:32.000000000 +0200
@@ -1,7 +1,7 @@
-azure-mgmt-authorization==0.30.0
-azure-mgmt-compute==3.1.0rc3
-azure-mgmt-containerservice==3.0.0
-azure-graphrbac==0.31.0
+azure-mgmt-authorization==0.40.0
+azure-mgmt-compute==4.0.0rc1
+azure-mgmt-containerservice==3.0.1
+azure-graphrbac==0.40.0
 azure-cli-core
 paramiko
 pyyaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-acs-2.0.25/setup.py 
new/azure-cli-acs-2.0.31/setup.py
--- old/azure-cli-acs-2.0.25/setup.py   2018-01-26 17:12:23.000000000 +0100
+++ new/azure-cli-acs-2.0.31/setup.py   2018-04-06 19:33:13.000000000 +0200
@@ -14,7 +14,7 @@
     logger.warn("Wheel is not available, disabling bdist_wheel hook")
     cmdclass = {}
 
-VERSION = "2.0.25"
+VERSION = "2.0.31"
 CLASSIFIERS = [
     'Development Status :: 5 - Production/Stable',
     'Intended Audience :: Developers',
@@ -30,10 +30,10 @@
 ]
 
 DEPENDENCIES = [
-    'azure-mgmt-authorization==0.30.0',
-    'azure-mgmt-compute==3.1.0rc3',
-    'azure-mgmt-containerservice==3.0.0',
-    'azure-graphrbac==0.31.0',
+    'azure-mgmt-authorization==0.40.0',
+    'azure-mgmt-compute==4.0.0rc1',
+    'azure-mgmt-containerservice==3.0.1',
+    'azure-graphrbac==0.40.0',
     'azure-cli-core',
     'paramiko',
     'pyyaml',


Reply via email to