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
3 changes: 2 additions & 1 deletion IM/VirtualMachine.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
9 changes: 6 additions & 3 deletions IM/connectors/EGI.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
21 changes: 21 additions & 0 deletions doc/source/radl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.<netId>.dns.<index>.name = <string>``
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.<netId>.dns.<index>.tls = <boolean>``
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.<netId>.dns.<index>.tls.certificate = <string>``
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.<netId>.dns.<index>.tls.private_key = <string>``
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
Expand Down
8 changes: 5 additions & 3 deletions test/unit/connectors/EGI.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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')
Expand Down
Loading