diff --git a/charms/neutron-k8s/config.yaml b/charms/neutron-k8s/config.yaml index e50c69c7..27b5f486 100644 --- a/charms/neutron-k8s/config.yaml +++ b/charms/neutron-k8s/config.yaml @@ -3,6 +3,15 @@ options: default: False description: Enable debug logging. type: boolean + dns-domain: + default: cloud.sunbeam.local. + description: | + Specifies the dns domain name that should be used for building instance + hostnames. The value of 'openstacklocal' will cause + the dhcp agents to broadcast the default domain of openstacklocal and + will not enable internal cloud dns resolution. This value should end + with a '.', e.g. 'cloud.example.org.'. + type: string os-admin-hostname: default: description: | diff --git a/charms/neutron-k8s/src/charm.py b/charms/neutron-k8s/src/charm.py index 5a8d9685..30e8292a 100755 --- a/charms/neutron-k8s/src/charm.py +++ b/charms/neutron-k8s/src/charm.py @@ -20,7 +20,9 @@ This charm provide Neutron services as part of an OpenStack deployment """ import logging +import re +import ops import ops_sunbeam.charm as sunbeam_charm import ops_sunbeam.config_contexts as sunbeam_ctxts import ops_sunbeam.container_handlers as sunbeam_chandlers @@ -121,6 +123,63 @@ class NeutronOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm): ] ] + def check_configuration(self, event: ops.EventBase): + """Check a configuration key is correct.""" + try: + self._validate_domain() + except ValueError as e: + raise sunbeam_guard.BlockedExceptionError(str(e)) from e + + def _validate_domain(self): + """Check given domain is valid.""" + domain = self.config.get("dns-domain") + if not domain: + raise ValueError("dns-domain cannot be empty") + + if len(domain) > 253: + raise ValueError( + "A full name cannot be longer than 253 characters (trailing dot included)" + ) + + if not domain.endswith("."): + raise ValueError("A domain name must have a trailing dot (.)") + + labels = domain.split(".") + + if len(labels) == 1: + raise ValueError( + "A domain name must have at least one label and a trailing dot," + " or two labels separated by a dot" + ) + + if domain.endswith("."): + # strip trailing dot + del labels[-1] + + label_regex = re.compile(r"^[a-z0-9-]*$", re.IGNORECASE) + + for label in labels: + if not 1 < len(label) < 63: + raise ValueError( + "A label in a domain cannot be empty or longer than 63 characters" + ) + + if label.startswith("-") or label.endswith("-"): + raise ValueError( + "A label in a domain cannot start or end with a hyphen (-)" + ) + + if label_regex.match(label) is None: + raise ValueError( + "A label in a domain can only contain alphanumeric characters" + " and hyphens (-)" + ) + + def configure_unit(self, event: ops.EventBase) -> None: + """Run configuration on this unit.""" + self.check_configuration(event) + return super().configure_unit(event) + def get_pebble_handlers(self) -> list[sunbeam_chandlers.PebbleHandler]: """Pebble handlers for the service.""" return [ @@ -178,7 +237,7 @@ class OVNContext(sunbeam_ctxts.ConfigContext): def context(self) -> dict: """Configuration context.""" return { - "extension_drivers": "port_security,qos", + "extension_drivers": "port_security,qos,dns_domain_ports", "type_drivers": "geneve,gre,vlan,flat,local", "tenant_network_types": "geneve,gre,vlan,flat,local", "mechanism_drivers": "ovn", diff --git a/charms/neutron-k8s/src/templates/neutron.conf.j2 b/charms/neutron-k8s/src/templates/neutron.conf.j2 index a0c3ff7d..2372bcf9 100644 --- a/charms/neutron-k8s/src/templates/neutron.conf.j2 +++ b/charms/neutron-k8s/src/templates/neutron.conf.j2 @@ -22,7 +22,7 @@ dhcp_agents_per_network = 1 notify_nova_on_port_status_changes = True notify_nova_on_port_data_changes = True - +dns_domain = {{ options.dns_domain }} global_physnet_mtu = 1500 diff --git a/charms/openstack-hypervisor/config.yaml b/charms/openstack-hypervisor/config.yaml index f7cf875a..f376b3e7 100644 --- a/charms/openstack-hypervisor/config.yaml +++ b/charms/openstack-hypervisor/config.yaml @@ -10,9 +10,6 @@ options: description: | Whether to resume the guest VMs when the host boots. type: boolean - dns-domain: - default: "openstack.local" - type: string dns-servers: default: "8.8.8.8" type: string diff --git a/charms/openstack-hypervisor/src/charm.py b/charms/openstack-hypervisor/src/charm.py index 7fc805ff..f5323901 100755 --- a/charms/openstack-hypervisor/src/charm.py +++ b/charms/openstack-hypervisor/src/charm.py @@ -429,7 +429,6 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm): "identity.user-domain-name": contexts.identity_credentials.user_domain_name, "identity.username": contexts.identity_credentials.username, "logging.debug": config("debug"), - "network.dns-domain": config("dns-domain"), "network.dns-servers": config("dns-servers"), "network.enable-gateway": config("enable-gateway"), "network.external-bridge": config("external-bridge"), diff --git a/charms/openstack-hypervisor/tests/unit/test_charm.py b/charms/openstack-hypervisor/tests/unit/test_charm.py index 6cad0e01..c2f97a6a 100644 --- a/charms/openstack-hypervisor/tests/unit/test_charm.py +++ b/charms/openstack-hypervisor/tests/unit/test_charm.py @@ -162,7 +162,6 @@ class TestCharm(test_utils.CharmTestCase): "identity.username": "username", "logging.debug": False, "monitoring.enable": False, - "network.dns-domain": "openstack.local", "network.dns-servers": "8.8.8.8", "network.enable-gateway": False, "network.external-bridge": "br-ex", @@ -266,7 +265,6 @@ class TestCharm(test_utils.CharmTestCase): "identity.username": "username", "logging.debug": False, "monitoring.enable": True, - "network.dns-domain": "openstack.local", "network.dns-servers": "8.8.8.8", "network.enable-gateway": False, "network.external-bridge": "br-ex",