diff --git a/IM/connectors/OpenStack.py b/IM/connectors/OpenStack.py index f29b0e0b3..98ae94be9 100644 --- a/IM/connectors/OpenStack.py +++ b/IM/connectors/OpenStack.py @@ -19,6 +19,8 @@ from netaddr import IPNetwork, IPAddress import os.path import tempfile +import requests +import base64 try: from libcloud.common.exceptions import BaseHTTPError @@ -495,6 +497,7 @@ def updateVMInfo(self, vm, auth_data): self.addAdditionalIP(vm, node.driver) self.addRouterInstance(vm, node.driver) self.setIPsFromInstance(vm, node) + self.add_dns_entries(vm, auth_data) self.setVolumesInfo(vm, node) else: self.log_warn("Error updating the instance %s. VM not found." % vm.id) @@ -502,6 +505,35 @@ def updateVMInfo(self, vm, auth_data): return (True, vm) + def add_dns_entries(self, vm, auth_data): + """ + Add the required entries in the AWS Route53 service + + Arguments: + - vm(:py:class:`IM.VirtualMachine`): VM information. + - auth_data(:py:class:`dict` of str objects): Authentication data to access cloud provider. + """ + try: + dns_entries = self.get_dns_entries(vm) + if dns_entries: + for hostname, domain, ip in dns_entries: + # Special case for EGI DyDNS + # format of the hostname: dydns:secret@hostname + if hostname.startswith("dydns:") and "@" in hostname: + parts = hostname[6:].split("@") + auth = "%s.%s:%s" % (parts[1], domain[:-1], parts[0]) + headers = {"Authorization": "Basic %s" % base64.b64encode(auth.encode()).decode()} + url = "https://nsupdate.fedcloud.eu/nic/update?hostname=%s.%s&myip=%s" % (parts[1], + domain[:-1], + ip) + resp = requests.get(url, headers=headers) + resp.raise_for_status() + return True + except Exception as ex: + self.error_messages += "Error creating DNS entries %s.\n" % str(ex) + self.log_exception("Error creating DNS entries") + return False + @staticmethod def map_radl_ost_networks(vm, ost_nets): """ diff --git a/test/unit/connectors/OpenStack.py b/test/unit/connectors/OpenStack.py index a694fcf84..ec6c97164 100644 --- a/test/unit/connectors/OpenStack.py +++ b/test/unit/connectors/OpenStack.py @@ -322,7 +322,8 @@ def test_20_launch(self, get_image_data, save_data, get_driver): self.assertEqual(driver.ex_create_subnet.call_args_list[5][0][2], "10.0.2.0/24") @patch('libcloud.compute.drivers.openstack.OpenStackNodeDriver') - def test_30_updateVMInfo(self, get_driver): + @patch('requests.get') + def test_30_updateVMInfo(self, request, get_driver): radl_data = """ network net (outbound = 'yes' and provider_id = 'pool1') network net1 (provider_id = 'os-lan' and router='10.0.0.0/16,vrouter1') @@ -331,7 +332,7 @@ def test_30_updateVMInfo(self, get_driver): cpu.count=1 and memory.size=512m and net_interface.0.connection = 'net' and - net_interface.0.dns_name = 'test' and + net_interface.0.dns_name = 'dydns:secret@test.domain.com' and net_interface.1.connection = 'net1' and disk.0.os.name = 'linux' and disk.0.image.url = 'ost://server.com/ami-id' and @@ -468,6 +469,11 @@ def test_30_updateVMInfo(self, get_driver): self.assertTrue(success, msg="ERROR: updating VM info.") self.assertEquals(vm.info.systems[0].getValue("net_interface.0.ip"), "8.8.8.8") self.assertEquals(vm.info.systems[0].getValue("net_interface.0.ipv6"), "2001:630:12:581:f816:3eff:fe92:2146") + + url = 'https://nsupdate.fedcloud.eu/nic/update?hostname=test.domain.com&myip=8.8.8.8' + self.assertEqual(request.call_args_list[0][0][0], url) + auth = "Basic dGVzdC5kb21haW4uY29tOnNlY3JldA==" + self.assertEqual(request.call_args_list[0][1]['headers']['Authorization'], auth) self.assertNotIn("ERROR", self.log.getvalue(), msg="ERROR found in log: %s" % self.log.getvalue()) @patch('libcloud.compute.drivers.openstack.OpenStackNodeDriver')