Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Commit

Permalink
Merge pull request #187 from indigo-dc/devel
Browse files Browse the repository at this point in the history
Devel
  • Loading branch information
micafer authored Jun 7, 2017
2 parents 2176219 + 3cb56a6 commit f3a56eb
Show file tree
Hide file tree
Showing 14 changed files with 536 additions and 71 deletions.
2 changes: 1 addition & 1 deletion IM/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
'InfrastructureInfo', 'InfrastructureManager', 'recipe', 'request', 'REST', 'retry',
'ServiceRequests', 'SSH', 'SSHRetry', 'timedcall', 'UnixHTTPConnection', 'uriparse',
'VirtualMachine', 'VMRC', 'xmlobject']
__version__ = '1.5.4'
__version__ = '1.5.5'
__author__ = 'Miguel Caballer'
111 changes: 91 additions & 20 deletions IM/connectors/Azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
from IM.VirtualMachine import VirtualMachine
from .CloudConnector import CloudConnector
from radl.radl import Feature
from IM.config import Config

try:
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.storage import StorageManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.dns import DnsManagementClient
from azure.common.credentials import UserPassCredentials
except Exception as ex:
print("WARN: Python Azure SDK not correctly installed. AzureCloudConnector will not work!.")
Expand Down Expand Up @@ -142,28 +144,25 @@ def get_instance_type(self, system, credentials, subscription_id):
disk_free_op = system.getFeature('memory.size').getLogOperator()

compute_client = ComputeManagementClient(credentials, subscription_id)
instace_types = compute_client.virtual_machine_sizes.list(location)
instace_types = list(compute_client.virtual_machine_sizes.list(location))
instace_types.sort(key=lambda x: (x.number_of_cores, x.memory_in_mb, x.resource_disk_size_in_mb))

res = None
default = None
for instace_type in list(instace_types):
for instace_type in instace_types:
if instace_type.name == self.INSTANCE_TYPE:
default = instace_type
# get the instance type with the lowest Memory
if res is None or (instace_type.memory_in_mb <= res.memory_in_mb):
if res is None:
str_compare = "instace_type.number_of_cores " + cpu_op + " cpu "
str_compare += " and instace_type.memory_in_mb " + memory_op + " memory "
str_compare += " and instace_type.resource_disk_size_in_mb " + \
disk_free_op + " disk_free"
str_compare += " and instace_type.resource_disk_size_in_mb " + disk_free_op + " disk_free"

if eval(str_compare):
if not instance_type_name or instace_type.name == instance_type_name:
res = instace_type
return instace_type

if res is None:
return default
else:
return res
return default

