From 98323ff4a670dba6095d1e4fc2106cea74f547a1 Mon Sep 17 00:00:00 2001 From: Miguel Caballer Date: Fri, 12 Jun 2026 08:55:50 +0200 Subject: [PATCH 1/3] Update docs --- doc/source/radl.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/source/radl.rst b/doc/source/radl.rst index 611f240e1..a8d88a276 100644 --- a/doc/source/radl.rst +++ b/doc/source/radl.rst @@ -295,6 +295,27 @@ machine. The supported features are: string contains ``#N#`` they are replaced by a number that is distinct for every virtual machine deployed with this ``system`` description. +``net_interface..dns..name = `` + Specify a set of DNS names for the IP assigned to this interface. If the + string contains ``#N#`` they are replaced by a number that is distinct for + every virtual machine deployed with this ``system`` description. + (new in version 2.0.0). + +``net_interface..dns..tls = `` + If set to ``true`` a TLS certificate for the DNS name specified in the previous + field will generated. This field only applies if the Cloud provider supports it. + (new in version 2.0.0). + +``net_interface..dns..tls.certificate = `` + If the previous field is set to ``true`` this field will be used to return the + generated TLS certificate for the DNS name specified. + (new in version 2.0.0). + +``net_interface..dns..tls.private_key = `` + If the previous field is set to ``true`` this field will be used to return the + generated TLS private key for the DNS name specified. + (new in version 2.0.0). + ``availability_zone`` Set the availability zone or region where this VM will be launched. It only applies to Google Cloud, Microsoft Azure, and Amazon AWS From d7ad222b0094585d2f5ebc656b6a4f63025eba8c Mon Sep 17 00:00:00 2001 From: Miguel Caballer Date: Fri, 12 Jun 2026 10:43:57 +0200 Subject: [PATCH 2/3] Fix wildcard cert generation --- IM/connectors/EGI.py | 9 ++++++--- test/unit/connectors/EGI.py | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/IM/connectors/EGI.py b/IM/connectors/EGI.py index a58cc9802..6ccf5cf24 100644 --- a/IM/connectors/EGI.py +++ b/IM/connectors/EGI.py @@ -105,17 +105,20 @@ def _generate_csr(fqdn, wildcard=False): The CSR includes subjectAltName for DNS validation and supports wildcard names. """ - cert_name = f"*.{fqdn}" if wildcard else fqdn + dns_names = [fqdn] + if wildcard: + dns_names.append(f"*.{fqdn}") + private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) csr_builder = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([ x509.NameAttribute(NameOID.COUNTRY_NAME, "SK"), x509.NameAttribute(NameOID.LOCALITY_NAME, "Bratislava"), x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Ustav informatiky SAV"), - x509.NameAttribute(NameOID.COMMON_NAME, cert_name), + x509.NameAttribute(NameOID.COMMON_NAME, fqdn), ])) csr_builder = csr_builder.add_extension( - x509.SubjectAlternativeName([x509.DNSName(cert_name)]), + x509.SubjectAlternativeName([x509.DNSName(name) for name in dns_names]), critical=False ) csr = csr_builder.sign(private_key, hashes.SHA256(), default_backend()) diff --git a/test/unit/connectors/EGI.py b/test/unit/connectors/EGI.py index 3fcafd912..cf8643dd2 100755 --- a/test/unit/connectors/EGI.py +++ b/test/unit/connectors/EGI.py @@ -172,9 +172,9 @@ def test_generate_csr_returns_private_key(self): def test_generate_wildcard_csr(self): csr_pem, _ = EGICloudConnector._generate_csr("hostname.domain", wildcard=True) csr = x509.load_pem_x509_csr(csr_pem.encode('utf-8')) - self.assertEqual(csr.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value, "*.hostname.domain") + self.assertEqual(csr.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value, "hostname.domain") san = csr.extensions.get_extension_for_oid(ExtensionOID.SUBJECT_ALTERNATIVE_NAME).value - self.assertIn("*.hostname.domain", san.get_values_for_type(x509.DNSName)) + self.assertEqual(san.get_values_for_type(x509.DNSName), ["hostname.domain", "*.hostname.domain"]) @patch('requests.get') @patch('requests.post') @@ -194,7 +194,9 @@ def test_create_tls_certificate_wildcard(self, mock_get_host, mock_post, mock_ge post_call = mock_post.call_args csr_pem = post_call.kwargs['json']['csr'] csr = x509.load_pem_x509_csr(csr_pem.encode('utf-8')) - self.assertEqual(csr.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value, "*.hostname.domain") + self.assertEqual(csr.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value, "hostname.domain") + san = csr.extensions.get_extension_for_oid(ExtensionOID.SUBJECT_ALTERNATIVE_NAME).value + self.assertEqual(san.get_values_for_type(x509.DNSName), ["hostname.domain", "*.hostname.domain"]) @patch('IM.connectors.EGI.EGICloudConnector.create_tls_certificate') @patch('IM.connectors.EGI.EGICloudConnector.add_dns_entry') From eb20307b3b147dcff639158ab115f1164be5e6e1 Mon Sep 17 00:00:00 2001 From: Miguel Caballer Date: Fri, 12 Jun 2026 12:24:36 +0200 Subject: [PATCH 3/3] Fix error getting tls cert --- IM/VirtualMachine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IM/VirtualMachine.py b/IM/VirtualMachine.py index c3a08498f..848c342b5 100644 --- a/IM/VirtualMachine.py +++ b/IM/VirtualMachine.py @@ -1200,6 +1200,7 @@ def set_tls_certificate(self, hostname, domain, private_key_pem, cert_pem): """ Set the TLS certificate in the VM info """ + expected_dns_name = "%s.%s" % (hostname, domain if not domain.endswith(".") else domain[:-1]) system = self.info.systems[0] for net_name in system.getNetworkIDs(): num_conn = system.getNumNetworkWithConnection(net_name) @@ -1208,7 +1209,7 @@ def set_tls_certificate(self, hostname, domain, private_key_pem, cert_pem): dns_name = system.getValue('net_interface.%d.dns.%d.name' % (num_conn, num_dns)) if not dns_name: break - if dns_name == "%s.%s" % (hostname, domain if not domain.endswith(".") else domain[:-1]): + if dns_name in [expected_dns_name, "*." + expected_dns_name]: system.setValue('net_interface.%d.dns.%d.tls.private_key' % (num_conn, num_dns), private_key_pem) system.setValue('net_interface.%d.dns.%d.tls.certificate' % (num_conn, num_dns), cert_pem) num_dns += 1