Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/command_modules/azure-cli-container/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
Release History
===============

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# pylint: disable=line-too-long

IP_ADDRESS_TYPES = ['Public']
IP_ADDRESS_TYPES = ['Public', 'Private']


def _environment_variables_type(value):
Expand Down Expand Up @@ -82,7 +82,9 @@ def load_arguments(self, _):

with self.argument_context('container create', arg_group='Network') as c:
c.argument('network_profile', network_profile_type)
c.argument('vnet_name', help='The name of the VNET when creating a new one or referencing an existing one.')
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.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,23 @@ def validate_gitrepo_directory(ns):


def validate_image(ns):
if ns.image.split(':')[0] in short_running_images and not ns.command_line:
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: /bin/bash',
'Ex: "tail -f /dev/null" '
'For more imformation visit https://aka.ms/aci/troubleshoot',
ns.image)


def validate_subnet(ns):
from msrestazure.tools import is_valid_resource_id

if not is_valid_resource_id(ns.subnet) and ((ns.vnet_name and not ns.subnet) or (ns.subnet and not ns.vnet_name)):
raise CLIError('usage error: --vnet-name NAME --subnet NAME | --subnet 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):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def create_container(cmd,
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,
Expand Down Expand Up @@ -183,8 +184,8 @@ def create_container(cmd,
identity = _build_identities_info(assign_identity)

# Set up VNET, subnet and network profile if needed
if subnet and vnet_name and not network_profile:
network_profile = _get_vnet_network_profile(cmd, location, resource_group_name, vnet_name, vnet_address_prefix, subnet, subnet_address_prefix)
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:
Expand Down Expand Up @@ -245,51 +246,63 @@ def _get_resource(client, resource_group_name, *subresources):
raise


def _get_vnet_network_profile(cmd, location, resource_group_name, vnet_name, vnet_address_prefix, subnet, subnet_address_prefix):
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

containerInstanceDelegationServiceName = "Microsoft.ContainerInstance/containerGroups"
aci_delegation_service_name = "Microsoft.ContainerInstance/containerGroups"
Delegation = cmd.get_models('Delegation', resource_type=ResourceType.MGMT_NETWORK)
aci_delegation = Delegation(
name="Microsoft.ContainerInstance.containerGroups",
service_name="Microsoft.ContainerInstance/containerGroups"
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:
for endpoint in (subnet.service_endpoints or []):
if endpoint.service != "Microsoft.ContainerInstance":
raise CLIError("Can not use subnet with existing service links other than 'Microsoft.ContainerInstance'.")
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 != containerInstanceDelegationServiceName:
raise CLIError("Can not use subnet with existing delegations other than {}".format(containerInstanceDelegationServiceName))
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,
Expand All @@ -301,13 +314,13 @@ def _get_vnet_network_profile(cmd, location, resource_group_name, vnet_name, vne
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,
Expand All @@ -321,6 +334,7 @@ def _get_vnet_network_profile(cmd, location, resource_group_name, vnet_name, vne
)]
)

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
Expand Down
Loading