Hello community,

here is the log from the commit of package azure-cli-container for 
openSUSE:Factory checked in at 2019-05-22 10:59:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/azure-cli-container (Old)
 and      /work/SRC/openSUSE:Factory/.azure-cli-container.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "azure-cli-container"

Wed May 22 10:59:37 2019 rev:5 rq:696827 version:0.3.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/azure-cli-container/azure-cli-container.changes  
2018-10-15 10:47:54.279104007 +0200
+++ 
/work/SRC/openSUSE:Factory/.azure-cli-container.new.5148/azure-cli-container.changes
        2019-05-22 10:59:38.942796048 +0200
@@ -1,0 +2,16 @@
+Tue Apr 16 14:05:22 UTC 2019 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- New upstream release
+  + Version 0.3.13
+  + For detailed information about changes see the
+    HISTORY.txt file provided with this package
+- Bump minimum version for Python Azure SDK namespace
+  packages to 3.0.0 in BuildRequires and Requires
+- Remove python3-devel package from BuildRequires
+- Remove unzip package from BuildRequires
+- Run fdupes to hardlink duplicate files
+  + Add fdupes to BuildRequires
+  + Add %fdupes invocation to %install
+- Update Requires from setup.py
+
+-------------------------------------------------------------------

Old:
----
  azure-cli-container-0.3.3.tar.gz

New:
----
  azure-cli-container-0.3.13.tar.gz

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

Other differences:
------------------
++++++ azure-cli-container.spec ++++++
--- /var/tmp/diff_new_pack.1wznXV/_old  2019-05-22 10:59:39.622795167 +0200
+++ /var/tmp/diff_new_pack.1wznXV/_new  2019-05-22 10:59:39.622795167 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package azure-cli-container
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           azure-cli-container
-Version:        0.3.3
+Version:        0.3.13
 Release:        0
 Summary:        Microsoft Azure CLI 'container' Command Module
 License:        MIT
@@ -27,18 +27,18 @@
 Source1:        LICENSE.txt
 BuildRequires:  azure-cli-command-modules-nspkg
 BuildRequires:  azure-cli-nspkg
-BuildRequires:  python3-azure-nspkg
-BuildRequires:  python3-devel
+BuildRequires:  fdupes
+BuildRequires:  python3-azure-nspkg >= 3.0.0
 BuildRequires:  python3-setuptools
-BuildRequires:  unzip
 Requires:       azure-cli-command-modules-nspkg
 Requires:       azure-cli-core
 Requires:       azure-cli-nspkg
-Requires:       python3-PyYAML >= 3.13
-Requires:       python3-azure-mgmt-containerinstance >= 1.0.0
+Requires:       python3-PyYAML >= 4.2b1
+Requires:       python3-azure-mgmt-authorization >= 0.50.0
+Requires:       python3-azure-mgmt-containerinstance >= 1.4.0
 Requires:       python3-azure-mgmt-loganalytics >= 0.2.0
-Requires:       python3-azure-mgmt-resource >= 2.0.0
-Requires:       python3-azure-nspkg
+Requires:       python3-azure-mgmt-network >= 2.4.0
+Requires:       python3-azure-nspkg >= 3.0.0
 Requires:       python3-colorama
 Requires:       python3-websocket-client
 Conflicts:      azure-cli < 2.0.0
@@ -60,6 +60,7 @@
 
 %install
 python3 setup.py install --root=%{buildroot} --prefix=%{_prefix} 
--install-lib=%{python3_sitelib}
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
 rm -rf %{buildroot}%{python3_sitelib}/azure/cli/command_modules/__init__.*
 rm -rf %{buildroot}%{python3_sitelib}/azure/cli/command_modules/__pycache__
 rm -rf %{buildroot}%{python3_sitelib}/azure/cli/__init__.*

++++++ azure-cli-container-0.3.3.tar.gz -> azure-cli-container-0.3.13.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-container-0.3.3/HISTORY.rst 
new/azure-cli-container-0.3.13/HISTORY.rst
--- old/azure-cli-container-0.3.3/HISTORY.rst   2018-08-09 08:34:43.000000000 
+0200
+++ new/azure-cli-container-0.3.13/HISTORY.rst  2019-01-25 20:43:40.000000000 
+0100
@@ -3,6 +3,55 @@
 Release History
 ===============
 
+0.3.13
+++++++
+* Adding 'az container start' command
+* Allow using decimal values for CPU during container creation
+
+0.3.12
+++++++
+* Updating dependencies
+
+0.3.11
+++++++
+* Updating dependencies
+
+0.3.10
+++++++
+* Minor fixes
+
+0.3.9
++++++
+* Minor fixes
+
+0.3.8
++++++
+* Show identity when exporting a container group to yaml
+
+0.3.7
++++++
+* Make 'Private' a valid type to pass to '--ip-address'
+* Allow using only subnet ID to setup a virtual network for the container group
+* Allow using vnet name or resource id to enable using vnets from different 
resource groups
+
+0.3.6
++++++
+* Add '--assign-identity' for adding a MSI identity to a container group
+* Add '--scope' to create a role assignment for the system assigned MSI 
identity
+* Show warning when creating a container group with an image without a long 
running process
+* Fix table output issues for 'list' and 'show' commands
+
+0.3.5
++++++
+* Minor changes
+
+0.3.4
++++++
+* Added ability to restart and stop a running container group
+* Add '--network-profile' for passing in a network profile
+* Add '--subnet', '--vnet_name', to allow creating container groups in a VNET
+* Update the table output to show the status of the container group
+
 0.3.3
 +++++
 * Add '--secure-environment-variables' for passing secure environment 
