|
|
@@ -6,19 +6,21 @@ import json
|
|
|
import logging
|
|
|
import time
|
|
|
|
|
|
+
|
|
|
from azure.common import AzureException
|
|
|
from azure.mgmt.network.models import NetworkSecurityGroup
|
|
|
|
|
|
from cloudbridge.cloud.base.resources import BaseAttachmentInfo, \
|
|
|
BaseBucket, BaseBucketObject, BaseFloatingIP, \
|
|
|
- BaseInstance, BaseInstanceType, BaseKeyPair, \
|
|
|
- BaseLaunchConfig, BaseMachineImage, BaseNetwork, \
|
|
|
+ BaseInstance, BaseInternetGateway, \
|
|
|
+ BaseKeyPair, BaseLaunchConfig, BaseMachineImage, BaseNetwork, \
|
|
|
BasePlacementZone, BaseRegion, BaseRouter, BaseSecurityGroup, \
|
|
|
BaseSecurityGroupRule, BaseSnapshot, BaseSubnet, \
|
|
|
- BaseVolume, ClientPagedResultList
|
|
|
+ BaseVMType, BaseVolume, ClientPagedResultList
|
|
|
from cloudbridge.cloud.interfaces import InstanceState, VolumeState
|
|
|
from cloudbridge.cloud.interfaces.resources import Instance, \
|
|
|
- MachineImageState, NetworkState, RouterState, SnapshotState
|
|
|
+ MachineImageState, NetworkState, RouterState, \
|
|
|
+ SnapshotState, SubnetState
|
|
|
from cloudbridge.cloud.providers.azure import helpers as azure_helpers
|
|
|
|
|
|
from msrestazure.azure_exceptions import CloudError
|
|
|
@@ -91,6 +93,7 @@ class AzureSecurityGroup(BaseSecurityGroup):
|
|
|
|
|
|
@name.setter
|
|
|
def name(self, value):
|
|
|
+ self.assert_valid_resource_name(value)
|
|
|
self._security_group.tags.update(Name=value)
|
|
|
self._provider.azure_client. \
|
|
|
update_security_group_tags(self.id,
|
|
|
@@ -103,7 +106,7 @@ class AzureSecurityGroup(BaseSecurityGroup):
|
|
|
@description.setter
|
|
|
def description(self, value):
|
|
|
self._security_group.tags.update(Description=value)
|
|
|
- self._provider.azure_client. \
|
|
|
+ self._provider.azure_client.\
|
|
|
update_security_group_tags(self.id,
|
|
|
self._security_group.tags)
|
|
|
|
|
|
@@ -121,13 +124,26 @@ class AzureSecurityGroup(BaseSecurityGroup):
|
|
|
|
|
|
def delete(self):
|
|
|
try:
|
|
|
- self._provider.azure_client. \
|
|
|
+ self._provider.azure_client.\
|
|
|
delete_security_group(self.id)
|
|
|
return True
|
|
|
except CloudError as cloudError:
|
|
|
log.exception(cloudError.message)
|
|
|
return False
|
|
|
|
|
|
+ def refresh(self):
|
|
|
+ """
|
|
|
+ Refreshes the security group with tags if required.
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ self._security_group = self._provider.azure_client. \
|
|
|
+ get_security_group(self.id)
|
|
|
+ if not self._security_group.tags:
|
|
|
+ self._security_group.tags = {}
|
|
|
+ except (CloudError, ValueError) as cloudError:
|
|
|
+ log.exception(cloudError.message)
|
|
|
+ # The security group no longer exists and cannot be refreshed.
|
|
|
+
|
|
|
def add_rule(self, ip_protocol=None, from_port=None, to_port=None,
|
|
|
cidr_ip=None, src_group=None):
|
|
|
"""
|
|
|
@@ -160,7 +176,7 @@ class AzureSecurityGroup(BaseSecurityGroup):
|
|
|
return self._create_rule(ip_protocol, from_port, to_port, cidr_ip)
|
|
|
elif src_group:
|
|
|
result = None
|
|
|
- sg = (self._provicer.security.security_groups.get(src_group)
|
|
|
+ sg = (self._provider.security.security_groups.get(src_group)
|
|
|
if isinstance(src_group, str) else src_group)
|
|
|
for rule in sg.rules:
|
|
|
result = self._create_rule(rule.ip_protocol, rule.from_port,
|
|
|
@@ -208,9 +224,9 @@ class AzureSecurityGroup(BaseSecurityGroup):
|
|
|
cidr_ip=None, src_group=None):
|
|
|
for rule in self.rules:
|
|
|
if (rule.ip_protocol == ip_protocol and
|
|
|
- rule.from_port == str(from_port) and
|
|
|
- rule.to_port == str(to_port) and
|
|
|
- rule.cidr_ip == cidr_ip):
|
|
|
+ rule.from_port == str(from_port) and
|
|
|
+ rule.to_port == str(to_port) and
|
|
|
+ rule.cidr_ip == cidr_ip):
|
|
|
return rule
|
|
|
return None
|
|
|
|
|
|
@@ -221,7 +237,7 @@ class AzureSecurityGroup(BaseSecurityGroup):
|
|
|
js['rules'] = [json.loads(r) for r in json_rules]
|
|
|
if js.get('network_id'):
|
|
|
js.pop('network_id') # Omit for consistency across cloud providers
|
|
|
- return json.dumps(js, sort_keys=True)
|
|
|
+ return js
|
|
|
|
|
|
|
|
|
class AzureSecurityGroupRule(BaseSecurityGroupRule):
|
|
|
@@ -370,7 +386,7 @@ class AzureBucketObject(BaseBucketObject):
|
|
|
Generate a URL to this object.
|
|
|
"""
|
|
|
return self._provider.azure_client.get_blob_url(
|
|
|
- self._container.name, self.name)
|
|
|
+ self._container.name, self.name, expires_in)
|
|
|
|
|
|
|
|
|
class AzureBucket(BaseBucket):
|
|
|
@@ -414,6 +430,11 @@ class AzureBucket(BaseBucket):
|
|
|
return ClientPagedResultList(self._provider, objects,
|
|
|
limit=limit, marker=marker)
|
|
|
|
|
|
+ def find(self, name, limit=None, marker=None):
|
|
|
+ objects = [obj for obj in self if obj.name == name]
|
|
|
+ return ClientPagedResultList(self._provider, objects,
|
|
|
+ limit=limit, marker=marker)
|
|
|
+
|
|
|
def delete(self, delete_contents=True):
|
|
|
"""
|
|
|
Delete this bucket.
|
|
|
@@ -495,6 +516,7 @@ class AzureVolume(BaseVolume):
|
|
|
Set the volume name.
|
|
|
"""
|
|
|
# self._volume.name = value
|
|
|
+ self.assert_valid_resource_name(value)
|
|
|
self._volume.tags.update(Name=value)
|
|
|
self._provider.azure_client. \
|
|
|
update_disk_tags(self.id,
|
|
|
@@ -526,7 +548,7 @@ class AzureVolume(BaseVolume):
|
|
|
@property
|
|
|
def source(self):
|
|
|
if self._volume.creation_data.source_uri:
|
|
|
- url_params = azure_helpers. \
|
|
|
+ url_params = azure_helpers.\
|
|
|
parse_url(SNAPSHOT_RESOURCE_ID,
|
|
|
self._volume.creation_data.source_uri)
|
|
|
return self._provider.storage.snapshots. \
|
|
|
@@ -682,7 +704,7 @@ class AzureSnapshot(BaseSnapshot):
|
|
|
"""
|
|
|
Set the snapshot name.
|
|
|
"""
|
|
|
- # self._snapshot.name = value
|
|
|
+ self.assert_valid_resource_name(value)
|
|
|
self._snapshot.tags.update(Name=value)
|
|
|
self._provider.azure_client. \
|
|
|
update_snapshot_tags(self.id,
|
|
|
@@ -705,7 +727,7 @@ class AzureSnapshot(BaseSnapshot):
|
|
|
|
|
|
@property
|
|
|
def volume_id(self):
|
|
|
- url_params = azure_helpers. \
|
|
|
+ url_params = azure_helpers.\
|
|
|
parse_url(VOLUME_RESOURCE_ID,
|
|
|
self._snapshot.creation_data.source_resource_id)
|
|
|
return url_params.get(VOLUME_NAME)
|
|
|
@@ -799,6 +821,7 @@ class AzureMachineImage(BaseMachineImage):
|
|
|
"""
|
|
|
Set the image name.
|
|
|
"""
|
|
|
+ self.assert_valid_resource_name(value)
|
|
|
self._image.tags.update(Name=value)
|
|
|
self._provider.azure_client. \
|
|
|
update_image_tags(self.id, self._image.tags)
|
|
|
@@ -852,7 +875,7 @@ class AzureMachineImage(BaseMachineImage):
|
|
|
for its latest state.
|
|
|
"""
|
|
|
try:
|
|
|
- self._image = self._provider.azure_client \
|
|
|
+ self._image = self._provider.azure_client\
|
|
|
.get_image(self.id)
|
|
|
self._state = self._image.provisioning_state
|
|
|
except CloudError as cloudError:
|
|
|
@@ -897,9 +920,10 @@ class AzureNetwork(BaseNetwork):
|
|
|
"""
|
|
|
Set the network name.
|
|
|
"""
|
|
|
+ self.assert_valid_resource_name(value)
|
|
|
self._network.tags.update(Name=value)
|
|
|
self._provider.azure_client. \
|
|
|
- update_network_tags(self.id, self._network.tags)
|
|
|
+ update_network_tags(self.id, self._network)
|
|
|
|
|
|
@property
|
|
|
def external(self):
|
|
|
@@ -920,7 +944,7 @@ class AzureNetwork(BaseNetwork):
|
|
|
for its latest state.
|
|
|
"""
|
|
|
try:
|
|
|
- self._network = self._provider.azure_client. \
|
|
|
+ self._network = self._provider.azure_client.\
|
|
|
get_network(self.id)
|
|
|
self._state = self._network.provisioning_state
|
|
|
except (CloudError, ValueError) as cloudError:
|
|
|
@@ -942,19 +966,20 @@ class AzureNetwork(BaseNetwork):
|
|
|
Delete an existing network.
|
|
|
"""
|
|
|
try:
|
|
|
- self._provider.azure_client. \
|
|
|
+ self._provider.azure_client.\
|
|
|
delete_network(self.id)
|
|
|
return True
|
|
|
except CloudError as cloudError:
|
|
|
log.exception(cloudError.message)
|
|
|
return False
|
|
|
|
|
|
+ @property
|
|
|
def subnets(self):
|
|
|
"""
|
|
|
List all the subnets in this network
|
|
|
:return:
|
|
|
"""
|
|
|
- return self._provider.network.subnets.list(network=self.id)
|
|
|
+ return self._provider.networking.subnets.list(network=self.id)
|
|
|
|
|
|
def create_subnet(self, cidr_block, name=None, zone=None):
|
|
|
"""
|
|
|
@@ -964,11 +989,12 @@ class AzureNetwork(BaseNetwork):
|
|
|
:param zone:
|
|
|
:return:
|
|
|
"""
|
|
|
- return self._provider.network.subnets. \
|
|
|
+ return self._provider.networking.subnets. \
|
|
|
create(network=self.id, cidr_block=cidr_block, name=name)
|
|
|
|
|
|
|
|
|
class AzureFloatingIP(BaseFloatingIP):
|
|
|
+
|
|
|
def __init__(self, provider, floating_ip):
|
|
|
super(AzureFloatingIP, self).__init__(provider)
|
|
|
self._ip = floating_ip
|
|
|
@@ -1035,7 +1061,6 @@ class AzurePlacementZone(BasePlacementZone):
|
|
|
As Azure does not provide zones (limited support), we are mapping the
|
|
|
region information in the zones.
|
|
|
"""
|
|
|
-
|
|
|
def __init__(self, provider, zone, region):
|
|
|
super(AzurePlacementZone, self).__init__(provider)
|
|
|
self._azure_zone = zone
|
|
|
@@ -1071,12 +1096,18 @@ class AzurePlacementZone(BasePlacementZone):
|
|
|
|
|
|
|
|
|
class AzureSubnet(BaseSubnet):
|
|
|
+ _SUBNET_STATE_MAP = {
|
|
|
+ 'InProgress': SubnetState.PENDING,
|
|
|
+ 'Succeeded': SubnetState.AVAILABLE,
|
|
|
+ }
|
|
|
+
|
|
|
def __init__(self, provider, subnet):
|
|
|
super(AzureSubnet, self).__init__(provider)
|
|
|
self._subnet = subnet
|
|
|
- self._url_params = azure_helpers \
|
|
|
+ self._state = self._subnet.provisioning_state
|
|
|
+ self._url_params = azure_helpers\
|
|
|
.parse_url(SUBNET_RESOURCE_ID, subnet.id)
|
|
|
- self._network = self._provider.azure_client. \
|
|
|
+ self._network = self._provider.azure_client.\
|
|
|
get_network(self._url_params.get(NETWORK_NAME))
|
|
|
|
|
|
@property
|
|
|
@@ -1098,7 +1129,7 @@ class AzureSubnet(BaseSubnet):
|
|
|
|
|
|
@property
|
|
|
def zone(self):
|
|
|
- region = self._provider. \
|
|
|
+ region = self._provider.\
|
|
|
compute.regions.get(self._network.location)
|
|
|
return region.zones[0]
|
|
|
|
|
|
@@ -1124,8 +1155,29 @@ class AzureSubnet(BaseSubnet):
|
|
|
log.exception(cloudError.message)
|
|
|
return False
|
|
|
|
|
|
+ @property
|
|
|
+ def state(self):
|
|
|
+ return self._SUBNET_STATE_MAP.get(
|
|
|
+ self._state, NetworkState.UNKNOWN)
|
|
|
+
|
|
|
+ def refresh(self):
|
|
|
+ """
|
|
|
+ Refreshes the state of this network by re-querying the cloud provider
|
|
|
+ for its latest state.
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ self._network = self._provider.azure_client. \
|
|
|
+ get_network(self.id)
|
|
|
+ self._state = self._network.provisioning_state
|
|
|
+ except (CloudError, ValueError) as cloudError:
|
|
|
+ log.exception(cloudError.message)
|
|
|
+ # The network no longer exists and cannot be refreshed.
|
|
|
+ # set the state to unknown
|
|
|
+ self._state = 'unknown'
|
|
|
+
|
|
|
|
|
|
class AzureInstance(BaseInstance):
|
|
|
+
|
|
|
INSTANCE_STATE_MAP = {
|
|
|
'InProgress': InstanceState.PENDING,
|
|
|
'Creating': InstanceState.PENDING,
|
|
|
@@ -1164,7 +1216,7 @@ class AzureInstance(BaseInstance):
|
|
|
self._public_ip_ids = []
|
|
|
self._nic_ids = []
|
|
|
for nic in self._vm.network_profile.network_interfaces:
|
|
|
- nic_params = azure_helpers. \
|
|
|
+ nic_params = azure_helpers.\
|
|
|
parse_url(NETWORK_INTERFACE_RESOURCE_ID, nic.id)
|
|
|
nic_name = nic_params.get(NETWORK_INTERFACE_NAME)
|
|
|
self._nic_ids.append(nic_name)
|
|
|
@@ -1173,17 +1225,17 @@ class AzureInstance(BaseInstance):
|
|
|
sg_params = azure_helpers. \
|
|
|
parse_url(SECURITY_GROUP_RESOURCE_ID,
|
|
|
nic.network_security_group.id)
|
|
|
- self._security_group_ids. \
|
|
|
+ self._security_group_ids.\
|
|
|
append(sg_params.get(SECURITY_GROUP_NAME))
|
|
|
if nic.ip_configurations:
|
|
|
for ip_config in nic.ip_configurations:
|
|
|
self._private_ips.append(ip_config.private_ip_address)
|
|
|
if ip_config.public_ip_address:
|
|
|
- url_params = azure_helpers. \
|
|
|
+ url_params = azure_helpers.\
|
|
|
parse_url(PUBLIC_IP_RESOURCE_ID,
|
|
|
ip_config.public_ip_address.id)
|
|
|
public_ip_name = url_params.get(PUBLIC_IP_NAME)
|
|
|
- public_ip = self._provider.azure_client. \
|
|
|
+ public_ip = self._provider.azure_client.\
|
|
|
get_public_ip(public_ip_name)
|
|
|
self._public_ip_ids.append(public_ip_name)
|
|
|
self._public_ips.append(public_ip.ip_address)
|
|
|
@@ -1214,9 +1266,10 @@ class AzureInstance(BaseInstance):
|
|
|
"""
|
|
|
Set the instance name.
|
|
|
"""
|
|
|
+ self.assert_valid_resource_name(value)
|
|
|
self._vm.tags.update(Name=value)
|
|
|
self._provider.azure_client. \
|
|
|
- update_vm_tags(self.id, self._vm.tags)
|
|
|
+ update_vm_tags(self.id, self._vm)
|
|
|
|
|
|
@property
|
|
|
def public_ips(self):
|
|
|
@@ -1269,15 +1322,15 @@ class AzureInstance(BaseInstance):
|
|
|
self._provider.azure_client.delete_public_ip(public_ip_id)
|
|
|
for data_disk in self._vm.storage_profile.data_disks:
|
|
|
if data_disk.managed_disk:
|
|
|
- disk_params = azure_helpers. \
|
|
|
+ disk_params = azure_helpers.\
|
|
|
parse_url(VOLUME_RESOURCE_ID,
|
|
|
data_disk.managed_disk.id)
|
|
|
- disk = self._provider.azure_client. \
|
|
|
+ disk = self._provider.azure_client.\
|
|
|
get_disk(disk_params.get(VOLUME_NAME))
|
|
|
if disk and disk.tags \
|
|
|
and disk.tags.get('delete_on_terminate',
|
|
|
'False') == 'True':
|
|
|
- self._provider.azure_client. \
|
|
|
+ self._provider.azure_client.\
|
|
|
delete_disk(disk_params.get(VOLUME_NAME))
|
|
|
if self._vm.storage_profile.os_disk.managed_disk:
|
|
|
disk_params = azure_helpers. \
|
|
|
@@ -1342,6 +1395,8 @@ class AzureInstance(BaseInstance):
|
|
|
the private key file path
|
|
|
"""
|
|
|
|
|
|
+ self.assert_valid_resource_name(name)
|
|
|
+
|
|
|
if not self._state == 'VM generalized':
|
|
|
if not self._state == 'VM running':
|
|
|
self._provider.azure_client.start_vm(self.id)
|
|
|
@@ -1360,9 +1415,9 @@ class AzureInstance(BaseInstance):
|
|
|
},
|
|
|
'tags': {'Name': name}
|
|
|
}
|
|
|
- self._provider.azure_client. \
|
|
|
+ self._provider.azure_client.\
|
|
|
create_image(name, create_params)
|
|
|
- image = self._provider.azure_client. \
|
|
|
+ image = self._provider.azure_client.\
|
|
|
get_image(name)
|
|
|
|
|
|
return AzureMachineImage(self._provider, image)
|
|
|
@@ -1371,7 +1426,7 @@ class AzureInstance(BaseInstance):
|
|
|
cnopts = pysftp.CnOpts()
|
|
|
cnopts.hostkeys = None
|
|
|
if private_key_path:
|
|
|
- with pysftp. \
|
|
|
+ with pysftp.\
|
|
|
Connection(self.public_ips[0],
|
|
|
username=self._provider.vm_default_user_name,
|
|
|
cnopts=cnopts,
|
|
|
@@ -1437,13 +1492,13 @@ class AzureInstance(BaseInstance):
|
|
|
nic.network_security_group = NetworkSecurityGroup()
|
|
|
nic.network_security_group.id = sg.resource_id
|
|
|
else:
|
|
|
- sg_url_params = azure_helpers. \
|
|
|
+ sg_url_params = azure_helpers.\
|
|
|
parse_url(SECURITY_GROUP_RESOURCE_ID,
|
|
|
nic.network_security_group.id)
|
|
|
- existing_sg = self._provider.security. \
|
|
|
+ existing_sg = self._provider.security.\
|
|
|
security_groups.get(sg_url_params.get(SECURITY_GROUP_NAME))
|
|
|
|
|
|
- new_sg = self._provider.security.security_groups. \
|
|
|
+ new_sg = self._provider.security.security_groups.\
|
|
|
create('{0}-{1}'.format(sg.name, existing_sg.name),
|
|
|
'Merged security groups {0} and {1}'.
|
|
|
format(sg.name, existing_sg.name))
|
|
|
@@ -1471,7 +1526,7 @@ class AzureInstance(BaseInstance):
|
|
|
sg = (self._provicer.security.security_groups.get(sg)
|
|
|
if isinstance(sg, str) else sg)
|
|
|
if nic.network_security_group and \
|
|
|
- nic.network_security_group.id == sg.resource_id:
|
|
|
+ nic.network_security_group.id == sg.resource_id:
|
|
|
nic.network_security_group = None
|
|
|
self._provider.azure_client.create_nic(self._nic_ids[0], nic)
|
|
|
|
|
|
@@ -1517,22 +1572,24 @@ class AzureInstance(BaseInstance):
|
|
|
|
|
|
|
|
|
class AzureLaunchConfig(BaseLaunchConfig):
|
|
|
+
|
|
|
def __init__(self, provider):
|
|
|
super(AzureLaunchConfig, self).__init__(provider)
|
|
|
|
|
|
|
|
|
-class AzureInstanceType(BaseInstanceType):
|
|
|
- def __init__(self, provider, instance_type):
|
|
|
- super(AzureInstanceType, self).__init__(provider)
|
|
|
- self._inst_type = instance_type
|
|
|
+class AzureVMType(BaseVMType):
|
|
|
+
|
|
|
+ def __init__(self, provider, vm_type):
|
|
|
+ super(AzureVMType, self).__init__(provider)
|
|
|
+ self._vm_type = vm_type
|
|
|
|
|
|
@property
|
|
|
def id(self):
|
|
|
- return self._inst_type.name
|
|
|
+ return self._vm_type.name
|
|
|
|
|
|
@property
|
|
|
def name(self):
|
|
|
- return self._inst_type.name
|
|
|
+ return self._vm_type.name
|
|
|
|
|
|
@property
|
|
|
def family(self):
|
|
|
@@ -1544,19 +1601,19 @@ class AzureInstanceType(BaseInstanceType):
|
|
|
|
|
|
@property
|
|
|
def vcpus(self):
|
|
|
- return self._inst_type.number_of_cores
|
|
|
+ return self._vm_type.number_of_cores
|
|
|
|
|
|
@property
|
|
|
def ram(self):
|
|
|
- return self._inst_type.memory_in_mb
|
|
|
+ return self._vm_type.memory_in_mb
|
|
|
|
|
|
@property
|
|
|
def size_root_disk(self):
|
|
|
- return self._inst_type.os_disk_size_in_mb / 1024
|
|
|
+ return self._vm_type.os_disk_size_in_mb / 1024
|
|
|
|
|
|
@property
|
|
|
def size_ephemeral_disks(self):
|
|
|
- return self._inst_type.resource_disk_size_in_mb / 1024
|
|
|
+ return self._vm_type.resource_disk_size_in_mb / 1024
|
|
|
|
|
|
@property
|
|
|
def num_ephemeral_disks(self):
|
|
|
@@ -1570,12 +1627,13 @@ class AzureInstanceType(BaseInstanceType):
|
|
|
@property
|
|
|
def extra_data(self):
|
|
|
return {
|
|
|
- 'max_data_disk_count':
|
|
|
- self._inst_type.max_data_disk_count
|
|
|
- }
|
|
|
+ 'max_data_disk_count':
|
|
|
+ self._vm_type.max_data_disk_count
|
|
|
+ }
|
|
|
|
|
|
|
|
|
class AzureKeyPair(BaseKeyPair):
|
|
|
+
|
|
|
def __init__(self, provider, key_pair):
|
|
|
super(AzureKeyPair, self).__init__(provider, key_pair)
|
|
|
self._material = None
|
|
|
@@ -1605,7 +1663,7 @@ class AzureKeyPair(BaseKeyPair):
|
|
|
|
|
|
def delete(self):
|
|
|
try:
|
|
|
- self._provider.azure_client. \
|
|
|
+ self._provider.azure_client.\
|
|
|
delete_public_key(self._key_pair)
|
|
|
return True
|
|
|
except CloudError:
|
|
|
@@ -1613,24 +1671,19 @@ class AzureKeyPair(BaseKeyPair):
|
|
|
|
|
|
|
|
|
class AzureRouter(BaseRouter):
|
|
|
- def __init__(self, provider, router):
|
|
|
+ def __init__(self, provider, route_table):
|
|
|
super(AzureRouter, self).__init__(provider)
|
|
|
- self._router = router
|
|
|
- self._ROUTE_CIDR = '0.0.0.0/0'
|
|
|
- self._name = None
|
|
|
- self._network_id = None
|
|
|
- self._state = RouterState.DETACHED
|
|
|
-
|
|
|
- def _route_table(self, subnet_id):
|
|
|
- pass
|
|
|
+ self._route_table = route_table
|
|
|
+ if not self._route_table.tags:
|
|
|
+ self._route_table.tags = {}
|
|
|
|
|
|
@property
|
|
|
def id(self):
|
|
|
- return self._name
|
|
|
+ return self._route_table.name
|
|
|
|
|
|
@property
|
|
|
def resource_id(self):
|
|
|
- pass
|
|
|
+ return self._route_table.id
|
|
|
|
|
|
@property
|
|
|
def name(self):
|
|
|
@@ -1639,7 +1692,7 @@ class AzureRouter(BaseRouter):
|
|
|
|
|
|
.. note:: the router must have a (case sensitive) tag ``Name``
|
|
|
"""
|
|
|
- return self._name
|
|
|
+ return self._route_table.tags.get('Name', self._route_table.name)
|
|
|
|
|
|
@name.setter
|
|
|
# pylint:disable=arguments-differ
|
|
|
@@ -1647,47 +1700,98 @@ class AzureRouter(BaseRouter):
|
|
|
"""
|
|
|
Set the router name.
|
|
|
"""
|
|
|
- self._name = value
|
|
|
+ self.assert_valid_resource_name(value)
|
|
|
+ self._route_table.tags.update(Name=value)
|
|
|
+ self._provider.azure_client. \
|
|
|
+ update_route_table_tags(self._route_table.name,
|
|
|
+ self._route_table)
|
|
|
|
|
|
def refresh(self):
|
|
|
- pass
|
|
|
+ self._route_table = self._provider.azure_client. \
|
|
|
+ get_route_table(self._route_table.name)
|
|
|
|
|
|
@property
|
|
|
def state(self):
|
|
|
- return self._state
|
|
|
+ self.refresh() # Explicitly refresh the local object
|
|
|
+ if self._route_table.subnets:
|
|
|
+ return RouterState.ATTACHED
|
|
|
+ return RouterState.DETACHED
|
|
|
|
|
|
@property
|
|
|
def network_id(self):
|
|
|
- return self._network_id
|
|
|
+ return None
|
|
|
|
|
|
def delete(self):
|
|
|
- pass
|
|
|
+ self._provider.azure_client. \
|
|
|
+ delete_route_table(self.name)
|
|
|
|
|
|
- def attach_network(self, network_id):
|
|
|
- self._network_id = network_id
|
|
|
- self._state = RouterState.ATTACHED
|
|
|
+ def attach_subnet(self, subnet):
|
|
|
+ subnet_id_parts = subnet.id.split('|$|')
|
|
|
+ if (len(subnet_id_parts) != 2):
|
|
|
+ pass
|
|
|
+ self._provider.azure_client. \
|
|
|
+ attach_subnet_to_route_table(subnet_id_parts[0],
|
|
|
+ subnet_id_parts[1],
|
|
|
+ self.resource_id)
|
|
|
+ self.refresh()
|
|
|
+
|
|
|
+ def detach_subnet(self, subnet):
|
|
|
+ subnet_id_parts = subnet.id.split('|$|')
|
|
|
+ if (len(subnet_id_parts) != 2):
|
|
|
+ pass
|
|
|
+ self._provider.azure_client. \
|
|
|
+ detach_subnet_to_route_table(subnet_id_parts[0],
|
|
|
+ subnet_id_parts[1],
|
|
|
+ self.resource_id)
|
|
|
+ self.refresh()
|
|
|
|
|
|
- def detach_network(self):
|
|
|
+ def attach_gateway(self, gateway):
|
|
|
pass
|
|
|
|
|
|
- def add_route(self, subnet_id):
|
|
|
- """
|
|
|
- Add a default route to this router.
|
|
|
+ def detach_gateway(self, gateway):
|
|
|
+ pass
|
|
|
|
|
|
- For Azure, routes are added to a route table. A route table is assoc.
|
|
|
- with a network vs. a subnet so we retrieve the network via the subnet.
|
|
|
- Note that the subnet must belong to the same network as the router
|
|
|
- is attached to.
|
|
|
|
|
|
- Further, only a single route can be added, targeting the Internet
|
|
|
- (i.e., destination CIDR block ``0.0.0.0/0``).
|
|
|
+class AzureInternetGateway(BaseInternetGateway):
|
|
|
+ def __init__(self, provider, gateway):
|
|
|
+ super(AzureInternetGateway, self).__init__(provider)
|
|
|
+ self._gateway = gateway
|
|
|
+ self._name = None
|
|
|
+ self._network_id = None
|
|
|
+ self._state = ''
|
|
|
+
|
|
|
+ @property
|
|
|
+ def id(self):
|
|
|
+ return self._name
|
|
|
+
|
|
|
+ @property
|
|
|
+ def name(self):
|
|
|
"""
|
|
|
- pass
|
|
|
+ Get the gateway name.
|
|
|
|
|
|
- def remove_route(self, subnet_id):
|
|
|
+ .. note:: the gateway must have a (case sensitive) tag ``Name``
|
|
|
"""
|
|
|
- Remove the default Internet route from this router.
|
|
|
+ return self._name
|
|
|
|
|
|
- .. seealso:: ``add_route`` method
|
|
|
+ @name.setter
|
|
|
+ # pylint:disable=arguments-differ
|
|
|
+ def name(self, value):
|
|
|
+ """
|
|
|
+ Set the router name.
|
|
|
"""
|
|
|
+ self.assert_valid_resource_name(value)
|
|
|
+ self._name = value
|
|
|
+
|
|
|
+ def refresh(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+ @property
|
|
|
+ def state(self):
|
|
|
+ return self._state
|
|
|
+
|
|
|
+ @property
|
|
|
+ def network_id(self):
|
|
|
+ return None
|
|
|
+
|
|
|
+ def delete(self):
|
|
|
pass
|