def update_system_info_from_instance(self, system, instance_type):
"""
Expand Down Expand Up @@ -283,7 +282,21 @@ def create_nics(self, inf, radl, credentials, subscription_id, group_name, subne
if radl.systems[0].getValue('availability_zone'):
location = radl.systems[0].getValue('availability_zone')

hasPublicIP = radl.hasPublicNet(system.name)
i = 0
hasPublicIP = False
hasPrivateIP = False
while system.getValue("net_interface." + str(i) + ".connection"):
network_name = system.getValue("net_interface." + str(i) + ".connection")
# TODO: check how to do that
# fixed_ip = system.getValue("net_interface." + str(i) + ".ip")
network = radl.get_network_by_id(network_name)

if network.isPublic():
hasPublicIP = True
else:
hasPrivateIP = True

i += 1

i = 0
res = []
Expand All @@ -294,7 +307,7 @@ def create_nics(self, inf, radl, credentials, subscription_id, group_name, subne
# fixed_ip = system.getValue("net_interface." + str(i) + ".ip")
network = radl.get_network_by_id(network_name)

if network.isPublic():
if network.isPublic() and hasPrivateIP:
# Public nets are not added as nics
i += 1
continue
Expand Down Expand Up @@ -442,7 +455,7 @@ def create_nets(self, inf, radl, credentials, subscription_id, group_name):

if not vnet:
# Create VNet in the RG of the Inf
async_vnet_creation = network_client.virtual_networks.create_or_update(
network_client.virtual_networks.create_or_update(
group_name,
"privates",
{
Expand All @@ -452,7 +465,6 @@ def create_nets(self, inf, radl, credentials, subscription_id, group_name):
}
}
)
async_vnet_creation.wait()

subnets = {}
for i, net in enumerate(radl.networks):
Expand Down Expand Up @@ -497,6 +509,7 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data):

res = []
i = 0
all_ok = True
while i < num_vm:
group_name = None
try:
Expand All @@ -523,9 +536,11 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data):
credentials, subscription_id, location)

if not storage_account:
all_ok = False
res.append((False, error_msg))
# delete VM group
resource_client.resource_groups.delete(group_name)
break
continue

nics = self.create_nics(inf, radl, credentials, subscription_id, group_name, subnets)

Expand All @@ -534,7 +549,7 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data):

compute_client = ComputeManagementClient(credentials, subscription_id)
async_vm_creation = compute_client.virtual_machines.create_or_update(group_name, vm_name, vm_parameters)
azure_vm = async_vm_creation.result()
# azure_vm = async_vm_creation.result()

vm = VirtualMachine(inf, group_name + '/' + vm_name, self.cloud, radl, requested_radl, self)
vm.info.systems[0].setValue('instance_id', group_name + '/' + vm_name)
Expand All @@ -543,6 +558,7 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data):

res.append((True, vm))
except Exception as ex:
all_ok = False
self.log_exception("Error creating the VM")
res.append((False, "Error creating the VM: " + str(ex)))

Expand All @@ -553,6 +569,10 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data):

i += 1

if not all_ok:
# Remove the general group
resource_client.resource_groups.delete("rg-%s" % inf.id)

return res

def attach_data_disks(self, vm, storage_account_name, credentials, subscription_id, location):
Expand All @@ -571,7 +591,7 @@ def attach_data_disks(self, vm, storage_account_name, credentials, subscription_

try:
# Attach data disk
async_vm_update = compute_client.virtual_machines.create_or_update(
compute_client.virtual_machines.create_or_update(
group_name,
vm_name,
{
Expand All @@ -590,7 +610,6 @@ def attach_data_disks(self, vm, storage_account_name, credentials, subscription_
}
}
)
async_vm_update.wait()
except Exception as ex:
self.log_exception("Error attaching disk %d to VM %s" % (cont, vm_name))
return False, "Error attaching disk %d to VM %s: %s" % (cont, vm_name, str(ex))
Expand Down Expand Up @@ -626,8 +645,60 @@ def updateVMInfo(self, vm, auth_data):

# Update IP info
self.setIPs(vm, virtual_machine.network_profile, credentials, subscription_id)
self.add_dns_entries(vm, credentials, subscription_id)
return (True, vm)

def add_dns_entries(self, vm, credentials, subscription_id):
"""
Add the required entries in the Azure DNS service
Arguments:
- vm(:py:class:`IM.VirtualMachine`): VM information.
- credentials, subscription_id: Authentication data to access cloud provider.
"""
try:
group_name = vm.id.split('/')[0]
dns_client = DnsManagementClient(credentials, subscription_id)
system = vm.info.systems[0]
for net_name in system.getNetworkIDs():
num_conn = system.getNumNetworkWithConnection(net_name)
ip = system.getIfaceIP(num_conn)
(hostname, domain) = vm.getRequestedNameIface(num_conn,
default_hostname=Config.DEFAULT_VM_NAME,
default_domain=Config.DEFAULT_DOMAIN)
if domain != "localdomain" and ip:
zone = None
try:
zone = dns_client.zones.get(group_name, domain)
except Exception:
pass
if not zone:
self.log_debug("Creating DNS zone %s" % domain)
zone = dns_client.zones.create_or_update(group_name, domain,
{'location': 'global'})
else:
self.log_debug("DNS zone %s exists. Do not create." % domain)

if zone:
record = None
try:
record = dns_client.record_sets.get(group_name, domain, hostname, 'A')
except Exception:
pass
if not record:
self.log_debug("Creating DNS record %s." % hostname)
record_data = {"ttl": 300, "arecords": [{"ipv4_address": ip}]}
record_set = dns_client.record_sets.create_or_update(group_name, domain,
hostname, 'A',
record_data)
else:
self.log_debug("DNS record %s exists. Do not create." % hostname)

return True
except Exception:
self.log_exception("Error creating DNS entries")
return False

def setIPs(self, vm, network_profile, credentials, subscription_id):
"""
Set the information about the IPs of the VM
Expand Down Expand Up @@ -664,7 +735,7 @@ def finalize(self, vm, last, auth_data):
# Delete Resource group and everything in it
resource_client = ResourceManagementClient(credentials, subscription_id)
self.log_debug("Removing RG: %s" % group_name)
resource_client.resource_groups.delete(group_name).wait()
resource_client.resource_groups.delete(group_name)

# if it is the last VM delete the RG of the Inf
if last:
Expand Down Expand Up @@ -724,7 +795,7 @@ def alterVM(self, vm, radl, auth_data):

# Start the VM
async_vm_start = compute_client.virtual_machines.start(group_name, vm_name)
async_vm_start.wait()
# async_vm_start.wait()

return self.updateVMInfo(vm, auth_data)
except Exception as ex:
Expand Down
Loading

0 comments on commit f3a56eb

Please sign in to comment.