Hello community,
here is the log from the commit of package azure-cli-appservice for
openSUSE:Factory checked in at 2018-10-15 10:48:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/azure-cli-appservice (Old)
and /work/SRC/openSUSE:Factory/.azure-cli-appservice.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "azure-cli-appservice"
Mon Oct 15 10:48:32 2018 rev:4 rq:641239 version:0.2.3
Changes:
--------
---
/work/SRC/openSUSE:Factory/azure-cli-appservice/azure-cli-appservice.changes
2018-05-13 16:01:11.998792592 +0200
+++
/work/SRC/openSUSE:Factory/.azure-cli-appservice.new/azure-cli-appservice.changes
2018-10-15 10:48:40.315054857 +0200
@@ -1,0 +2,9 @@
+Mon Sep 17 08:46:56 UTC 2018 - John Paul Adrian Glaubitz
<[email protected]>
+
+- New upstream release
+ + Version 0.2.3
+ + For detailed information about changes see the
+ HISTORY.txt file provided with this package
+- Update Requires from setup.py
+
+-------------------------------------------------------------------
Old:
----
azure-cli-appservice-0.1.31.tar.gz
New:
----
azure-cli-appservice-0.2.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ azure-cli-appservice.spec ++++++
--- /var/tmp/diff_new_pack.erWThY/_old 2018-10-15 10:48:41.055054068 +0200
+++ /var/tmp/diff_new_pack.erWThY/_new 2018-10-15 10:48:41.083054038 +0200
@@ -12,12 +12,12 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
Name: azure-cli-appservice
-Version: 0.1.31
+Version: 0.2.3
Release: 0
Summary: Microsoft Azure CLI 'appservice' Command Module
License: MIT
@@ -34,10 +34,12 @@
Requires: azure-cli-command-modules-nspkg
Requires: azure-cli-core
Requires: azure-cli-nspkg
-Requires: python3-azure-mgmt-containerregistry >= 1.0.1
+Requires: python3-azure-mgmt-containerregistry >= 2.1.0
+Requires: python3-azure-mgmt-storage >= 2.0.0
Requires: python3-azure-mgmt-web >= 0.35.0
Requires: python3-azure-nspkg
Requires: python3-pyOpenSSL
+Requires: python3-six
Requires: python3-urllib3 >= 1.18
Requires: python3-xmltodict
Conflicts: azure-cli < 2.0.0
++++++ azure-cli-appservice-0.1.31.tar.gz -> azure-cli-appservice-0.2.3.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure-cli-appservice-0.1.31/HISTORY.rst
new/azure-cli-appservice-0.2.3/HISTORY.rst
--- old/azure-cli-appservice-0.1.31/HISTORY.rst 2018-04-06 19:33:13.000000000
+0200
+++ new/azure-cli-appservice-0.2.3/HISTORY.rst 2018-08-23 01:07:57.000000000
+0200
@@ -2,6 +2,52 @@
Release History
===============
+
+0.2.3
++++++
+* support CORS on functionapp & webapp
+* arm tag support on create commands
+* `webapp/functionapp identity show`: exception handling to exit with code 3
upon a missing resource for consistency
+
+0.2.2
++++++
+* fix a bug that prevent from creating a function-app using storage accounts
in external resource groups
+* fix a crash on zip deployment
+
+0.2.1
++++++
+* Minor fixes.
+
+0.2.0
++++++
+* BREAKING CHANGE: 'show' commands log error message and fail with exit code
of 3 upon a missing resource.
+* appservice: allow PremiumV2 skus
+
+0.1.36
+++++++
+* webapp/functionapp: Adding support for disabling identity az webapp identity
remove. Preview tag removed for Identity feature.
+
+0.1.35
+++++++
+* dependencies: remove the cap on the urllib as newer requests was released
+* functionapp create: support to use appservice plan from external resource
groups
+
+0.1.34
+++++++
+* dependencies: cap the urllib to 1.22 to avoid conflit with requests 2.18.4
+
+0.1.33
+++++++
+* webapp/functionapp: improve generic update commands
+* webapp/functionapp: webapp deployment source config-zip supports async
operation with status updates for long running operation
+
+0.1.32
+++++++
+* webapp: fix a bug in `az webapp delete` when `--slot` is provided
+* webapp: remove `--runtime-version` from `az webapp auth update` as it's not
very public ready
+* webapp: az webapp config set support for min_tls_version & https2.0
+* webapp: az webapp create support for multicontainers
+
0.1.31
++++++
* (Breaking change): remove `assign-identity` which was tagged `deprecating` 2
releases ago
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure-cli-appservice-0.1.31/PKG-INFO
new/azure-cli-appservice-0.2.3/PKG-INFO
--- old/azure-cli-appservice-0.1.31/PKG-INFO 2018-04-06 19:33:30.000000000
+0200
+++ new/azure-cli-appservice-0.2.3/PKG-INFO 2018-08-23 01:09:29.000000000
+0200
@@ -1,12 +1,11 @@
Metadata-Version: 1.1
Name: azure-cli-appservice
-Version: 0.1.31
+Version: 0.2.3
Summary: Microsoft Azure Command-Line Tools AppService Command Module
Home-page: https://github.com/Azure/azure-cli
Author: Microsoft Corporation
Author-email: [email protected]
License: MIT
-Description-Content-Type: UNKNOWN
Description: Microsoft Azure CLI 'appservice' Command Module
===============================================
@@ -20,6 +19,52 @@
Release History
===============
+
+ 0.2.3
+ +++++
+ * support CORS on functionapp & webapp
+ * arm tag support on create commands
+ * `webapp/functionapp identity show`: exception handling to exit with
code 3 upon a missing resource for consistency
+
+ 0.2.2
+ +++++
+ * fix a bug that prevent from creating a function-app using storage
accounts in external resource groups
+ * fix a crash on zip deployment
+
+ 0.2.1
+ +++++
+ * Minor fixes.
+
+ 0.2.0
+ +++++
+ * BREAKING CHANGE: 'show' commands log error message and fail with
exit code of 3 upon a missing resource.
+ * appservice: allow PremiumV2 skus
+
+ 0.1.36
+ ++++++
+ * webapp/functionapp: Adding support for disabling identity az webapp
identity remove. Preview tag removed for Identity feature.
+
+ 0.1.35
+ ++++++
+ * dependencies: remove the cap on the urllib as newer requests was
released
+ * functionapp create: support to use appservice plan from external
resource groups
+
+ 0.1.34
+ ++++++
+ * dependencies: cap the urllib to 1.22 to avoid conflit with requests
2.18.4
+
+ 0.1.33
+ ++++++
+ * webapp/functionapp: improve generic update commands
+ * webapp/functionapp: webapp deployment source config-zip supports
async operation with status updates for long running operation
+
+ 0.1.32
+ ++++++
+ * webapp: fix a bug in `az webapp delete` when `--slot` is provided
+ * webapp: remove `--runtime-version` from `az webapp auth update` as
it's not very public ready
+ * webapp: az webapp config set support for min_tls_version & https2.0
+ * webapp: az webapp create support for multicontainers
+
0.1.31
++++++
* (Breaking change): remove `assign-identity` which was tagged
`deprecating` 2 releases ago
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/__init__.py
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/__init__.py
---
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/__init__.py
2018-04-06 19:33:13.000000000 +0200
+++
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/__init__.py
2018-08-23 01:07:57.000000000 +0200
@@ -14,7 +14,8 @@
from azure.cli.core.commands import CliCommandType
appservice_custom =
CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.custom#{}')
super(AppserviceCommandsLoader, self).__init__(cli_ctx=cli_ctx,
-
custom_command_type=appservice_custom)
+
custom_command_type=appservice_custom,
+
min_profile='2017-03-10-profile')
def load_command_table(self, args):
from azure.cli.command_modules.appservice.commands import
load_command_table
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/_help.py
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/_help.py
---
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/_help.py
2018-04-06 19:33:13.000000000 +0200
+++
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/_help.py
2018-08-23 01:07:57.000000000 +0200
@@ -1,3 +1,4 @@
+# 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.
@@ -46,24 +47,29 @@
helps['webapp identity assign'] = """
type: command
- short-summary: (PREVIEW) assign managed service identity to the webapp
+ short-summary: assign or disable managed service identity to the webapp
examples:
- name: assign local identity and assign a reader role to the current
resource group.
text: >
az webapp identity assign -g MyResourceGroup -n MyUniqueApp --role
reader --scope
/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/MyResourceGroup
- - name: disable the identity when there is need.
+ - name: enable identity for the webapp.
text: >
- az webapp config appsettings set -g MyResourceGroup -n MyUniqueApp
--settings WEBSITE_DISABLE_MSI=true
+ az webapp identity assign -g MyResourceGroup -n MyUniqueApp
"""
helps['webapp identity'] = """
type: group
- short-summary: (PREVIEW) manage webapp's managed service identity
+ short-summary: manage webapp's managed service identity
"""
helps['webapp identity show'] = """
type: command
- short-summary: (PREVIEW) display webapp's managed service identity
+ short-summary: display webapp's managed service identity
+"""
+
+helps['webapp identity remove'] = """
+ type: command
+ short-summary: Disable webapp's managed service identity
"""
helps['functionapp identity'] = helps['webapp identity'].replace('webapp',
'functionapp')
@@ -72,6 +78,8 @@
helps['functionapp identity show'] = helps['webapp identity
show'].replace('webapp', 'functionapp')
+helps['functionapp identity remove'] = helps['webapp identity
remove'].replace('webapp', 'functionapp')
+
helps['webapp config'] = """
type: group
short-summary: Configure a web app.
@@ -320,7 +328,7 @@
examples:
- name: Get an endpoint and add it as a git remote.
text: >
- az webapp source-control config-local-git \\
+ az webapp deployment source config-local-git \\
-g MyResourceGroup -n MyUniqueApp
git remote add azure \\
@@ -332,7 +340,7 @@
short-summary: Perform deployment using the kudu zip push deployment for a
webapp.
long-summary: >
By default Kudu assumes that zip deployments do not require any
build-related actions like
- npm install or dotnet publish. This can be overridden by including a
.deployment file on your
+ npm install or dotnet publish. This can be overridden by including a
.deployment file in your
zip file with the following content '[config]
SCM_DO_BUILD_DURING_DEPLOYMENT = true',
to enable Kudu detection logic and build script generation process.
See
https://github.com/projectkudu/kudu/wiki/Configurable-settings#enabledisable-build-actions-preview.
@@ -380,11 +388,47 @@
short-summary: Clear the routing rules and send all traffic to production.
"""
+helps['webapp cors'] = """
+ type: group
+ short-summary: Manage Cross-Origin Resource Sharing (CORS)
+"""
+
+helps['webapp cors add'] = """
+ type: command
+ short-summary: Add allowed origins
+ examples:
+ - name: add a new allowed origin
+ text: >
+ az webapp cors add -g <myRG> -n <myAppName> --allowed-origins
https://myapps.com
+"""
+
+helps['webapp cors remove'] = """
+ type: command
+ short-summary: Remove allowed origins
+ examples:
+ - name: remove an allowed origin
+ text: >
+ az webapp cors remove -g <myRG> -n <myAppName> --allowed-origins
https://myapps.com
+ - name: remove all allowed origins
+ text: >
+ az webapp cors remove -g <myRG> -n <myAppName> --allowed-origins *
+"""
+
+helps['webapp cors show'] = """
+ type: command
+ short-summary: show allowed origins
+"""
+
helps['appservice plan'] = """
type: group
short-summary: Manage app service plans.
"""
+helps['appservice list-locations'] = """
+ type: command
+ short-summary: List regions where a plan sku is available.
+"""
+
helps['appservice plan update'] = """
type: command
short-summary: Update an app service plan.
@@ -561,6 +605,11 @@
az functionapp create -g MyResourceGroup -p MyPlan -n
MyUniqueAppName -s MyStorageAccount
"""
+helps['functionapp update'] = """
+ type: command
+ short-summary: Update a function app.
+"""
+
helps['functionapp delete'] = """
type: command
short-summary: Delete a function app.
@@ -687,6 +736,11 @@
short-summary: Manage function app deployments.
"""
+helps['functionapp deployment list-publishing-profiles'] = """
+ type: command
+ short-summary: Get the details for available function app deployment
profiles.
+"""
+
helps['functionapp deployment source'] = """
type: group
short-summary: Manage function app deployment via source control.
@@ -703,7 +757,7 @@
examples:
- name: Get an endpoint and add it as a git remote.
text: >
- az functionapp source-control config-local-git \\
+ az functionapp deployment source config-local-git \\
-g MyResourceGroup -n MyUniqueApp
git remote add azure \\
@@ -747,7 +801,7 @@
short-summary: Perform deployment using the kudu zip push deployment for a
function app.
long-summary: >
By default Kudu assumes that zip deployments do not require any
build-related actions like
- npm install or dotnet publish. This can be overridden by including an
.deployment file on your
+ npm install or dotnet publish. This can be overridden by including an
.deployment file in your
zip file with the following content '[config]
SCM_DO_BUILD_DURING_DEPLOYMENT = true',
to enable Kudu detection logic and build script generation process.
See
https://github.com/projectkudu/kudu/wiki/Configurable-settings#enabledisable-build-actions-preview.
@@ -759,3 +813,34 @@
-g <myRG> -n <myAppName> \\
--src <zip file path location>
"""
+
+helps['functionapp cors'] = """
+ type: group
+ short-summary: Manage Cross-Origin Resource Sharing (CORS)
+"""
+
+helps['functionapp cors add'] = """
+ type: command
+ short-summary: Add allowed origins
+ examples:
+ - name: add a new allowed origin
+ text: >
+ az functionapp cors add -g <myRG> -n <myAppName>
--allowed-origins https://myapps.com
+"""
+
+helps['functionapp cors remove'] = """
+ type: command
+ short-summary: Remove allowed origins
+ examples:
+ - name: remove an allowed origin
+ text: >
+ az functionapp cors remove -g <myRG> -n <myAppName>
--allowed-origins https://myapps.com
+ - name: remove all allowed origins
+ text: >
+ az functionapp cors remove -g <myRG> -n <myAppName>
--allowed-origins *
+"""
+
+helps['functionapp cors show'] = """
+ type: command
+ short-summary: show allowed origins
+"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/_params.py
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/_params.py
---
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/_params.py
2018-04-06 19:33:13.000000000 +0200
+++
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/_params.py
2018-08-23 01:07:57.000000000 +0200
@@ -9,7 +9,7 @@
from azure.cli.core.commands.parameters import (resource_group_name_type,
get_location_type,
get_resource_name_completion_list, file_type,
- get_three_state_flag,
get_enum_type)
+ get_three_state_flag,
get_enum_type, tags_type)
from azure.mgmt.web.models import DatabaseType, ConnectionStringType,
BuiltInAuthenticationProvider
from ._completers import get_hostname_completion_list
@@ -22,6 +22,8 @@
'LoginWithMicrosoftAccount':
BuiltInAuthenticationProvider.microsoft_account,
'LoginWithTwitter': BuiltInAuthenticationProvider.twitter}
+MULTI_CONTAINER_TYPES = ['COMPOSE', 'KUBE']
+
# pylint: disable=too-many-statements
@@ -34,7 +36,7 @@
arg_type=get_enum_type(['F1', 'FREE', 'D1',
'SHARED', 'B1', 'B2', 'B3', 'S1', 'S2', 'S3', 'P1', 'P2', 'P3', 'P1V2', 'P2V2',
'P3V2']))
webapp_name_arg_type = CLIArgumentType(configured_default='web',
options_list=['--name', '-n'], metavar='NAME',
completer=get_resource_name_completion_list('Microsoft.Web/sites'),
id_part='name',
- help="name of the web. You can
configure the default using 'az configure --defaults web=<name>'")
+ help="name of the webapp. You can
configure the default using 'az configure --defaults web=<name>'")
# use this hidden arg to give a command the right instance, that
functionapp commands
# work on function app and webapp ones work on web app
@@ -45,7 +47,7 @@
c.argument('slot', options_list=['--slot', '-s'], help="the name of
the slot. Default to the productions slot if not specified")
c.argument('name', configured_default='web', arg_type=name_arg_type,
completer=get_resource_name_completion_list('Microsoft.Web/sites'),
id_part='name',
- help="name of the web. You can configure the default using
'az configure --defaults web=<name>'")
+ help="name of the webapp. You can configure the default
using 'az configure --defaults web=<name>'")
with self.argument_context('appservice') as c:
c.argument('resource_group_name', arg_type=resource_group_name_type)
@@ -66,6 +68,8 @@
c.argument('name', options_list=['--name', '-n'], help="Name of the
new app service plan", completer=None)
c.argument('sku', arg_type=sku_arg_type)
c.argument('is_linux', action='store_true', required=False, help='host
webapp on Linux worker')
+ c.argument('tags', arg_type=tags_type)
+
with self.argument_context('appservice plan update') as c:
c.argument('sku', arg_type=sku_arg_type)
c.ignore('allow_pending_state')
@@ -73,6 +77,8 @@
with self.argument_context('webapp create') as c:
c.argument('name', options_list=['--name', '-n'], help='name of the
new webapp')
c.argument('startup_file', help="Linux only. The web's startup file")
+ c.argument('multicontainer_config_type',
options_list=['--multicontainer-config-type'], help="Linux only.",
arg_type=get_enum_type(MULTI_CONTAINER_TYPES))
+ c.argument('multicontainer_config_file',
options_list=['--multicontainer-config-file'], help="Linux only. Config file
for multicontainer apps. (local or remote)")
c.argument('runtime', options_list=['--runtime', '-r'],
help="canonicalized web runtime in the format of Framework|Version, e.g.
\"PHP|5.6\". Use 'az webapp list-runtimes' for available list") # TODO ADD
completer
c.argument('plan', options_list=['--plan', '-p'],
configured_default='appserviceplan',
completer=get_resource_name_completion_list('Microsoft.Web/serverFarms'),
@@ -90,6 +96,11 @@
with self.argument_context('webapp update') as c:
c.argument('client_affinity_enabled', help="Enables sending session
affinity cookies.", arg_type=get_three_state_flag(return_label=True))
c.argument('https_only', help="Redirect all traffic made to an app
using HTTP to HTTPS.", arg_type=get_three_state_flag(return_label=True))
+ c.argument('force_dns_registration', help="If true, web app hostname
is force registered with DNS", arg_type=get_three_state_flag(return_label=True))
+ c.argument('skip_custom_domain_verification', help="If true, custom
(non *.azurewebsites.net) domains associated with web app are not verified",
arg_type=get_three_state_flag(return_label=True))
+ c.argument('ttl_in_seconds', help="Time to live in seconds for web
app's default domain name", arg_type=get_three_state_flag(return_label=True))
+ c.argument('skip_dns_registration', help="If true web app hostname is
not registered with DNS on creation",
arg_type=get_three_state_flag(return_label=True))
+
with self.argument_context('webapp browse') as c:
c.argument('logs', options_list=['--logs', '-l'], action='store_true',
help='Enable viewing the log stream immediately after launching the web app')
with self.argument_context('webapp delete') as c:
@@ -104,6 +115,8 @@
c.argument('deployment_zip', options_list=['--deployment-zip',
'-z'], help='perform deployment using zip file')
c.argument('deployment_source_url',
options_list=['--deployment-source-url', '-u'], help='Git repository URL to
link with manual integration')
c.argument('deployment_source_branch',
options_list=['--deployment-source-branch', '-b'], help='the branch to deploy')
+ c.argument('tags', arg_type=tags_type)
+
with self.argument_context(scope + ' config ssl bind') as c:
c.argument('ssl_type', help='The ssl cert type',
arg_type=get_enum_type(['SNI', 'IP']))
with self.argument_context(scope + ' config ssl upload') as c:
@@ -114,6 +127,7 @@
with self.argument_context(scope + ' config appsettings') as c:
c.argument('settings', nargs='+', help="space-separated app
settings in a format of <name>=<value>")
c.argument('setting_names', nargs='+', help="space-separated app
setting names")
+
with self.argument_context(scope + ' config hostname') as c:
c.argument('hostname', completer=get_hostname_completion_list,
help="hostname assigned to the site, such as custom domains",
id_part='child_name_1')
with self.argument_context(scope + ' deployment user') as c:
@@ -137,15 +151,27 @@
c.argument('repository_type', help='repository type',
arg_type=get_enum_type(['git', 'mercurial', 'vsts', 'github', 'externalgit',
'localgit']))
c.argument('git_token', help='Git access token required for auto
sync')
with self.argument_context(scope + ' identity') as c:
- c.argument('disable_msi', action='store_true', help='disable the
identity')
c.argument('scope', help="The scope the managed identity has
access to")
c.argument('role', help="Role name or id the managed identity will
be assigned")
+ with self.argument_context(scope + ' deployment source config-zip') as
c:
+ c.argument('src', help='a zip file path for deployment')
+
+ with self.argument_context(scope + ' config appsettings list') as c:
+ c.argument('name', arg_type=webapp_name_arg_type, id_part=None)
+
+ with self.argument_context(scope + ' config hostname list') as c:
+ c.argument('webapp_name', arg_type=webapp_name_arg_type,
id_part=None, options_list='--webapp-name')
+
+ with self.argument_context(scope + ' cors') as c:
+ c.argument('allowed_origins', options_list=['--allowed-origins',
'-a'], nargs='*', help='space separated origins that should be allowed to make
cross-origin calls (for example: http://example.com:12345). To allow all, use
"*" and remove all other origins from the list')
+
+ with self.argument_context('webapp config connection-string list') as c:
+ c.argument('name', arg_type=webapp_name_arg_type, id_part=None)
+
with self.argument_context('webapp config hostname') as c:
c.argument('webapp_name', help="webapp name. You can configure the
default using 'az configure --defaults web=<name>'", configured_default='web',
completer=get_resource_name_completion_list('Microsoft.Web/sites'),
id_part='name')
- with self.argument_context('webapp config appsettings') as c:
- c.argument('slot_settings', nargs='+', help="space-separated slot app
settings in a format of <name>=<value>")
with self.argument_context('webapp deployment container config') as c:
c.argument('enable', options_list=['--enable-cd', '-e'],
help='enable/disable continuous deployment', arg_type=get_enum_type(['true',
'false']))
with self.argument_context('webapp deployment slot') as c:
@@ -188,6 +214,9 @@
c.argument('docker_registry_server_user',
options_list=['--docker-registry-server-user', '-u'], help='the container
registry server username')
c.argument('docker_registry_server_password',
options_list=['--docker-registry-server-password', '-p'], help='the container
registry server password')
c.argument('websites_enable_app_service_storage',
options_list=['--enable-app-service-storage', '-t'], help='enables platform
storage (custom container only)',
arg_type=get_three_state_flag(return_label=True))
+ c.argument('multicontainer_config_type',
options_list=['--multicontainer-config-type'], help='config type',
arg_type=get_enum_type(MULTI_CONTAINER_TYPES))
+ c.argument('multicontainer_config_file',
options_list=['--multicontainer-config-file'], help="config file for
multicontainer apps")
+ c.argument('show_multicontainer_config', action='store_true',
help='shows decoded config if a multicontainer config is set')
with self.argument_context('webapp config set') as c:
c.argument('remote_debugging_enabled', help='enable or disable remote
debugging', arg_type=get_three_state_flag(return_label=True))
@@ -202,6 +231,8 @@
c.argument('java_version', help="The version used to run your web app
if using Java, e.g., '1.7' for Java 7, '1.8' for Java 8")
c.argument('java_container', help="The java container, e.g., Tomcat,
Jetty")
c.argument('java_container_version', help="The version of the java
container, e.g., '8.0.23' for Tomcat")
+ c.argument('min_tls_version', help="The minimum version of TLS
required for SSL requests, e.g., '1.0', '1.1', '1.2'")
+ c.argument('http20_enabled', help="configures a web site to allow
clients to connect over http2.0.",
arg_type=get_three_state_flag(return_label=True))
c.argument('app_command_line', options_list=['--startup-file'],
help="The startup file for linux hosted web apps, e.g. 'process.json' for
Node.js web")
with self.argument_context('webapp config backup') as c:
@@ -228,26 +259,27 @@
with self.argument_context('webapp auth update') as c:
c.argument('enabled', arg_type=get_three_state_flag(return_label=True))
- c.argument('token_store_enabled', options_list=['--token-store'],
arg_type=get_three_state_flag(return_label=True))
+ c.argument('token_store_enabled', options_list=['--token-store'],
arg_type=get_three_state_flag(return_label=True), help='use App Service Token
Store')
c.argument('action', arg_type=get_enum_type(AUTH_TYPES))
+ c.argument('runtime_version', help='Runtime version of the
Authentication/Authorization feature in use for the current app')
c.argument('token_refresh_extension_hours', type=float, help="Hours,
must be formattable into a float")
c.argument('allowed_external_redirect_urls', nargs='+', help="One or
more urls (space-delimited).")
- c.argument('client_id', options_list=['--aad-client-id'],
arg_group='Azure Active Directory')
- c.argument('client_secret', options_list=['--aad-client-secret'],
arg_group='Azure Active Directory')
+ c.argument('client_id', options_list=['--aad-client-id'],
arg_group='Azure Active Directory', help='Application ID to integrate AAD
organization account Sign-in into your web app')
+ c.argument('client_secret', options_list=['--aad-client-secret'],
arg_group='Azure Active Directory', help='AAD application secret')
c.argument('allowed_audiences', nargs='+',
options_list=['--aad-allowed-token-audiences'], arg_group='Azure Active
Directory', help="One or more token audiences (space-delimited).")
c.argument('issuer', options_list=['--aad-token-issuer-url'],
help='This url can be found in the JSON output returned
from your active directory endpoint using your tenantID. The endpoint can be
queried from \'az cloud show\' at \"endpoints.activeDirectory\". '
'The tenantID can be found using \'az account show\'.
Get the \"issuer\" from the JSON at <active directory
endpoint>/<tenantId>/.well-known/openid-configuration.', arg_group='Azure
Active Directory')
- c.argument('facebook_app_id', arg_group='Facebook')
- c.argument('facebook_app_secret', arg_group='Facebook')
+ c.argument('facebook_app_id', arg_group='Facebook', help="Application
ID to integrate Facebook Sign-in into your web app")
+ c.argument('facebook_app_secret', arg_group='Facebook', help='Facebook
Application client secret')
c.argument('facebook_oauth_scopes', nargs='+', help="One or more
facebook authentication scopes (space-delimited).", arg_group='Facebook')
- c.argument('twitter_consumer_key', arg_group='Twitter')
- c.argument('twitter_consumer_secret', arg_group='Twitter')
- c.argument('google_client_id', arg_group='Google')
- c.argument('google_client_secret', arg_group='Google')
+ c.argument('twitter_consumer_key', arg_group='Twitter',
help='Application ID to integrate Twitter Sign-in into your web app')
+ c.argument('twitter_consumer_secret', arg_group='Twitter',
help='Twitter Application client secret')
+ c.argument('google_client_id', arg_group='Google', help='Application
ID to integrate Google Sign-in into your web app')
+ c.argument('google_client_secret', arg_group='Google', help='Google
Application client secret')
c.argument('google_oauth_scopes', nargs='+', help="One or more Google
authentication scopes (space-delimited).", arg_group='Google')
- c.argument('microsoft_account_client_id', arg_group='Microsoft')
- c.argument('microsoft_account_client_secret', arg_group='Microsoft')
+ c.argument('microsoft_account_client_id', arg_group='Microsoft',
help="AAD V2 Application ID to integrate Microsoft account Sign-in into your
web app")
+ c.argument('microsoft_account_client_secret', arg_group='Microsoft',
help='AAD V2 Application client secret')
c.argument('microsoft_account_oauth_scopes', nargs='+', help="One or
more Microsoft authentification scopes (space-delimited).",
arg_group='Microsoft')
with self.argument_context('functionapp') as c:
@@ -267,3 +299,5 @@
# For commands with shared impl between webapp and functionapp and has
output, we apply type validation to avoid confusions
with self.argument_context('functionapp show') as c:
c.argument('name', arg_type=name_arg_type)
+ with self.argument_context('functionapp config appsettings') as c:
+ c.argument('slot_settings', nargs='+', help="space-separated slot app
settings in a format of <name>=<value>")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/commands.py
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/commands.py
---
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/commands.py
2018-04-06 19:33:13.000000000 +0200
+++
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/commands.py
2018-08-23 01:07:57.000000000 +0200
@@ -66,10 +66,12 @@
operations_tmpl='azure.mgmt.web.operations.web_apps_operations#WebAppsOperations.{}',
client_factory=cf_webapps
)
+ appservice_custom =
CliCommandType(operations_tmpl='azure.cli.command_modules.appservice.custom#{}')
+
with self.command_group('webapp', webapp_sdk) as g:
g.custom_command('create', 'create_webapp',
exception_handler=ex_handler_factory())
g.custom_command('list', 'list_webapp',
table_transformer=transform_web_list_output)
- g.custom_command('show', 'show_webapp',
exception_handler=empty_on_404, table_transformer=transform_web_output)
+ g.custom_show_command('show', 'show_webapp',
table_transformer=transform_web_output)
g.custom_command('delete', 'delete_webapp')
g.custom_command('stop', 'stop_webapp')
g.custom_command('start', 'start_webapp')
@@ -77,17 +79,23 @@
g.custom_command('browse', 'view_in_browser')
g.custom_command('list-runtimes', 'list_runtimes')
g.custom_command('identity assign', 'assign_identity')
- g.custom_command('identity show', 'show_identity')
- g.generic_update_command('update', custom_func_name='update_webapp',
setter_arg_name='site_envelope')
+ g.custom_show_command('identity show', 'show_identity')
+ g.custom_command('identity remove', 'remove_identity')
+ g.generic_update_command('update', getter_name='get_webapp',
setter_name='set_webapp', custom_func_name='update_webapp',
command_type=appservice_custom)
with self.command_group('webapp traffic-routing') as g:
g.custom_command('set', 'set_traffic_routing')
- g.custom_command('show', 'show_traffic_routing')
+ g.custom_show_command('show', 'show_traffic_routing')
g.custom_command('clear', 'clear_traffic_routing')
+ with self.command_group('webapp cors') as g:
+ g.custom_command('add', 'add_cors')
+ g.custom_command('remove', 'remove_cors')
+ g.custom_command('show', 'show_cors')
+
with self.command_group('webapp config') as g:
g.custom_command('set', 'update_site_configs')
- g.custom_command('show', 'get_site_configs',
exception_handler=empty_on_404)
+ g.custom_show_command('show', 'get_site_configs')
with self.command_group('webapp config appsettings') as g:
g.custom_command('list', 'get_app_settings',
exception_handler=empty_on_404)
@@ -108,7 +116,7 @@
with self.command_group('webapp config container') as g:
g.custom_command('set', 'update_container_settings')
g.custom_command('delete', 'delete_container_settings')
- g.custom_command('show', 'show_container_settings',
exception_handler=empty_on_404)
+ g.custom_show_command('show', 'show_container_settings')
with self.command_group('webapp config ssl') as g:
g.custom_command('upload', 'upload_ssl_cert',
exception_handler=ex_handler_factory())
@@ -119,7 +127,7 @@
with self.command_group('webapp config backup') as g:
g.custom_command('list', 'list_backups')
- g.custom_command('show', 'show_backup_configuration',
exception_handler=empty_on_404)
+ g.custom_show_command('show', 'show_backup_configuration')
g.custom_command('create', 'create_backup',
exception_handler=ex_handler_factory())
g.custom_command('update', 'update_backup_schedule',
exception_handler=ex_handler_factory())
g.custom_command('restore', 'restore_backup',
exception_handler=ex_handler_factory())
@@ -129,7 +137,7 @@
g.custom_command('config-zip', 'enable_zip_deploy')
g.custom_command('config', 'config_source_control',
exception_handler=ex_handler_factory())
g.custom_command('sync', 'sync_site_repo',
exception_handler=ex_handler_factory())
- g.custom_command('show', 'show_source_control',
exception_handler=empty_on_404)
+ g.custom_show_command('show', 'show_source_control')
g.custom_command('delete', 'delete_source_control')
g.custom_command('update-token', 'update_git_token',
exception_handler=ex_handler_factory())
@@ -137,7 +145,7 @@
g.custom_command('tail', 'get_streaming_log')
g.custom_command('download', 'download_historical_logs')
g.custom_command('config', 'config_diagnostics')
- g.custom_command('show', 'show_diagnostic_settings')
+ g.custom_show_command('show', 'show_diagnostic_settings')
with self.command_group('webapp deployment slot') as g:
g.custom_command('list', 'list_slots',
table_transformer=output_slots_in_table)
@@ -150,7 +158,7 @@
g.custom_command('list-publishing-profiles', 'list_publish_profiles')
with self.command_group('webapp deployment user', webclient_sdk) as g:
- g.command('show', 'get_publishing_user',
exception_handler=empty_on_404)
+ g.show_command('show', 'get_publishing_user')
g.custom_command('set', 'set_deployment_user',
exception_handler=ex_handler_factory())
with self.command_group('webapp deployment container') as g:
@@ -158,14 +166,14 @@
g.custom_command('show-cd-url', 'show_container_cd_url')
with self.command_group('webapp auth') as g:
- g.custom_command('show', 'get_auth_settings')
+ g.custom_show_command('show', 'get_auth_settings')
g.custom_command('update', 'update_auth_settings')
with self.command_group('appservice plan', appservice_plan_sdk) as g:
g.custom_command('create', 'create_app_service_plan',
exception_handler=ex_handler_factory(creating_plan=True))
g.command('delete', 'delete', confirmation=True)
g.custom_command('list', 'list_app_service_plans')
- g.command('show', 'get', exception_handler=empty_on_404)
+ g.show_command('show', 'get')
g.generic_update_command('update',
custom_func_name='update_app_service_plan', setter_arg_name='app_service_plan')
with self.command_group('appservice') as g:
g.custom_command('list-locations', 'list_locations',
transform=transform_list_location_output)
@@ -173,15 +181,16 @@
with self.command_group('functionapp') as g:
g.custom_command('create', 'create_function')
g.custom_command('list', 'list_function_app',
table_transformer=transform_web_list_output)
- g.custom_command('show', 'show_webapp',
exception_handler=empty_on_404, table_transformer=transform_web_output)
+ g.custom_show_command('show', 'show_webapp',
table_transformer=transform_web_output)
g.custom_command('delete', 'delete_function_app')
g.custom_command('stop', 'stop_webapp')
g.custom_command('start', 'start_webapp')
g.custom_command('restart', 'restart_webapp')
g.custom_command('list-consumption-locations',
'list_consumption_locations')
- g.custom_command('assign-identity', 'assign_identity',
deprecate_info='identity assign')
g.custom_command('identity assign', 'assign_identity')
- g.custom_command('identity show', 'show_identity')
+ g.custom_show_command('identity show', 'show_identity')
+ g.custom_command('identity remove', 'remove_identity')
+ g.generic_update_command('update', setter_name='set_functionapp',
setter_type=appservice_custom, command_type=webapp_sdk)
with self.command_group('functionapp config appsettings') as g:
g.custom_command('list', 'get_app_settings',
exception_handler=empty_on_404)
@@ -206,13 +215,18 @@
g.custom_command('config-zip', 'enable_zip_deploy')
g.custom_command('config', 'config_source_control',
exception_handler=ex_handler_factory())
g.custom_command('sync', 'sync_site_repo')
- g.custom_command('show', 'show_source_control',
exception_handler=empty_on_404)
+ g.custom_show_command('show', 'show_source_control')
g.custom_command('delete', 'delete_source_control')
g.custom_command('update-token', 'update_git_token',
exception_handler=ex_handler_factory())
with self.command_group('functionapp deployment user', webclient_sdk) as g:
g.custom_command('set', 'set_deployment_user',
exception_handler=ex_handler_factory())
- g.command('show', 'get_publishing_user',
exception_handler=empty_on_404)
+ g.show_command('show', 'get_publishing_user')
with self.command_group('functionapp deployment') as g:
g.custom_command('list-publishing-profiles', 'list_publish_profiles')
+
+ with self.command_group('functionapp cors') as g:
+ g.custom_command('add', 'add_cors')
+ g.custom_command('remove', 'remove_cors')
+ g.custom_command('show', 'show_cors')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/custom.py
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/custom.py
---
old/azure-cli-appservice-0.1.31/azure/cli/command_modules/appservice/custom.py
2018-04-06 19:33:13.000000000 +0200
+++
new/azure-cli-appservice-0.2.3/azure/cli/command_modules/appservice/custom.py
2018-08-23 01:07:57.000000000 +0200
@@ -5,13 +5,17 @@
from __future__ import print_function
import threading
+
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse # pylint: disable=import-error
+from six.moves.urllib.request import urlopen # pylint: disable=import-error,
ungrouped-imports
from binascii import hexlify
from os import urandom
import json
+import ssl
+import sys
import OpenSSL.crypto
from knack.prompting import prompt_pass, NoTTYException
@@ -30,9 +34,11 @@
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from azure.cli.core.commands import LongRunningOperation
+from azure.cli.core.util import in_cloud_console
+from azure.cli.core.util import open_page_in_browser
from .vsts_cd_provider import VstsContinuousDeliveryProvider
-from ._params import AUTH_TYPES
+from ._params import AUTH_TYPES, MULTI_CONTAINER_TYPES
from ._client_factory import web_client_factory, ex_handler_factory
from ._appservice_utils import _generic_site_operation
@@ -47,7 +53,8 @@
def create_webapp(cmd, resource_group_name, name, plan, runtime=None,
startup_file=None,
deployment_container_image_name=None,
deployment_source_url=None, deployment_source_branch='master',
- deployment_local_git=None):
+ deployment_local_git=None, multicontainer_config_type=None,
multicontainer_config_file=None,
+ tags=None):
if deployment_source_url and deployment_local_git:
raise CLIError('usage error: --deployment-source-url <url> |
--deployment-local-git')
client = web_client_factory(cmd.cli_ctx)
@@ -62,12 +69,14 @@
node_default_version = "6.9.1"
location = plan_info.location
site_config = SiteConfig(app_settings=[])
- webapp_def = Site(server_farm_id=plan_info.id, location=location,
site_config=site_config)
+ webapp_def = Site(server_farm_id=plan_info.id, location=location,
site_config=site_config, tags=tags)
helper = _StackRuntimeHelper(client, linux=is_linux)
if is_linux:
- if runtime and deployment_container_image_name:
- raise CLIError('usage error: --runtime |
--deployment-container-image-name')
+ if not validate_linux_create_options(runtime,
deployment_container_image_name,
+ multicontainer_config_type,
multicontainer_config_file):
+ raise CLIError("usage error: --runtime |
--deployment-container-image-name |"
+ " --multicontainer-config-type TYPE
--multicontainer-config-file FILE")
if startup_file:
site_config.app_command_line = startup_file
@@ -77,16 +86,17 @@
if not match:
raise CLIError("Linux Runtime '{}' is not supported."
"Please invoke 'list-runtimes' to cross
check".format(runtime))
-
elif deployment_container_image_name:
site_config.linux_fx_version =
_format_linux_fx_version(deployment_container_image_name)
site_config.app_settings.append(NameValuePair("WEBSITES_ENABLE_APP_SERVICE_STORAGE",
"false"))
- else: # must specify runtime
- raise CLIError('usage error: must specify --runtime |
--deployment-container-image-name') # pylint: disable=line-too-long
+ elif multicontainer_config_type and multicontainer_config_file:
+ encoded_config_file =
_get_linux_multicontainer_encoded_config_from_file(multicontainer_config_file)
+ site_config.linux_fx_version =
_format_linux_fx_version(encoded_config_file, multicontainer_config_type)
elif runtime: # windows webapp with runtime specified
- if startup_file or deployment_container_image_name:
- raise CLIError("usage error: --startup-file or
--deployment-container-image-name is "
+ if any([startup_file, deployment_container_image_name,
multicontainer_config_file, multicontainer_config_type]):
+ raise CLIError("usage error: --startup-file or
--deployment-container-image-name or "
+ "--multicontainer-config-type and
--multicontainer-config-file is "
"only appliable on linux webapp")
match = helper.resolve(runtime)
if not match:
@@ -117,6 +127,14 @@
return webapp
+def validate_linux_create_options(runtime=None,
deployment_container_image_name=None,
+ multicontainer_config_type=None,
multicontainer_config_file=None):
+ if bool(multicontainer_config_type) != bool(multicontainer_config_file):
+ return False
+ opts = [runtime, deployment_container_image_name,
multicontainer_config_type]
+ return len([x for x in opts if x]) == 1 # you can only specify one out
the combinations
+
+
def update_app_settings(cmd, resource_group_name, name, settings=None,
slot=None, slot_settings=None):
if not settings and not slot_settings:
raise CLIError('Usage Error: --settings |--slot-settings')
@@ -151,7 +169,8 @@
def enable_zip_deploy(cmd, resource_group_name, name, src, slot=None):
user_name, password = _get_site_credential(cmd.cli_ctx,
resource_group_name, name, slot)
scm_url = _get_scm_url(cmd, resource_group_name, name, slot)
- zip_url = scm_url + '/api/zipdeploy'
+ zip_url = scm_url + '/api/zipdeploy?isAsync=true'
+ deployment_status_url = scm_url + '/api/deployments/latest'
import urllib3
authorization =
urllib3.util.make_headers(basic_auth='{0}:{1}'.format(user_name, password))
@@ -163,14 +182,14 @@
# Read file content
with open(os.path.realpath(os.path.expanduser(src)), 'rb') as fs:
zip_content = fs.read()
- r = requests.post(zip_url, data=zip_content, headers=headers)
- if r.status_code != 200:
- raise CLIError("Zip deployment {} failed with status code '{}' and
reason '{}'".format(
- zip_url, r.status_code, r.text))
-
- # on successful deployment navigate to the app, display the latest
deployment json response
- response = requests.get(scm_url + '/api/deployments/latest',
headers=authorization)
- return response.json()
+ requests.post(zip_url, data=zip_content, headers=headers)
+ # check the status of async deployment
+ response = requests.get(deployment_status_url, headers=authorization)
+ response = response.json()
+ if response.get('status', 0) != 4:
+ logger.warning(response.get('progress', ''))
+ response = _check_zip_deployment_status(deployment_status_url,
authorization)
+ return response
def get_sku_name(tier):
@@ -191,12 +210,6 @@
raise CLIError("Invalid sku(pricing tier), please refer to command
help for valid values")
-# deprecated, do not use
-def _get_sku_name(tier):
- return get_sku_name(tier)
-# endregion
-
-
def _generic_settings_operation(cli_ctx, resource_group_name, name,
operation_name,
setting_properties, slot=None, client=None):
client = client or web_client_factory(cli_ctx)
@@ -211,19 +224,53 @@
webapp = app_instance
if not app_instance: # when the routine is invoked as a help method, not
through commands
webapp = _generic_site_operation(cmd.cli_ctx, resource_group_name,
name, 'get', slot)
+ if not webapp:
+ raise CLIError("'{}' app doesn't exist".format(name))
_rename_server_farm_props(webapp)
_fill_ftp_publishing_url(cmd, webapp, resource_group_name, name, slot)
return webapp
+# for generic updater
+def get_webapp(cmd, resource_group_name, name, slot=None):
+ return _generic_site_operation(cmd.cli_ctx, resource_group_name, name,
'get', slot)
+
+
+def set_webapp(cmd, resource_group_name, name, slot=None,
skip_dns_registration=None,
+ skip_custom_domain_verification=None,
force_dns_registration=None, ttl_in_seconds=None, **kwargs):
+ instance = kwargs['parameters']
+ client = web_client_factory(cmd.cli_ctx)
+ updater = client.web_apps.create_or_update_slot if slot else
client.web_apps.create_or_update
+ kwargs = dict(resource_group_name=resource_group_name, name=name,
site_envelope=instance,
+ skip_dns_registration=skip_dns_registration,
+
skip_custom_domain_verification=skip_custom_domain_verification,
+ force_dns_registration=force_dns_registration,
+ ttl_in_seconds=ttl_in_seconds)
+ if slot:
+ kwargs['slot'] = slot
+
+ return updater(**kwargs)
+
+
def update_webapp(instance, client_affinity_enabled=None, https_only=None):
+ if 'function' in instance.kind:
+ raise CLIError("please use 'az functionapp update' to update this
function app")
if client_affinity_enabled is not None:
instance.client_affinity_enabled = client_affinity_enabled == 'true'
if https_only is not None:
instance.https_only = https_only == 'true'
+
return instance
+def set_functionapp(cmd, resource_group_name, name, **kwargs):
+ instance = kwargs['parameters']
+ if 'function' not in instance.kind:
+ raise CLIError('Not a function app to update')
+ client = web_client_factory(cmd.cli_ctx)
+ return client.web_apps.create_or_update(resource_group_name, name,
site_envelope=instance)
+
+
def list_webapp(cmd, resource_group_name=None):
result = _list_app(cmd.cli_ctx, resource_group_name)
return [r for r in result if 'function' not in r.kind]
@@ -245,7 +292,7 @@
return result
-def assign_identity(cmd, resource_group_name, name, role='Contributor',
slot=None, scope=None, disable_msi=False):
+def assign_identity(cmd, resource_group_name, name, role='Contributor',
slot=None, scope=None):
def getter():
return _generic_site_operation(cmd.cli_ctx, resource_group_name, name,
'get', slot)
@@ -256,7 +303,6 @@
from azure.cli.core.commands.arm import assign_identity as _assign_identity
webapp = _assign_identity(cmd.cli_ctx, getter, setter, role, scope)
- update_app_settings(cmd, resource_group_name, name,
['WEBSITE_DISABLE_MSI={}'.format(disable_msi)], slot)
return webapp.identity
@@ -264,13 +310,27 @@
return _generic_site_operation(cmd.cli_ctx, resource_group_name, name,
'get', slot).identity
+def remove_identity(cmd, resource_group_name, name, slot=None):
+ def getter():
+ return _generic_site_operation(cmd.cli_ctx, resource_group_name, name,
'get', slot)
+
+ def setter(webapp):
+ webapp.identity = ManagedServiceIdentity(type='None')
+ poller = _generic_site_operation(cmd.cli_ctx, resource_group_name,
name, 'create_or_update', slot, webapp)
+ return LongRunningOperation(cmd.cli_ctx)(poller)
+
+ from azure.cli.core.commands.arm import assign_identity as _assign_identity
+ webapp = _assign_identity(cmd.cli_ctx, getter, setter)
+ return webapp.identity
+
+
def get_auth_settings(cmd, resource_group_name, name, slot=None):
return _generic_site_operation(cmd.cli_ctx, resource_group_name, name,
'get_auth_settings', slot)
def update_auth_settings(cmd, resource_group_name, name, enabled=None,
action=None, # pylint: disable=unused-argument
client_id=None, token_store_enabled=None, # pylint:
disable=unused-argument
- runtime_version=None,
token_refresh_extension_hours=None, # pylint: disable=unused-argument
+ token_refresh_extension_hours=None, # pylint:
disable=unused-argument
allowed_external_redirect_urls=None,
client_secret=None, # pylint: disable=unused-argument
allowed_audiences=None, issuer=None,
facebook_app_id=None, # pylint: disable=unused-argument
facebook_app_secret=None, facebook_oauth_scopes=None,
# pylint: disable=unused-argument
@@ -323,11 +383,16 @@
def delete_webapp(cmd, resource_group_name, name, keep_metrics=None,
keep_empty_plan=None,
keep_dns_registration=None, slot=None):
client = web_client_factory(cmd.cli_ctx)
- delete_method = getattr(client.web_apps, 'delete' if slot is None else
'delete_slot')
- delete_method(resource_group_name, name,
- delete_metrics=False if keep_metrics else None,
- delete_empty_server_farm=False if keep_empty_plan else None,
- skip_dns_registration=False if keep_dns_registration else
None)
+ if slot:
+ client.web_apps.delete_slot(resource_group_name, name, slot,
+ delete_metrics=False if keep_metrics else
None,
+ delete_empty_server_farm=False if
keep_empty_plan else None,
+ skip_dns_registration=False if
keep_dns_registration else None)
+ else:
+ client.web_apps.delete(resource_group_name, name,
+ delete_metrics=False if keep_metrics else None,
+ delete_empty_server_farm=False if
keep_empty_plan else None,
+ skip_dns_registration=False if
keep_dns_registration else None)
def stop_webapp(cmd, resource_group_name, name, slot=None):
@@ -371,12 +436,14 @@
return webapp
-def _format_linux_fx_version(custom_image_name):
+def _format_linux_fx_version(custom_image_name, container_config_type=None):
fx_version = custom_image_name.strip()
fx_version_lower = fx_version.lower()
# handles case of only spaces
if fx_version:
- if not fx_version_lower.startswith('docker|'):
+ if container_config_type:
+ fx_version = '{}|{}'.format(container_config_type,
custom_image_name)
+ elif not fx_version_lower.startswith('docker|'):
fx_version = '{}|{}'.format('DOCKER', custom_image_name)
else:
fx_version = ' '
@@ -397,6 +464,36 @@
return site_config.linux_fx_version
+def url_validator(url):
+ try:
+ result = urlparse(url)
+ return all([result.scheme, result.netloc, result.path])
+ except ValueError:
+ return False
+
+
+def _get_linux_multicontainer_decoded_config(cmd, resource_group_name, name,
slot=None):
+ from base64 import b64decode
+ linux_fx_version = _get_linux_fx_version(cmd, resource_group_name, name,
slot)
+ if not any([linux_fx_version.startswith(s) for s in
MULTI_CONTAINER_TYPES]):
+ raise CLIError("Cannot decode config that is not one of the"
+ " following types:
{}".format(','.join(MULTI_CONTAINER_TYPES)))
+ return b64decode(linux_fx_version.split('|')[1].encode('utf-8'))
+
+
+def _get_linux_multicontainer_encoded_config_from_file(file_name):
+ from base64 import b64encode
+ config_file_bytes = None
+ if url_validator(file_name):
+ response = urlopen(file_name, context=_ssl_context())
+ config_file_bytes = response.read()
+ else:
+ with open(file_name, 'rb') as f:
+ config_file_bytes = f.read()
+ # Decode base64 encoded byte array into string
+ return b64encode(config_file_bytes).decode('utf-8')
+
+
# for any modifications to the non-optional parameters, adjust the reflection
logic accordingly
# in the method
def update_site_configs(cmd, resource_group_name, name, slot=None,
@@ -406,6 +503,8 @@
remote_debugging_enabled=None,
web_sockets_enabled=None, # pylint: disable=unused-argument
always_on=None, auto_heal_enabled=None, # pylint:
disable=unused-argument
use32_bit_worker_process=None, # pylint:
disable=unused-argument
+ min_tls_version=None, # pylint:
disable=unused-argument
+ http20_enabled=None, # pylint: disable=unused-argument
app_command_line=None): # pylint:
disable=unused-argument
configs = get_site_configs(cmd, resource_group_name, name, slot)
if linux_fx_version:
@@ -417,7 +516,7 @@
import inspect
frame = inspect.currentframe()
bool_flags = ['remote_debugging_enabled', 'web_sockets_enabled',
'always_on',
- 'auto_heal_enabled', 'use32_bit_worker_process']
+ 'auto_heal_enabled', 'use32_bit_worker_process',
'http20_enabled']
# note: getargvalues is used already in azure.cli.core.commands.
# and no simple functional replacement for this deprecating method for 3.5
args, _, _, values = inspect.getargvalues(frame) # pylint:
disable=deprecated-method
@@ -450,6 +549,16 @@
return _build_app_settings_output(result.properties,
slot_cfg_names.app_setting_names)
+def _ssl_context():
+ if sys.version_info < (3, 4) or (in_cloud_console() and
sys.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()
+
+
def _build_app_settings_output(app_settings, slot_cfg_names):
slot_cfg_names = slot_cfg_names or []
return [{'name': p,
@@ -519,7 +628,7 @@
def update_container_settings(cmd, resource_group_name, name,
docker_registry_server_url=None,
docker_custom_image_name=None,
docker_registry_server_user=None,
websites_enable_app_service_storage=None,
docker_registry_server_password=None,
- slot=None):
+ multicontainer_config_type=None,
multicontainer_config_file=None, slot=None):
settings = []
if docker_registry_server_url is not None:
settings.append('DOCKER_REGISTRY_SERVER_URL=' +
docker_registry_server_url)
@@ -547,6 +656,13 @@
update_app_settings(cmd, resource_group_name, name, settings, slot)
settings = get_app_settings(cmd, resource_group_name, name, slot)
+ if multicontainer_config_file and multicontainer_config_type:
+ encoded_config_file =
_get_linux_multicontainer_encoded_config_from_file(multicontainer_config_file)
+ linux_fx_version = _format_linux_fx_version(encoded_config_file,
multicontainer_config_type)
+ update_site_configs(cmd, resource_group_name, name,
linux_fx_version=linux_fx_version)
+ elif multicontainer_config_file or multicontainer_config_type:
+ logger.warning('Must change both settings --multicontainer-config-file
FILE --multicontainer-config-type TYPE')
+
return _mask_creds_related_appsettings(_filter_for_container_settings(cmd,
resource_group_name, name, settings))
@@ -576,19 +692,25 @@
delete_app_settings(cmd, resource_group_name, name,
CONTAINER_APPSETTING_NAMES, slot)
-def show_container_settings(cmd, resource_group_name, name, slot=None):
+def show_container_settings(cmd, resource_group_name, name,
show_multicontainer_config=None, slot=None):
settings = get_app_settings(cmd, resource_group_name, name, slot)
- return _mask_creds_related_appsettings(_filter_for_container_settings(cmd,
resource_group_name,
-
name, settings, slot))
+ return _mask_creds_related_appsettings(_filter_for_container_settings(cmd,
resource_group_name, name, settings,
+
show_multicontainer_config, slot))
-def _filter_for_container_settings(cmd, resource_group_name, name, settings,
slot=None):
+def _filter_for_container_settings(cmd, resource_group_name, name, settings,
+ show_multicontainer_config=None, slot=None):
result = [x for x in settings if x['name'] in CONTAINER_APPSETTING_NAMES]
fx_version = _get_linux_fx_version(cmd, resource_group_name, name,
slot).strip()
if fx_version:
added_image_name = {'name': 'DOCKER_CUSTOM_IMAGE_NAME',
'value': fx_version}
result.append(added_image_name)
+ if show_multicontainer_config:
+ decoded_value = _get_linux_multicontainer_decoded_config(cmd,
resource_group_name, name, slot)
+ decoded_image_name = {'name': 'DOCKER_CUSTOM_IMAGE_NAME_DECODED',
+ 'value': decoded_value}
+ result.append(decoded_image_name)
return result
@@ -602,6 +724,8 @@
def add_hostname(cmd, resource_group_name, webapp_name, hostname, slot=None):
client = web_client_factory(cmd.cli_ctx)
webapp = client.web_apps.get(resource_group_name, webapp_name)
+ if not webapp:
+ raise CLIError("'{}' app doesn't exist".format(webapp_name))
binding = HostNameBinding(webapp.location, site_name=webapp.name)
if slot is None:
return
client.web_apps.create_or_update_host_name_binding(resource_group_name,
webapp.name, hostname, binding)
@@ -629,17 +753,19 @@
def get_external_ip(cmd, resource_group_name, webapp_name):
# logics here are ported from portal
client = web_client_factory(cmd.cli_ctx)
- webapp_name = client.web_apps.get(resource_group_name, webapp_name)
- if webapp_name.hosting_environment_profile:
+ webapp = client.web_apps.get(resource_group_name, webapp_name)
+ if not webapp:
+ raise CLIError("'{}' app doesn't exist".format(webapp_name))
+ if webapp.hosting_environment_profile:
address = client.app_service_environments.list_vips(
- resource_group_name, webapp_name.hosting_environment_profile.name)
+ resource_group_name, webapp.hosting_environment_profile.name)
if address.internal_ip_address:
ip_address = address.internal_ip_address
else:
- vip = next((s for s in webapp_name.host_name_ssl_states if
s.ssl_state == SslState.ip_based_enabled), None)
+ vip = next((s for s in webapp.host_name_ssl_states if s.ssl_state
== SslState.ip_based_enabled), None)
ip_address = vip.virtual_ip if vip else address.service_ip_address
else:
- ip_address =
_resolve_hostname_through_dns(webapp_name.default_host_name)
+ ip_address = _resolve_hostname_through_dns(webapp.default_host_name)
return {'ip': ip_address}
@@ -652,6 +778,8 @@
def create_webapp_slot(cmd, resource_group_name, webapp, slot,
configuration_source=None):
client = web_client_factory(cmd.cli_ctx)
site = client.web_apps.get(resource_group_name, webapp)
+ if not site:
+ raise CLIError("'{}' app doesn't exist".format(webapp))
location = site.location
slot_def = Site(server_farm_id=site.server_farm_id, location=location)
clone_from_prod = None
@@ -814,14 +942,14 @@
def _linux_sku_check(sku):
tier = get_sku_name(sku)
- if tier in ['BASIC', 'STANDARD']:
+ if tier in ['BASIC', 'STANDARD', 'PREMIUMV2']:
return
format_string = 'usage error: {0} is not a valid sku for linux plan,
please use one of the following: {1}'
- raise CLIError(format_string.format(sku, 'B1, B2, B3, S1, S2, S3'))
+ raise CLIError(format_string.format(sku, 'B1, B2, B3, S1, S2, S3, P1V2,
P2V2, P3V2'))
def create_app_service_plan(cmd, resource_group_name, name, is_linux,
sku='B1', number_of_workers=None,
- location=None):
+ location=None, tags=None):
client = web_client_factory(cmd.cli_ctx)
sku = _normalize_sku(sku)
if location is None:
@@ -831,7 +959,7 @@
# the api is odd on parameter naming, have to live with it for now
sku_def = SkuDescription(tier=get_sku_name(sku), name=sku,
capacity=number_of_workers)
plan_def = AppServicePlan(location, app_service_plan_name=name,
- sku=sku_def, reserved=(is_linux or None))
+ sku=sku_def, reserved=(is_linux or None),
tags=tags)
return client.app_service_plans.create_or_update(resource_group_name,
name, plan_def)
@@ -1002,6 +1130,8 @@
def _get_location_from_webapp(client, resource_group_name, webapp):
webapp = client.web_apps.get(resource_group_name, webapp)
+ if not webapp:
+ raise CLIError("'{}' app doesn't exist".format(webapp))
return webapp.location
@@ -1097,29 +1227,17 @@
def view_in_browser(cmd, resource_group_name, name, slot=None, logs=False):
site = _generic_site_operation(cmd.cli_ctx, resource_group_name, name,
'get', slot)
+ if not site:
+ raise CLIError("'{}' app doesn't exist".format(name))
url = site.enabled_host_names[0] # picks the custom domain URL incase a
domain is assigned
ssl_host = next((h for h in site.host_name_ssl_states
if h.ssl_state != SslState.disabled), None)
url = ('https' if ssl_host else 'http') + '://' + url
- _open_page_in_browser(url)
+ open_page_in_browser(url)
if logs:
get_streaming_log(cmd, resource_group_name, name, provider=None,
slot=slot)
-def _open_page_in_browser(url):
- import sys
- if sys.platform.lower() == 'darwin':
- # handle 2 things:
- # a. On OSX sierra, 'python -m webbrowser -t <url>' emits out
"execution error: <url> doesn't
- # understand the "open location" message"
- # b. Python 2.x can't sniff out the default browser
- import subprocess
- subprocess.Popen(['open', url])
- else:
- import webbrowser
- webbrowser.open(url, new=2) # 2 means: open in a new tab, if possible
-
-
# TODO: expose new blob suport
def config_diagnostics(cmd, resource_group_name, name, level=None,
application_logging=None, web_server_logging=None,
@@ -1131,6 +1249,8 @@
client = web_client_factory(cmd.cli_ctx)
# TODO: ensure we call get_site only once
site = client.web_apps.get(resource_group_name, name)
+ if not site:
+ raise CLIError("'{}' app doesn't exist".format(name))
location = site.location
application_logs = None
@@ -1227,6 +1347,8 @@
def set_traffic_routing(cmd, resource_group_name, name, distribution):
client = web_client_factory(cmd.cli_ctx)
site = client.web_apps.get(resource_group_name, name)
+ if not site:
+ raise CLIError("'{}' app doesn't exist".format(name))
configs = get_site_configs(cmd, resource_group_name, name)
host_name_suffix = '.' + site.default_host_name.split('.', 1)[1]
configs.experiments.ramp_up_rules = []
@@ -1249,6 +1371,32 @@
set_traffic_routing(cmd, resource_group_name, name, [])
+def add_cors(cmd, resource_group_name, name, allowed_origins, slot=None):
+ from azure.mgmt.web.models import CorsSettings
+ configs = get_site_configs(cmd, resource_group_name, name, slot)
+ if not configs.cors:
+ configs.cors = CorsSettings()
+ configs.cors.allowed_origins = (configs.cors.allowed_origins or []) +
allowed_origins
+ result = _generic_site_operation(cmd.cli_ctx, resource_group_name, name,
'update_configuration', slot, configs)
+ return result.cors
+
+
+def remove_cors(cmd, resource_group_name, name, allowed_origins, slot=None):
+ configs = get_site_configs(cmd, resource_group_name, name, slot)
+ if configs.cors:
+ if allowed_origins:
+ configs.cors.allowed_origins = [x for x in
(configs.cors.allowed_origins or []) if x not in allowed_origins]
+ else:
+ configs.cors.allowed_origins = []
+ configs = _generic_site_operation(cmd.cli_ctx, resource_group_name,
name, 'update_configuration', slot, configs)
+ return configs.cors
+
+
+def show_cors(cmd, resource_group_name, name, slot=None):
+ configs = get_site_configs(cmd, resource_group_name, name, slot)
+ return configs.cors
+
+
def get_streaming_log(cmd, resource_group_name, name, provider=None,
slot=None):
scm_url = _get_scm_url(cmd, resource_group_name, name, slot)
streaming_url = scm_url + '/logstream'
@@ -1280,7 +1428,6 @@
def _get_log(url, user_name, password, log_file=None):
- import sys
import certifi
import urllib3
try:
@@ -1377,6 +1524,9 @@
def _update_ssl_binding(cmd, resource_group_name, name,
certificate_thumbprint, ssl_type, slot=None):
client = web_client_factory(cmd.cli_ctx)
webapp = client.web_apps.get(resource_group_name, name)
+ if not webapp:
+ raise CLIError("'{}' app doesn't exist".format(name))
+
cert_resource_group_name =
parse_resource_id(webapp.server_farm_id)['resource_group']
webapp_certs =
client.certificates.list_by_resource_group(cert_resource_group_name)
for webapp_cert in webapp_certs:
@@ -1521,7 +1671,7 @@
def create_function(cmd, resource_group_name, name, storage_account, plan=None,
consumption_plan_location=None, deployment_source_url=None,
deployment_source_branch='master',
deployment_local_git=None,
- deployment_container_image_name=None):
+ deployment_container_image_name=None, tags=None):
# pylint: disable=too-many-statements
if deployment_source_url and deployment_local_git:
raise CLIError('usage error: --deployment-source-url <url> |
--deployment-local-git')
@@ -1529,7 +1679,7 @@
raise CLIError("usage error: --plan NAME_OR_ID |
--consumption-plan-location LOCATION")
site_config = SiteConfig(app_settings=[])
- functionapp_def = Site(location=None, site_config=site_config)
+ functionapp_def = Site(location=None, site_config=site_config, tags=tags)
client = web_client_factory(cmd.cli_ctx)
if consumption_plan_location:
@@ -1541,8 +1691,10 @@
functionapp_def.kind = 'functionapp'
else:
if is_valid_resource_id(plan):
- plan = parse_resource_id(plan)['name']
- plan_info = client.app_service_plans.get(resource_group_name, plan)
+ parse_result = parse_resource_id(plan)
+ plan_info =
client.app_service_plans.get(parse_result['resource_group'],
parse_result['name'])
+ else:
+ plan_info = client.app_service_plans.get(resource_group_name, plan)
if not plan_info:
raise CLIError("The plan '{}' doesn't exist".format(plan))
location = plan_info.location
@@ -1622,14 +1774,14 @@
for e in ['blob', 'queue', 'table']:
if not getattr(endpoints, e, None):
- error_message = "Storage account '{}' has no '{}' endpoint. It
must have table, queue, and blob endpoints all enabled".format(e,
storage_account) # pylint: disable=line-too-long
+ error_message = "Storage account '{}' has no '{}' endpoint. It
must have table, queue, and blob endpoints all enabled".format(storage_account,
e) # pylint: disable=line-too-long
if sku not in allowed_storage_types:
error_message += 'Storage type {} is not allowed'.format(sku)
if error_message:
raise CLIError(error_message)
- obj = storage_client.storage_accounts.list_keys(resource_group_name,
storage_account) # pylint: disable=no-member
+ obj = storage_client.storage_accounts.list_keys(sa_resource_group,
storage_account) # pylint: disable=no-member
try:
keys = [obj.keys[0].value, obj.keys[1].value] # pylint:
disable=no-member
except AttributeError:
@@ -1656,3 +1808,25 @@
client = web_client_factory(cmd.cli_ctx)
full_sku = get_sku_name(sku)
return client.list_geo_regions(full_sku, linux_workers_enabled)
+
+
+def _check_zip_deployment_status(deployment_status_url, authorization):
+ import requests
+ import time
+ num_trials = 1
+ while num_trials < 200:
+ time.sleep(15)
+ response = requests.get(deployment_status_url, headers=authorization)
+ res_dict = response.json()
+ num_trials = num_trials + 1
+ if res_dict['status'] == 5:
+ logger.warning("Zip deployment failed status %s",
res_dict['status_text'])
+ break
+ elif res_dict['status'] == 4:
+ break
+ logger.warning(res_dict['progress'])
+ # if the deployment is taking longer than expected
+ if res_dict['status'] != 4:
+ logger.warning("""Deployment is taking longer than expected. Please
verify status at '%s'
+ beforing launching the app""", deployment_status_url)
+ return res_dict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure-cli-appservice-0.1.31/azure_cli_appservice.egg-info/PKG-INFO
new/azure-cli-appservice-0.2.3/azure_cli_appservice.egg-info/PKG-INFO
--- old/azure-cli-appservice-0.1.31/azure_cli_appservice.egg-info/PKG-INFO
2018-04-06 19:33:30.000000000 +0200
+++ new/azure-cli-appservice-0.2.3/azure_cli_appservice.egg-info/PKG-INFO
2018-08-23 01:09:29.000000000 +0200
@@ -1,12 +1,11 @@
Metadata-Version: 1.1
Name: azure-cli-appservice
-Version: 0.1.31
+Version: 0.2.3
Summary: Microsoft Azure Command-Line Tools AppService Command Module
Home-page: https://github.com/Azure/azure-cli
Author: Microsoft Corporation
Author-email: [email protected]
License: MIT
-Description-Content-Type: UNKNOWN
Description: Microsoft Azure CLI 'appservice' Command Module
===============================================
@@ -20,6 +19,52 @@
Release History
===============
+
+ 0.2.3
+ +++++
+ * support CORS on functionapp & webapp
+ * arm tag support on create commands
+ * `webapp/functionapp identity show`: exception handling to exit with
code 3 upon a missing resource for consistency
+
+ 0.2.2
+ +++++
+ * fix a bug that prevent from creating a function-app using storage
accounts in external resource groups
+ * fix a crash on zip deployment
+
+ 0.2.1
+ +++++
+ * Minor fixes.
+
+ 0.2.0
+ +++++
+ * BREAKING CHANGE: 'show' commands log error message and fail with
exit code of 3 upon a missing resource.
+ * appservice: allow PremiumV2 skus
+
+ 0.1.36
+ ++++++
+ * webapp/functionapp: Adding support for disabling identity az webapp
identity remove. Preview tag removed for Identity feature.
+
+ 0.1.35
+ ++++++
+ * dependencies: remove the cap on the urllib as newer requests was
released
+ * functionapp create: support to use appservice plan from external
resource groups
+
+ 0.1.34
+ ++++++
+ * dependencies: cap the urllib to 1.22 to avoid conflit with requests
2.18.4
+
+ 0.1.33
+ ++++++
+ * webapp/functionapp: improve generic update commands
+ * webapp/functionapp: webapp deployment source config-zip supports
async operation with status updates for long running operation
+
+ 0.1.32
+ ++++++
+ * webapp: fix a bug in `az webapp delete` when `--slot` is provided
+ * webapp: remove `--runtime-version` from `az webapp auth update` as
it's not very public ready
+ * webapp: az webapp config set support for min_tls_version & https2.0
+ * webapp: az webapp create support for multicontainers
+
0.1.31
++++++
* (Breaking change): remove `assign-identity` which was tagged
`deprecating` 2 releases ago
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure-cli-appservice-0.1.31/azure_cli_appservice.egg-info/requires.txt
new/azure-cli-appservice-0.2.3/azure_cli_appservice.egg-info/requires.txt
--- old/azure-cli-appservice-0.1.31/azure_cli_appservice.egg-info/requires.txt
2018-04-06 19:33:30.000000000 +0200
+++ new/azure-cli-appservice-0.2.3/azure_cli_appservice.egg-info/requires.txt
2018-08-23 01:09:29.000000000 +0200
@@ -1,7 +1,9 @@
azure-cli-core
azure-mgmt-web==0.35.0
-azure-mgmt-containerregistry==1.0.1
+azure-mgmt-storage==2.0.0rc4
+azure-mgmt-containerregistry==2.1.0
urllib3[secure]>=1.18
xmltodict
pyOpenSSL
+six
vsts-cd-manager<1.1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure-cli-appservice-0.1.31/setup.py
new/azure-cli-appservice-0.2.3/setup.py
--- old/azure-cli-appservice-0.1.31/setup.py 2018-04-06 19:33:13.000000000
+0200
+++ new/azure-cli-appservice-0.2.3/setup.py 2018-08-23 01:07:57.000000000
+0200
@@ -14,7 +14,7 @@
logger.warn("Wheel is not available, disabling bdist_wheel hook")
cmdclass = {}
-VERSION = "0.1.31"
+VERSION = "0.2.3"
CLASSIFIERS = [
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
@@ -32,11 +32,13 @@
DEPENDENCIES = [
'azure-cli-core',
'azure-mgmt-web==0.35.0',
- 'azure-mgmt-containerregistry==1.0.1',
+ 'azure-mgmt-storage==2.0.0rc4',
+ 'azure-mgmt-containerregistry==2.1.0',
# v1.17 breaks on wildcard cert
https://github.com/shazow/urllib3/issues/981
'urllib3[secure]>=1.18',
'xmltodict',
'pyOpenSSL',
+ 'six',
'vsts-cd-manager<1.1.0',
]