diff --git a/kuryr_kubernetes/config.py b/kuryr_kubernetes/config.py index 679e96c66..e2c42d293 100644 --- a/kuryr_kubernetes/config.py +++ b/kuryr_kubernetes/config.py @@ -108,6 +108,10 @@ k8s_opts = [ help=_("The driver to determine OpenStack " "project for services"), default='default'), + cfg.StrOpt('namespace_project_driver', + help=_("The driver to determine OpenStack " + "project for namespaces"), + default='default'), cfg.StrOpt('pod_subnets_driver', help=_("The driver to determine Neutron " "subnets for pod ports"), diff --git a/kuryr_kubernetes/controller/drivers/base.py b/kuryr_kubernetes/controller/drivers/base.py index 42d638440..c531d8057 100644 --- a/kuryr_kubernetes/controller/drivers/base.py +++ b/kuryr_kubernetes/controller/drivers/base.py @@ -113,6 +113,23 @@ class ServiceProjectDriver(DriverBase): raise NotImplementedError() +@six.add_metaclass(abc.ABCMeta) +class NamespaceProjectDriver(DriverBase): + """Provides an OpenStack project ID for Kubernetes Namespace.""" + + ALIAS = 'namespace_project' + + @abc.abstractmethod + def get_project(self, namespace): + """Get an OpenStack project ID for Kubernetes Namespace. + + :param service: dict containing Kubernetes Namespace object + :return: project ID + """ + + raise NotImplementedError() + + @six.add_metaclass(abc.ABCMeta) class PodSubnetsDriver(DriverBase): """Provides subnets for Kubernetes Pods.""" diff --git a/kuryr_kubernetes/controller/drivers/default_project.py b/kuryr_kubernetes/controller/drivers/default_project.py index ea177c337..a7744fc8c 100644 --- a/kuryr_kubernetes/controller/drivers/default_project.py +++ b/kuryr_kubernetes/controller/drivers/default_project.py @@ -51,3 +51,20 @@ class DefaultServiceProjectDriver(base.ServiceProjectDriver): cfg.OptGroup('neutron_defaults')) return project_id + + +class DefaultNamespaceProjectDriver(base.NamespaceProjectDriver): + """Provides project ID for Namespace based on a configuration option.""" + + def get_project(self, namespace): + project_id = config.CONF.neutron_defaults.project + + if not project_id: + # NOTE(ivc): this option is only required for + # DefaultNamespaceProjectDriver and its subclasses, but it may be + # optional for other drivers (e.g. when each namespace has own + # project) + raise cfg.RequiredOptError('project', + cfg.OptGroup('neutron_defaults')) + + return project_id diff --git a/kuryr_kubernetes/controller/handlers/namespace.py b/kuryr_kubernetes/controller/handlers/namespace.py index b6193f8ad..be4870e36 100644 --- a/kuryr_kubernetes/controller/handlers/namespace.py +++ b/kuryr_kubernetes/controller/handlers/namespace.py @@ -29,9 +29,8 @@ class NamespaceHandler(k8s_base.ResourceEventHandler): def __init__(self): super(NamespaceHandler, self).__init__() - self._drv_project = drivers.PodProjectDriver.get_instance() + self._drv_project = drivers.NamespaceProjectDriver.get_instance() self._drv_subnets = drivers.PodSubnetsDriver.get_instance() - self._drv_sg = drivers.PodSecurityGroupsDriver.get_instance() self._drv_vif_pool = drivers.VIFPoolDriver.get_instance( driver_alias='multi_pool') self._drv_vif_pool.set_vif_driver() diff --git a/kuryr_kubernetes/tests/unit/controller/handlers/test_namespace.py b/kuryr_kubernetes/tests/unit/controller/handlers/test_namespace.py index faf2c5329..cb61cea73 100644 --- a/kuryr_kubernetes/tests/unit/controller/handlers/test_namespace.py +++ b/kuryr_kubernetes/tests/unit/controller/handlers/test_namespace.py @@ -33,7 +33,6 @@ class TestNamespaceHandler(test_base.TestCase): self._project_id = mock.sentinel.project_id self._subnets = mock.sentinel.subnets - self._security_groups = mock.sentinel.security_groups self._namespace_version = mock.sentinel.namespace_version self._namespace_link = mock.sentinel.namespace_link @@ -48,15 +47,14 @@ class TestNamespaceHandler(test_base.TestCase): self._handler = mock.MagicMock(spec=namespace.NamespaceHandler) - self._handler._drv_project = mock.Mock(spec=drivers.PodProjectDriver) + self._handler._drv_project = mock.Mock( + spec=drivers.NamespaceProjectDriver) self._handler._drv_subnets = mock.Mock(spec=drivers.PodSubnetsDriver) - self._handler._drv_sg = mock.Mock(spec=drivers.PodSecurityGroupsDriver) self._handler._drv_vif_pool = mock.MagicMock( spec=vif_pool.MultiVIFPool) self._get_project = self._handler._drv_project.get_project self._get_subnets = self._handler._drv_subnets.get_subnets - self._get_security_groups = self._handler._drv_sg.get_security_groups self._create_namespace_network = ( self._handler._drv_subnets.create_namespace_network) @@ -73,7 +71,6 @@ class TestNamespaceHandler(test_base.TestCase): self._get_project.return_value = self._project_id self._get_subnets.return_value = self._subnets - self._get_security_groups.return_value = self._security_groups def _get_crd(self): crd = { @@ -87,26 +84,22 @@ class TestNamespaceHandler(test_base.TestCase): return crd @mock.patch.object(drivers.VIFPoolDriver, 'get_instance') - @mock.patch.object(drivers.PodSecurityGroupsDriver, 'get_instance') @mock.patch.object(drivers.PodSubnetsDriver, 'get_instance') - @mock.patch.object(drivers.PodProjectDriver, 'get_instance') + @mock.patch.object(drivers.NamespaceProjectDriver, 'get_instance') def test_init(self, m_get_project_driver, m_get_subnets_driver, - m_get_sg_driver, m_get_vif_pool_driver): + m_get_vif_pool_driver): project_driver = mock.sentinel.project_driver subnets_driver = mock.sentinel.subnets_driver - sg_driver = mock.sentinel.sg_driver vif_pool_driver = mock.Mock(spec=vif_pool.MultiVIFPool) m_get_project_driver.return_value = project_driver m_get_subnets_driver.return_value = subnets_driver - m_get_sg_driver.return_value = sg_driver m_get_vif_pool_driver.return_value = vif_pool_driver handler = namespace.NamespaceHandler() self.assertEqual(project_driver, handler._drv_project) self.assertEqual(subnets_driver, handler._drv_subnets) - self.assertEqual(sg_driver, handler._drv_sg) self.assertEqual(vif_pool_driver, handler._drv_vif_pool) def test_on_present(self): diff --git a/setup.cfg b/setup.cfg index c6091e6bb..557538b22 100644 --- a/setup.cfg +++ b/setup.cfg @@ -46,6 +46,9 @@ kuryr_kubernetes.controller.drivers.pod_project = kuryr_kubernetes.controller.drivers.service_project = default = kuryr_kubernetes.controller.drivers.default_project:DefaultServiceProjectDriver +kuryr_kubernetes.controller.drivers.namespace_project = + default = kuryr_kubernetes.controller.drivers.default_project:DefaultNamespaceProjectDriver + kuryr_kubernetes.controller.drivers.pod_subnets = default = kuryr_kubernetes.controller.drivers.default_subnet:DefaultPodSubnetDriver namespace = kuryr_kubernetes.controller.drivers.namespace_subnet:NamespacePodSubnetDriver