variables to a container
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-container-0.3.3/PKG-INFO 
new/azure-cli-container-0.3.13/PKG-INFO
--- old/azure-cli-container-0.3.3/PKG-INFO      2018-08-09 08:36:01.000000000 
+0200
+++ new/azure-cli-container-0.3.13/PKG-INFO     2019-01-25 20:43:55.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: azure-cli-container
-Version: 0.3.3
+Version: 0.3.13
 Summary: Microsoft Azure Command-Line Tools container Command Module
 Home-page: https://github.com/Azure/azure-cli
 Author: Microsoft Corporation
@@ -305,6 +305,55 @@
         Release History
         ===============
         
+        0.3.13
+        ++++++
+        * Adding 'az container start' command
+        * Allow using decimal values for CPU during container creation
+        
+        0.3.12
+        ++++++
+        * Updating dependencies
+        
+        0.3.11
+        ++++++
+        * Updating dependencies
+        
+        0.3.10
+        ++++++
+        * Minor fixes
+        
+        0.3.9
+        +++++
+        * Minor fixes
+        
+        0.3.8
+        +++++
+        * Show identity when exporting a container group to yaml
+        
+        0.3.7
+        +++++
+        * Make 'Private' a valid type to pass to '--ip-address'
+        * Allow using only subnet ID to setup a virtual network for the 
container group
+        * Allow using vnet name or resource id to enable using vnets from 
different resource groups
+        
+        0.3.6
+        +++++
+        * Add '--assign-identity' for adding a MSI identity to a container 
group
+        * Add '--scope' to create a role assignment for the system assigned 
MSI identity
+        * Show warning when creating a container group with an image without a 
long running process
+        * Fix table output issues for 'list' and 'show' commands
+        
+        0.3.5
+        +++++
+        * Minor changes
+        
+        0.3.4
+        +++++
+        * Added ability to restart and stop a running container group
+        * Add '--network-profile' for passing in a network profile
+        * Add '--subnet', '--vnet_name', to allow creating container groups in 
a VNET
+        * Update the table output to show the status of the container group
+        
         0.3.3
         +++++
         * Add '--secure-environment-variables' for passing secure environment 
variables to a container
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_client_factory.py
 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_client_factory.py
--- 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_client_factory.py
        2018-08-09 08:34:43.000000000 +0200
+++ 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_client_factory.py
       2019-01-25 20:43:40.000000000 +0100
@@ -32,3 +32,22 @@
     from azure.mgmt.resource import ResourceManagementClient
     from azure.cli.core.commands.client_factory import get_mgmt_service_client
     return get_mgmt_service_client(cli_ctx, ResourceManagementClient)
+
+
+def get_auth_management_client(cli_ctx, scope=None, **_):
+    import re
+    from azure.cli.core.profiles import ResourceType
+    from azure.cli.core.commands.client_factory import get_mgmt_service_client
+
+    subscription_id = None
+    if scope:
+        matched = re.match('/subscriptions/(?P<subscription>[^/]*)/', scope)
+        if matched:
+            subscription_id = matched.groupdict()['subscription']
+    return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_AUTHORIZATION, 
subscription_id=subscription_id)
+
+
+def cf_network(cli_ctx):
+    from azure.mgmt.network import NetworkManagementClient
+    from azure.cli.core.commands.client_factory import get_mgmt_service_client
+    return get_mgmt_service_client(cli_ctx, NetworkManagementClient, 
api_version="2018-08-01")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_format.py 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_format.py
--- 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_format.py    
    2018-08-09 08:34:43.000000000 +0200
+++ 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_format.py   
    2019-01-25 20:43:40.000000000 +0100
@@ -38,19 +38,40 @@
 def _format_ip_address(container_group):
     """Format IP address. """
     ip_address = container_group.get('ipAddress')
-    if ip_address is not None:
-        ports = ','.join(str(p['port']) for p in ip_address['ports'])
+    if ip_address:
+        ports = ip_address['ports'] or []
+
+        if ip_address['type'] == 'Private':
+            for container in container_group.get('containers'):
+                ports += container.get('ports')
+
+        ports = ','.join(str(p['port']) for p in ports)
         return '{0}:{1}'.format(ip_address.get('ip'), ports)
     return None
 
 
+def _format_status(container_group):
+    if container_group['instanceView'] and 
container_group['instanceView']['state']:
+        return container_group['instanceView']['state']
+
+    return container_group['provisioningState']
+
+
+def _format_network(container_group):
+    ip_address = container_group.get('ipAddress')
+    if ip_address:
+        return ip_address['type']
+    return None
+
+
 def transform_container_group(result):
     """Transform a container group to table output. """
     return OrderedDict([('Name', result['name']),
                         ('ResourceGroup', result['resourceGroup']),
-                        ('ProvisioningState', result.get('provisioningState')),
+                        ('Status', _format_status(result)),
                         ('Image', _get_images(result)),
                         ('IP:ports', _format_ip_address(result)),
+                        ('Network', _format_network(result)),
                         ('CPU/Memory', _format_cpu_memory(result)),
                         ('OsType', result.get('osType')),
                         ('Location', result['location'])])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_help.py 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_help.py
--- old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_help.py  
2018-08-09 08:34:43.000000000 +0200
+++ new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_help.py 
2019-01-25 20:43:40.000000000 +0100
@@ -20,9 +20,6 @@
           text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --cpu 1 --memory 1
         - name: Create a container in a container group that runs Windows, 
with 2 cores and 3.5Gb of memory.
           text: az container create -g MyResourceGroup --name mywinapp --image 
winappimage:latest --os-type Windows --cpu 2 --memory 3.5
-        - name: Create a container in a container group with public IP address 
and ports.
-          text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --ip-address public --ports 80 443
-        - name: Create a container in a container group with public IP address 
and UDP port.
           text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --ip-address public --ports 8081 --protocol UDP
         - name: Create a container in a container group with public IP 
address, ports and DNS name label.
           text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --ports 80 443 --dns-name-label contoso
@@ -31,11 +28,9 @@
         - name: Create a container in a container group that runs a command 
and stop the container afterwards.
           text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --command-line "echo hello" --restart-policy Never
         - name: Create a container in a container group with environment 
variables.
-          text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest -e key1=value1 key2=value2
+          text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --environment-variables key1=value1 key2=value2
         - name: Create a container in a container group using container image 
from Azure Container Registry.
           text: az container create -g MyResourceGroup --name myapp --image 
myAcrRegistry.azurecr.io/myimage:latest --registry-password password
-        - name: Create a container in a container group using container image 
from another private container image registry.
-          text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --cpu 1 --memory 1.5 --registry-login-server myregistry.com 
--registry-username username --registry-password password
         - name: Create a container in a container group that mounts an Azure 
File share as volume.
           text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --command-line "cat /mnt/azfile/myfile" 
--azure-file-volume-share-name myshare --azure-file-volume-account-name 
mystorageaccount --azure-file-volume-account-key mystoragekey 
--azure-file-volume-mount-path /mnt/azfile
         - name: Create a container in a container group that mounts a git repo 
as volume.
@@ -44,8 +39,15 @@
           text: az container create -g MyResourceGroup -f containerGroup.yaml
         - name: Create a container group using Log Analytics from a workspace 
name.
           text: az container create -g MyResourceGroup --name myapp 
--log-analytics-workspace myworkspace
-        - name: Create a container group using Log Analytics from a workspace 
id and key.
-          text: az container create -g MyResourceGroup --name myapp 
--log-analytics-workspace workspaceid --log-analytics-workspace-key workspacekey
+        - name: Create a container group with a system assigned identity.
+          text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --assign-identity
+        - name: Create a container group with a system assigned identity. The 
group will have a 'Contributor' role with access to a storage account.
+          text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --assign-identity --scope 
/subscriptions/99999999-1bf0-4dda-aec3-cb9272f09590/MyResourceGroup/myRG/providers/Microsoft.Storage/storageAccounts/storage1
+        - name: Create a container group with a user assigned identity.
+          text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --assign-identity  
/subscriptions/mySubscrpitionId/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID
+        - name: Create a container group with both system and user assigned 
identity.
+          text: az container create -g MyResourceGroup --name myapp --image 
myimage:latest --assign-identity [system] 
/subscriptions/mySubscrpitionId/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID
+          min_profile: latest
 """
 
 helps['container delete'] = """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_params.py 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_params.py
--- 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_params.py    
    2018-08-09 08:34:43.000000000 +0200
+++ 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_params.py   
    2019-01-25 20:43:40.000000000 +0100
@@ -11,11 +11,12 @@
 from azure.cli.core.commands.validators import 
get_default_location_from_resource_group
 from azure.mgmt.containerinstance.models import (
     ContainerGroupRestartPolicy, OperatingSystemTypes, 
ContainerNetworkProtocol)
-from ._validators import validate_volume_mount_path, validate_secrets, 
validate_gitrepo_directory
+from ._validators import (validate_volume_mount_path, validate_secrets, 
validate_subnet, validate_msi,
+                          validate_gitrepo_directory, 
validate_network_profile, validate_image)
 
 # pylint: disable=line-too-long
 
-IP_ADDRESS_TYPES = ['Public']
+IP_ADDRESS_TYPES = ['Public', 'Private']
 
 
 def _environment_variables_type(value):
@@ -46,19 +47,25 @@
     nargs='+'
 )
 
+network_profile_type = CLIArgumentType(
+    validator=validate_network_profile,
+    help="The network profile name or id."
+)
+
 
 # pylint: disable=too-many-statements
 def load_arguments(self, _):
     with self.argument_context('container') as c:
         c.argument('resource_group_name', arg_type=resource_group_name_type)
+        c.argument('container_group_name', options_list=['--name', '-n'], 
help="The name of the container group.")
         c.argument('name', options_list=['--name', '-n'], help="The name of 
the container group", id_part='name')
         c.argument('location', arg_type=get_location_type(self.cli_ctx))
 
     with self.argument_context('container create') as c:
         c.argument('location', arg_type=get_location_type(self.cli_ctx), 
validator=get_default_location_from_resource_group)
-        c.argument('image', help='The container image name')
-        c.argument('cpu', type=int, help='The required number of CPU cores of 
the containers')
-        c.argument('memory', type=float, help='The required memory of the 
containers in GB')
+        c.argument('image', validator=validate_image, help='The container 
image name')
+        c.argument('cpu', type=float, help='The required number of CPU cores 
of the containers, accurate to one decimal place')
+        c.argument('memory', type=float, help='The required memory of the 
containers in GB, accurate to one decimal place')
         c.argument('os_type', arg_type=get_enum_type(OperatingSystemTypes), 
help='The OS type of the containers')
         c.argument('ip_address', arg_type=get_enum_type(IP_ADDRESS_TYPES), 
help='The IP address type of the container group')
         c.argument('ports', type=int, nargs='+', default=[80], help='The ports 
to open')
@@ -72,6 +79,20 @@
         c.argument('secrets_mount_path', validator=validate_volume_mount_path, 
help="The path within the container where the secrets volume should be mounted. 
Must not contain colon ':'.")
         c.argument('file', options_list=['--file', '-f'], help="The path to 
the input file.")
 
+    with self.argument_context('container create', arg_group='Managed Service 
Identity') as c:
+        c.argument('assign_identity', nargs='*', validator=validate_msi, 
help="Space-separated list of assigned identities. Assigned identities are 
either user assigned identities (resource IDs) and / or the system assigned 
identity ('[system]'). See examples for more info.")
+        c.argument('identity_scope', options_list=['--scope'], help="Scope 
that the system assigned identity can access")
+        c.argument('identity_role', options_list=['--role'], help="Role name 
or id the system assigned identity will have")
+
+    with self.argument_context('container create', arg_group='Network') as c:
+        c.argument('network_profile', network_profile_type)
+        c.argument('vnet', help='The name of the VNET when creating a new one 
or referencing an existing one. Can also reference an existing vnet by ID. This 
allows using vnets from other resource groups.')
+        c.argument('vnet_name', help='The name of the VNET when creating a new 
one or referencing an existing one.',
+                   deprecate_info=c.deprecate(redirect="--vnet", hide="0.3.5"))
+        c.argument('vnet_address_prefix', help='The IP address prefix to use 
when creating a new VNET in CIDR format.')
+        c.argument('subnet', options_list=['--subnet'], 
validator=validate_subnet, help='The name of the subnet when creating a new 
VNET or referencing an existing one. Can also reference an existing subnet by 
ID.')
+        c.argument('subnet_address_prefix', help='The subnet IP address prefix 
to use when creating a new VNET in CIDR format.')
+
     with self.argument_context('container create', arg_group='Image Registry') 
as c:
         c.argument('registry_login_server', help='The container image registry 
login server')
         c.argument('registry_username', help='The username to log in container 
image registry server')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_validators.py
 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_validators.py
--- 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/_validators.py
    2018-08-09 08:34:43.000000000 +0200
+++ 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/_validators.py
   2019-01-25 20:43:40.000000000 +0100
@@ -5,6 +5,11 @@
 
 from base64 import b64encode
 from knack.util import CLIError
+from knack.log import get_logger
+
+logger = get_logger(__name__)
+
+short_running_images = ['alpine', 'busybox', 'ubuntu', 'node', 'golang', 
'centos', 'python', 'php']
 
 
 def validate_volume_mount_path(ns):
@@ -35,3 +40,57 @@
 def validate_gitrepo_directory(ns):
     if ns.gitrepo_dir and '..' in ns.gitrepo_dir:
         raise CLIError("The git repo directory cannot contain '..'")
+
+
+def validate_image(ns):
+    if ns.image and ns.image.split(':')[0] in short_running_images and not 
ns.command_line:
+        logger.warning('Image "%s" has no long running process. The 
"--command-line" argument must be used to start a '
+                       'long running process inside the container for the 
container group to stay running. '
+                       'Ex: "tail -f /dev/null" '
+                       'For more imformation visit 
https://aka.ms/aci/troubleshoot',
+                       ns.image)
+
+
+def validate_msi(namespace):
+    MSI_LOCAL_ID = '[system]'
+    if namespace.assign_identity is not None:
+        identities = namespace.assign_identity or []
+        if not namespace.identity_scope and getattr(namespace.identity_role, 
'is_default', None) is None:
+            raise CLIError("usage error: '--role {}' is not applicable as the 
'--scope' is not provided".format(
+                namespace.identity_role))
+
+        if namespace.identity_scope:
+            if identities and MSI_LOCAL_ID not in identities:
+                raise CLIError("usage error: '--scope'/'--role' is only 
applicable when assign system identity")
+
+    elif namespace.identity_scope or getattr(namespace.identity_role, 
'is_default', None) is None:
+        raise CLIError('usage error: --assign-identity [--scope SCOPE] [--role 
ROLE]')
+
+
+def validate_subnet(ns):
+    from msrestazure.tools import is_valid_resource_id
+
+    # vnet_name is depricated, using for backwards compatability
+    if ns.vnet_name and not ns.vnet:
+        ns.vnet = ns.vnet_name
+
+    if not is_valid_resource_id(ns.subnet) and ((ns.vnet and not ns.subnet) or 
(ns.subnet and not ns.vnet)):
+        raise CLIError('usage error: --vnet NAME --subnet NAME | --vnet ID 
--subnet NAME | --subnet ID')
+
+
+def validate_network_profile(cmd, ns):
+    from azure.cli.core.commands.client_factory import get_subscription_id
+    from msrestazure.tools import is_valid_resource_id, resource_id
+
+    if ns.network_profile and ns.ip_address:
+        raise CLIError('Can not use "--network-profile" with IP address type 
"Public".')
+    elif ns.network_profile and ns.dns_name_label:
+        raise CLIError('Can not use "--network-profile" with 
"--dns-name-label".')
+    elif ns.network_profile:
+        if not is_valid_resource_id(ns.network_profile):
+            ns.network_profile = resource_id(
+                subscription=get_subscription_id(cmd.cli_ctx),
+                resource_group=ns.resource_group_name,
+                namespace='Microsoft.Network', type='networkProfiles',
+                name=ns.network_profile
+            )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/commands.py 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/commands.py
--- 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/commands.py   
    2018-08-09 08:34:43.000000000 +0200
+++ 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/commands.py  
    2019-01-25 20:43:40.000000000 +0100
@@ -3,10 +3,17 @@
 # Licensed under the MIT License. See License.txt in the project root for 
license information.
 # 
--------------------------------------------------------------------------------------------
 
+from azure.cli.core.commands import CliCommandType
 from ._client_factory import cf_container_groups, cf_container
 from ._format import transform_container_group_list, transform_container_group
 
 
+container_group_sdk = CliCommandType(
+    
operations_tmpl='azure.mgmt.containerinstance.operations.container_groups_operations#ContainerGroupsOperations.{}',
+    client_factory=cf_container_groups
+)
+
+
 def load_command_table(self, _):
     with self.command_group('container', client_factory=cf_container_groups) 
as g:
         g.custom_command('list', 'list_containers', 
table_transformer=transform_container_group_list)
@@ -18,3 +25,8 @@
         g.custom_command('exec', 'container_exec')
         g.custom_command('export', 'container_export')
         g.custom_command('attach', 'attach_to_container')
+
+    with self.command_group('container', container_group_sdk) as g:
+        g.command('restart', 'restart')
+        g.command('stop', 'stop')
+        g.command('start', 'start')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure/cli/command_modules/container/custom.py 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/custom.py
--- old/azure-cli-container-0.3.3/azure/cli/command_modules/container/custom.py 
2018-08-09 08:34:43.000000000 +0200
+++ 
new/azure-cli-container-0.3.13/azure/cli/command_modules/container/custom.py    
    2019-01-25 20:43:40.000000000 +0100
@@ -3,7 +3,7 @@
 # Licensed under the MIT License. See License.txt in the project root for 
license information.
 # 
--------------------------------------------------------------------------------------------
 
-# pylint: 
disable=too-few-public-methods,too-many-arguments,no-self-use,too-many-locals,line-too-long,unused-argument
+# pylint: 
disable=too-few-public-methods,no-self-use,too-many-locals,line-too-long,unused-argument
 
 import errno
 try:
@@ -32,10 +32,10 @@
 from azure.mgmt.containerinstance.models import (AzureFileVolume, Container, 
ContainerGroup, ContainerGroupNetworkProtocol,
                                                  ContainerPort, 
ImageRegistryCredential, IpAddress, Port, ResourceRequests,
                                                  ResourceRequirements, Volume, 
VolumeMount, ContainerExecRequestTerminalSize,
-                                                 GitRepoVolume, LogAnalytics, 
ContainerGroupDiagnostics)
+                                                 GitRepoVolume, LogAnalytics, 
ContainerGroupDiagnostics, ContainerGroupNetworkProfile,
+                                                 ContainerGroupIpAddressType, 
ResourceIdentityType, ContainerGroupIdentity)
 from azure.cli.core.util import sdk_no_wait
-from msrestazure.tools import parse_resource_id
-from ._client_factory import cf_container_groups, cf_container, 
cf_log_analytics, cf_resource
+from ._client_factory import (cf_container_groups, cf_container, 
cf_log_analytics, cf_resource, cf_network)
 
 logger = get_logger(__name__)
 WINDOWS_NAME = 'Windows'
@@ -44,6 +44,7 @@
 AZURE_FILE_VOLUME_NAME = 'azurefile'
 SECRETS_VOLUME_NAME = 'secrets'
 GITREPO_VOLUME_NAME = 'gitrepo'
+MSI_LOCAL_ID = '[system]'
 
 
 def list_containers(client, resource_group_name=None):
@@ -63,6 +64,7 @@
     return client.delete(resource_group_name, name)
 
 
+# pylint: disable=too-many-statements
 def create_container(cmd,
                      resource_group_name,
                      name=None,
@@ -88,6 +90,12 @@
                      azure_file_volume_mount_path=None,
                      log_analytics_workspace=None,
                      log_analytics_workspace_key=None,
+                     vnet=None,
+                     vnet_name=None,
+                     vnet_address_prefix='10.0.0.0/16',
+                     subnet=None,
+                     subnet_address_prefix='10.0.0.0/24',
+                     network_profile=None,
                      gitrepo_url=None,
                      gitrepo_dir='.',
                      gitrepo_revision=None,
@@ -95,9 +103,11 @@
                      secrets=None,
                      secrets_mount_path=None,
                      file=None,
+                     assign_identity=None,
+                     identity_scope=None,
+                     identity_role='Contributor',
                      no_wait=False):
     """Create a container group. """
-
     if file:
         return _create_update_from_file(cmd.cli_ctx, resource_group_name, 
name, location, file, no_wait)
 
@@ -164,14 +174,26 @@
         volumes.append(gitrepo_volume)
         mounts.append(gitrepo_volume_mount)
 
-    cgroup_ip_address = _create_ip_address(ip_address, ports, protocol, 
dns_name_label)
-
     # Concatenate secure and standard environment variables
     if environment_variables and secure_environment_variables:
         environment_variables = environment_variables + 
secure_environment_variables
     else:
         environment_variables = environment_variables or 
secure_environment_variables
 
+    identity = None
+    if assign_identity is not None:
+        identity = _build_identities_info(assign_identity)
+
+    # Set up VNET, subnet and network profile if needed
+    if subnet and not network_profile:
+        network_profile = _get_vnet_network_profile(cmd, location, 
resource_group_name, vnet, vnet_address_prefix, subnet, subnet_address_prefix)
+
+    cg_network_profile = None
+    if network_profile:
+        cg_network_profile = ContainerGroupNetworkProfile(id=network_profile)
+
+    cgroup_ip_address = _create_ip_address(ip_address, ports, protocol, 
dns_name_label, network_profile)
+
     container = Container(name=name,
                           image=image,
                           resources=container_resource_requirements,
@@ -182,20 +204,154 @@
                           volume_mounts=mounts or None)
 
     cgroup = ContainerGroup(location=location,
+                            identity=identity,
                             containers=[container],
                             os_type=os_type,
                             restart_policy=restart_policy,
                             ip_address=cgroup_ip_address,
                             
image_registry_credentials=image_registry_credentials,
                             volumes=volumes or None,
+                            network_profile=cg_network_profile,
                             diagnostics=diagnostics,
                             tags=tags)
 
     container_group_client = cf_container_groups(cmd.cli_ctx)
-    return sdk_no_wait(no_wait, container_group_client.create_or_update, 
resource_group_name, name, cgroup)
+
+    lro = sdk_no_wait(no_wait, container_group_client.create_or_update, 
resource_group_name,
+                      name, cgroup)
+
+    if assign_identity is not None and identity_scope:
+        from azure.cli.core.commands.arm import assign_identity
+        cg = container_group_client.get(resource_group_name, name)
+        assign_identity(cmd.cli_ctx, lambda: cg, lambda cg: cg, identity_role, 
identity_scope)
+
+    return lro
+
+
+def _build_identities_info(identities):
+    identities = identities or []
+    identity_type = ResourceIdentityType.none
+    if not identities or MSI_LOCAL_ID in identities:
+        identity_type = ResourceIdentityType.system_assigned
+    external_identities = [x for x in identities if x != MSI_LOCAL_ID]
+    if external_identities and identity_type == 
ResourceIdentityType.system_assigned:
+        identity_type = ResourceIdentityType.system_assigned_user_assigned
+    elif external_identities:
+        identity_type = ResourceIdentityType.user_assigned
+    identity = ContainerGroupIdentity(type=identity_type)
+    if external_identities:
+        identity.user_assigned_identities = {e: {} for e in 
external_identities}
+    return identity
+
+
+def _get_resource(client, resource_group_name, *subresources):
+    from msrestazure.azure_exceptions import CloudError
+    try:
+        resource = client.get(resource_group_name, *subresources)
+        return resource
+    except CloudError as ex:
+        if ex.error.error == "NotFound" or ex.error.error == 
"ResourceNotFound":
+            return None
+        else:
+            raise
+
+
+def _get_vnet_network_profile(cmd, location, resource_group_name, vnet, 
vnet_address_prefix, subnet, subnet_address_prefix):
+    from azure.cli.core.profiles import ResourceType
+    from msrestazure.tools import parse_resource_id, is_valid_resource_id
+
+    aci_delegation_service_name = "Microsoft.ContainerInstance/containerGroups"
+    Delegation = cmd.get_models('Delegation', 
resource_type=ResourceType.MGMT_NETWORK)
+    aci_delegation = Delegation(
+        name=aci_delegation_service_name,
+        service_name=aci_delegation_service_name
+    )
+
+    ncf = cf_network(cmd.cli_ctx)
+
+    vnet_name = vnet
+    subnet_name = subnet
+    if is_valid_resource_id(subnet):
+        parsed_subnet_id = parse_resource_id(subnet)
+        subnet_name = parsed_subnet_id['resource_name']
+        vnet_name = parsed_subnet_id['name']
+        resource_group_name = parsed_subnet_id['resource_group']
+    elif is_valid_resource_id(vnet):
+        parsed_vnet_id = parse_resource_id(vnet)
+        vnet_name = parsed_vnet_id['resource_name']
+        resource_group_name = parsed_vnet_id['resource_group']
+
+    default_network_profile_name = 
"aci-network-profile-{}-{}".format(vnet_name, subnet_name)
+
+    subnet = _get_resource(ncf.subnets, resource_group_name, vnet_name, 
subnet_name)
+    # For an existing subnet, validate and add delegation if needed
+    if subnet:
+        logger.info('Using existing subnet "%s" in resource group "%s"', 
subnet.name, resource_group_name)
+        for sal in (subnet.service_association_links or []):
+            if sal.linked_resource_type != aci_delegation_service_name:
+                raise CLIError("Can not use subnet with existing service 
association links other than {}.".format(aci_delegation_service_name))
+
+        if not subnet.delegations:
+            logger.info('Adding ACI delegation to the existing subnet.')
+            subnet.delegations = [aci_delegation]
+            subnet = ncf.subnets.create_or_update(resource_group_name, 
vnet_name, subnet_name, subnet).result()
+        else:
+            for delegation in subnet.delegations:
+                if delegation.service_name != aci_delegation_service_name:
+                    raise CLIError("Can not use subnet with existing 
delegations other than {}".format(aci_delegation_service_name))
+
+        network_profile = _get_resource(ncf.network_profiles, 
resource_group_name, default_network_profile_name)
+        if network_profile:
+            logger.info('Using existing network profile "%s"', 
default_network_profile_name)
+            return network_profile.id
+
+    # Create new subnet and Vnet if not exists
+    else:
+        Subnet, VirtualNetwork, AddressSpace = cmd.get_models('Subnet', 
'VirtualNetwork',
+                                                              'AddressSpace', 
resource_type=ResourceType.MGMT_NETWORK)
+
+        vnet = _get_resource(ncf.virtual_networks, resource_group_name, 
vnet_name)
+        if not vnet:
+            logger.info('Creating new vnet "%s" in resource group "%s"', 
vnet_name, resource_group_name)
+            ncf.virtual_networks.create_or_update(resource_group_name,
+                                                  vnet_name,
+                                                  
VirtualNetwork(name=vnet_name,
+                                                                 
location=location,
+                                                                 
address_space=AddressSpace(address_prefixes=[vnet_address_prefix])))
+        subnet = Subnet(
+            name=subnet_name,
+            location=location,
+            address_prefix=subnet_address_prefix,
+            delegations=[aci_delegation])
+
+        logger.info('Creating new subnet "%s" in resource group "%s"', 
subnet_name, resource_group_name)
+        subnet = ncf.subnets.create_or_update(resource_group_name, vnet_name, 
subnet_name, subnet).result()
+
+    NetworkProfile, ContainerNetworkInterfaceConfiguration, 
IPConfigurationProfile = cmd.get_models('NetworkProfile',
+                                                                               
                     'ContainerNetworkInterfaceConfiguration',
+                                                                               
                     'IPConfigurationProfile',
+                                                                               
                     resource_type=ResourceType.MGMT_NETWORK)
+    # In all cases, create the network profile with aci NIC
+    network_profile = NetworkProfile(
+        name=default_network_profile_name,
+        location=location,
+        
container_network_interface_configurations=[ContainerNetworkInterfaceConfiguration(
+            name="eth0",
+            ip_configurations=[IPConfigurationProfile(
+                name="ipconfigprofile",
+                subnet=subnet
+            )]
+        )]
+    )
+
+    logger.info('Creating network profile "%s" in resource group "%s"', 
default_network_profile_name, resource_group_name)
+    network_profile = 
ncf.network_profiles.create_or_update(resource_group_name, 
default_network_profile_name, network_profile).result()
+
+    return network_profile.id
 
 
 def _get_diagnostics_from_workspace(cli_ctx, log_analytics_workspace):
+    from msrestazure.tools import parse_resource_id
     log_analytics_client = cf_log_analytics(cli_ctx)
 
     for workspace in log_analytics_client.list():
@@ -217,7 +373,6 @@
 def _create_update_from_file(cli_ctx, resource_group_name, name, location, 
file, no_wait):
     resource_client = cf_resource(cli_ctx)
     container_group_client = cf_container_groups(cli_ctx)
-
     cg_defintion = None
 
     try:
@@ -370,10 +525,14 @@
 
 
 # pylint: disable=inconsistent-return-statements
-def _create_ip_address(ip_address, ports, protocol, dns_name_label):
+def _create_ip_address(ip_address, ports, protocol, dns_name_label, 
network_profile):
     """Create IP address. """
     if (ip_address and ip_address.lower() == 'public') or dns_name_label:
-        return IpAddress(ports=[Port(protocol=protocol, port=p) for p in 
ports], dns_name_label=dns_name_label)
+        return IpAddress(ports=[Port(protocol=protocol, port=p) for p in 
ports],
+                         dns_name_label=dns_name_label, 
type=ContainerGroupIpAddressType.public)
+    elif network_profile:
+        return IpAddress(ports=[Port(protocol=protocol, port=p) for p in 
ports],
+                         type=ContainerGroupIpAddressType.private)
 
 
 # pylint: disable=inconsistent-return-statements
@@ -402,7 +561,6 @@
 def container_export(cmd, resource_group_name, name, file):
     resource_client = cf_resource(cmd.cli_ctx)
     container_group_client = cf_container_groups(cmd.cli_ctx)
-
     resource = resource_client.resources.get(resource_group_name,
                                              "Microsoft.ContainerInstance",
                                              '',
@@ -410,17 +568,26 @@
                                              name,
                                              
container_group_client.api_version,
                                              False).__dict__
-
     # Remove unwanted properites
     resource['properties'].pop('instanceView', None)
     resource.pop('sku', None)
     resource.pop('id', None)
     resource.pop('plan', None)
-    resource.pop('identity', None)
     resource.pop('kind', None)
     resource.pop('managed_by', None)
     resource['properties'].pop('provisioningState', None)
 
+    # Correctly export the identity
+    if 'identity' in resource and resource['identity'].type != 
ResourceIdentityType.none:
+        resource['identity'] = resource['identity'].__dict__
+        identity_entry = {'type': resource['identity']['type'].value}
+        if resource['identity']['user_assigned_identities']:
+            identity_entry['user_assigned_identities'] = {k: {} for k in 
resource['identity']['user_assigned_identities']}
+        resource['identity'] = identity_entry
+    else:
+        resource.pop('identity', None)
+
+    # Remove container instance views
     for i in range(len(resource['properties']['containers'])):
         
resource['properties']['containers'][i]['properties'].pop('instanceView', None)
 
@@ -651,3 +818,8 @@
     if lines > 0:
         # Use stdout.write to support Python 2
         sys.stdout.write('\033[{}A\033[K\033[J'.format(lines))
+
+
+def _gen_guid():
+    import uuid
+    return uuid.uuid4()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure_cli_container.egg-info/PKG-INFO 
new/azure-cli-container-0.3.13/azure_cli_container.egg-info/PKG-INFO
--- old/azure-cli-container-0.3.3/azure_cli_container.egg-info/PKG-INFO 
2018-08-09 08:36:01.000000000 +0200
+++ new/azure-cli-container-0.3.13/azure_cli_container.egg-info/PKG-INFO        
2019-01-25 20:43:55.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: azure-cli-container
-Version: 0.3.3
+Version: 0.3.13
 Summary: Microsoft Azure Command-Line Tools container Command Module
 Home-page: https://github.com/Azure/azure-cli
 Author: Microsoft Corporation
@@ -305,6 +305,55 @@
         Release History
         ===============
         
+        0.3.13
+        ++++++
+        * Adding 'az container start' command
+        * Allow using decimal values for CPU during container creation
+        
+        0.3.12
+        ++++++
+        * Updating dependencies
+        
+        0.3.11
+        ++++++
+        * Updating dependencies
+        
+        0.3.10
+        ++++++
+        * Minor fixes
+        
+        0.3.9
+        +++++
+        * Minor fixes
+        
+        0.3.8
+        +++++
+        * Show identity when exporting a container group to yaml
+        
+        0.3.7
+        +++++
+        * Make 'Private' a valid type to pass to '--ip-address'
+        * Allow using only subnet ID to setup a virtual network for the 
container group
+        * Allow using vnet name or resource id to enable using vnets from 
different resource groups
+        
+        0.3.6
+        +++++
+        * Add '--assign-identity' for adding a MSI identity to a container 
group
+        * Add '--scope' to create a role assignment for the system assigned 
MSI identity
+        * Show warning when creating a container group with an image without a 
long running process
+        * Fix table output issues for 'list' and 'show' commands
+        
+        0.3.5
+        +++++
+        * Minor changes
+        
+        0.3.4
+        +++++
+        * Added ability to restart and stop a running container group
+        * Add '--network-profile' for passing in a network profile
+        * Add '--subnet', '--vnet_name', to allow creating container groups in 
a VNET
+        * Update the table output to show the status of the container group
+        
         0.3.3
         +++++
         * Add '--secure-environment-variables' for passing secure environment 
variables to a container
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-container-0.3.3/azure_cli_container.egg-info/requires.txt 
new/azure-cli-container-0.3.13/azure_cli_container.egg-info/requires.txt
--- old/azure-cli-container-0.3.3/azure_cli_container.egg-info/requires.txt     
2018-08-09 08:36:01.000000000 +0200
+++ new/azure-cli-container-0.3.13/azure_cli_container.egg-info/requires.txt    
2019-01-25 20:43:55.000000000 +0100
@@ -1,7 +1,8 @@
-azure-mgmt-containerinstance==1.0.0
+azure-mgmt-containerinstance==1.4.0
 azure-mgmt-loganalytics==0.2.0
-azure-mgmt-resource==2.0.0
+azure-mgmt-network==2.4.0
+azure-mgmt-authorization==0.50.0
 azure-cli-core
-pyyaml>=3.13
+pyyaml>=4.2b1
 colorama
 websocket-client
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-container-0.3.3/setup.py 
new/azure-cli-container-0.3.13/setup.py
--- old/azure-cli-container-0.3.3/setup.py      2018-08-09 08:34:43.000000000 
+0200
+++ new/azure-cli-container-0.3.13/setup.py     2019-01-25 20:43:40.000000000 
+0100
@@ -14,7 +14,7 @@
     logger.warn("Wheel is not available, disabling bdist_wheel hook")
     cmdclass = {}
 
-VERSION = "0.3.3"
+VERSION = "0.3.13"
 
 CLASSIFIERS = [
     'Development Status :: 4 - Beta',
@@ -31,11 +31,12 @@
 ]
 
 DEPENDENCIES = [
-    'azure-mgmt-containerinstance==1.0.0',
+    'azure-mgmt-containerinstance==1.4.0',
     'azure-mgmt-loganalytics==0.2.0',
-    'azure-mgmt-resource==2.0.0',
+    'azure-mgmt-network==2.4.0',
+    'azure-mgmt-authorization==0.50.0',
     'azure-cli-core',
-    'pyyaml>=3.13',
+    'pyyaml>=4.2b1',
     'colorama',
     'websocket-client'
 ]


Reply via email to