Merge "Refactor the class hierarchy of controller drivers"

This commit is contained in:
Jenkins 2017-06-07 10:17:05 +00:00 committed by Gerrit Code Review
commit 97ded78681
8 changed files with 187 additions and 140 deletions

View File

@ -0,0 +1,74 @@
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import abc
import six
from kuryr.lib._i18n import _
from kuryr.lib import exceptions as kl_exc
from neutronclient.common import exceptions as n_exc
from oslo_config import cfg as oslo_cfg
from oslo_log import log as logging
from kuryr_kubernetes.controller.drivers import neutron_vif
LOG = logging.getLogger(__name__)
# Moved out from neutron_defaults group
nested_vif_driver_opts = [
oslo_cfg.StrOpt('worker_nodes_subnet',
help=_("Neutron subnet ID for k8s worker node vms.")),
]
oslo_cfg.CONF.register_opts(nested_vif_driver_opts, "pod_vif_nested")
@six.add_metaclass(abc.ABCMeta)
class NestedPodVIFDriver(neutron_vif.NeutronPodVIFDriver):
"""Skeletal handler driver for VIFs for Nested Pods."""
def _get_parent_port(self, neutron, pod):
node_subnet_id = oslo_cfg.CONF.pod_vif_nested.worker_nodes_subnet
if not node_subnet_id:
raise oslo_cfg.RequiredOptError('worker_nodes_subnet',
oslo_cfg.OptGroup('pod_vif_nested'))
try:
# REVISIT(vikasc): Assumption is being made that hostIP is the IP
# of trunk interface on the node(vm).
node_fixed_ip = pod['status']['hostIP']
except KeyError:
if pod['status']['conditions'][0]['type'] != "Initialized":
LOG.debug("Pod condition type is not 'Initialized'")
LOG.error("Failed to get parent vm port ip")
raise
try:
fixed_ips = ['subnet_id=%s' % str(node_subnet_id),
'ip_address=%s' % str(node_fixed_ip)]
ports = neutron.list_ports(fixed_ips=fixed_ips)
except n_exc.NeutronClientException as ex:
LOG.error("Parent vm port with fixed ips %s not found!",
fixed_ips)
raise ex
if ports['ports']:
return ports['ports'][0]
else:
LOG.error("Neutron port for vm port with fixed ips %s"
" not found!", fixed_ips)
raise kl_exc.NoResourceException

View File

@ -13,16 +13,14 @@
# under the License.
from time import sleep
from kuryr.lib._i18n import _
from kuryr.lib import constants as kl_const
from kuryr.lib import segmentation_type_drivers as seg_driver
from neutronclient.common import exceptions as n_exc
from oslo_config import cfg as oslo_cfg
from oslo_log import log as logging
from kuryr_kubernetes import clients
from kuryr_kubernetes import constants as const
from kuryr_kubernetes.controller.drivers import generic_vif
from kuryr_kubernetes.controller.drivers import nested_vif
from kuryr_kubernetes import exceptions as k_exc
from kuryr_kubernetes import os_vif_util as ovu
@ -33,18 +31,8 @@ DEFAULT_MAX_RETRY_COUNT = 3
DEFAULT_RETRY_INTERVAL = 1
# Moved out from neutron_defaults group
nested_vif_driver_opts = [
oslo_cfg.StrOpt('worker_nodes_subnet',
help=_("Neutron subnet ID for k8s worker node vms.")),
]
oslo_cfg.CONF.register_opts(nested_vif_driver_opts, "pod_vif_nested")
class NestedVlanPodVIFDriver(generic_vif.GenericPodVIFDriver):
"""Manages ports for nested-containers to provide VIFs."""
class NestedVlanPodVIFDriver(nested_vif.NestedPodVIFDriver):
"""Manages ports for nested-containers using VLANs to provide VIFs."""
def request_vif(self, pod, project_id, subnets, security_groups):
neutron = clients.get_neutron_client()
@ -95,39 +83,6 @@ class NestedVlanPodVIFDriver(generic_vif.GenericPodVIFDriver):
"with a Neutron vlan trunk")
raise k_exc.K8sNodeTrunkPortFailure
def _get_parent_port(self, neutron, pod):
node_subnet_id = oslo_cfg.CONF.pod_vif_nested.worker_nodes_subnet
if not node_subnet_id:
raise oslo_cfg.RequiredOptError('worker_nodes_subnet',
'pod_vif_nested')
try:
# REVISIT(vikasc): Assumption is being made that hostIP is the IP
# of trunk interface on the node(vm).
node_fixed_ip = pod['status']['hostIP']
except KeyError:
if pod['status']['conditions'][0]['type'] != "Initialized":
LOG.debug("Pod condition type is not 'Initialized'")
LOG.error("Failed to get parent vm port ip")
raise
try:
fixed_ips = ['subnet_id=%s' % str(node_subnet_id),
'ip_address=%s' % str(node_fixed_ip)]
ports = neutron.list_ports(fixed_ips=fixed_ips)
except n_exc.NeutronClientException as ex:
LOG.error("Parent vm port with fixed ips %s not found!",
fixed_ips)
raise ex
if ports['ports']:
return ports['ports'][0]
else:
LOG.error("Neutron port for vm port with fixed ips %s"
" not found!", fixed_ips)
raise k_exc.K8sNodeTrunkPortFailure
def _add_subport(self, neutron, trunk_id, subport):
"""Adds subport port to Neutron trunk

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from kuryr.lib._i18n import _
from kuryr.lib import constants as kl_const
from neutronclient.common import exceptions as n_exc
from oslo_log import log as logging
@ -27,7 +26,7 @@ from kuryr_kubernetes import os_vif_util as ovu
LOG = logging.getLogger(__name__)
class GenericPodVIFDriver(base.PodVIFDriver):
class NeutronPodVIFDriver(base.PodVIFDriver):
"""Manages normal Neutron ports to provide VIFs for Kubernetes Pods."""
def request_vif(self, pod, project_id, subnets, security_groups):
@ -82,11 +81,9 @@ class GenericPodVIFDriver(base.PodVIFDriver):
ids = ovu.osvif_to_neutron_network_ids(subnets)
if len(ids) != 1:
raise k_exc.IntegrityError(_(
"Subnet mapping %(subnets)s is not valid: %(num_networks)s "
"unique networks found") % {
'subnets': subnets,
'num_networks': len(ids)})
raise k_exc.IntegrityError("Subnet mapping %(subnets)s is not "
"valid: %(num_networks)s unique networks found" %
{'subnets': subnets, 'num_networks': len(ids)})
return ids[0]

View File

@ -39,7 +39,6 @@ def format_msg(exception):
class K8sNodeTrunkPortFailure(Exception):
"""Exception represents that error is related to K8s node trunk port
This exception is thrown when Neutron port for k8s node could
not be found using subnet ID and IP address OR neutron port is
not associated to a Neutron vlan trunk.
This exception is thrown when Neutron port is not associated to a Neutron
vlan trunk.
"""

View File

@ -15,13 +15,13 @@ from oslo_log import _options
from kuryr.lib import opts as lib_opts
from kuryr_kubernetes import config
from kuryr_kubernetes.controller.drivers import nested_vlan_vif
from kuryr_kubernetes.controller.drivers import nested_vif
_kuryr_k8s_opts = [
('kubernetes', config.k8s_opts),
('kuryr-kubernetes', config.kuryr_k8s_opts),
('neutron_defaults', config.neutron_defaults),
('pod_vif_nested', nested_vlan_vif.nested_vif_driver_opts),
('pod_vif_nested', nested_vif.nested_vif_driver_opts),
]

View File

@ -0,0 +1,87 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from kuryr.lib import exceptions as kl_exc
from oslo_config import cfg as oslo_cfg
from kuryr_kubernetes.controller.drivers import nested_vif
from kuryr_kubernetes.tests import base as test_base
from kuryr_kubernetes.tests.unit import kuryr_fixtures as k_fix
class TestNestedPodVIFDriver(test_base.TestCase):
def test_get_parent_port(self):
cls = nested_vif.NestedPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
node_subnet_id = mock.sentinel.node_subnet_id
oslo_cfg.CONF.set_override('worker_nodes_subnet',
node_subnet_id,
group='pod_vif_nested')
node_fixed_ip = mock.sentinel.node_fixed_ip
pod_status = mock.MagicMock()
pod_status.__getitem__.return_value = node_fixed_ip
pod = mock.MagicMock()
pod.__getitem__.return_value = pod_status
port = mock.sentinel.port
ports = {'ports': [port]}
neutron.list_ports.return_value = ports
self.assertEqual(port, cls._get_parent_port(m_driver, neutron, pod))
fixed_ips = ['subnet_id=%s' % str(node_subnet_id),
'ip_address=%s' % str(node_fixed_ip)]
neutron.list_ports.assert_called_once_with(fixed_ips=fixed_ips)
def test_get_parent_port_subnet_id_not_configured(self):
cls = nested_vif.NestedPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
oslo_cfg.CONF.set_override('worker_nodes_subnet',
'',
group='pod_vif_nested')
pod = mock.MagicMock()
self.assertRaises(oslo_cfg.RequiredOptError,
cls._get_parent_port, m_driver, neutron, pod)
def test_get_parent_port_trunk_not_found(self):
cls = nested_vif.NestedPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
node_subnet_id = mock.sentinel.node_subnet_id
oslo_cfg.CONF.set_override('worker_nodes_subnet',
node_subnet_id,
group='pod_vif_nested')
node_fixed_ip = mock.sentinel.node_fixed_ip
pod_status = mock.MagicMock()
pod_status.__getitem__.return_value = node_fixed_ip
pod = mock.MagicMock()
pod.__getitem__.return_value = pod_status
ports = {'ports': []}
neutron.list_ports.return_value = ports
self.assertRaises(kl_exc.NoResourceException,
cls._get_parent_port, m_driver, neutron, pod)
fixed_ips = ['subnet_id=%s' % str(node_subnet_id),
'ip_address=%s' % str(node_fixed_ip)]
neutron.list_ports.assert_called_once_with(fixed_ips=fixed_ips)

View File

@ -15,7 +15,6 @@ import mock
from kuryr.lib import constants as kl_const
from kuryr.lib import exceptions as kl_exc
from neutronclient.common import exceptions as n_exc
from oslo_config import cfg as oslo_cfg
from kuryr_kubernetes import constants as const
from kuryr_kubernetes.controller.drivers import nested_vlan_vif
@ -173,70 +172,6 @@ class TestNestedVlanPodVIFDriver(test_base.TestCase):
self.assertRaises(k_exc.K8sNodeTrunkPortFailure,
cls._get_trunk_id, m_driver, port)
def test_get_parent_port(self):
cls = nested_vlan_vif.NestedVlanPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
node_subnet_id = mock.sentinel.node_subnet_id
oslo_cfg.CONF.set_override('worker_nodes_subnet',
node_subnet_id,
group='pod_vif_nested')
node_fixed_ip = mock.sentinel.node_fixed_ip
pod_status = mock.MagicMock()
pod_status.__getitem__.return_value = node_fixed_ip
pod = mock.MagicMock()
pod.__getitem__.return_value = pod_status
port = mock.sentinel.port
ports = {'ports': [port]}
neutron.list_ports.return_value = ports
self.assertEqual(port, cls._get_parent_port(m_driver, neutron, pod))
fixed_ips = ['subnet_id=%s' % str(node_subnet_id),
'ip_address=%s' % str(node_fixed_ip)]
neutron.list_ports.assert_called_once_with(fixed_ips=fixed_ips)
def test_get_parent_port_subnet_id_not_configured(self):
cls = nested_vlan_vif.NestedVlanPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
oslo_cfg.CONF.set_override('worker_nodes_subnet',
'',
group='pod_vif_nested')
pod = mock.MagicMock()
self.assertRaises(oslo_cfg.RequiredOptError,
cls._get_parent_port, m_driver, neutron, pod)
def test_get_parent_port_trunk_not_found(self):
cls = nested_vlan_vif.NestedVlanPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
node_subnet_id = mock.sentinel.node_subnet_id
oslo_cfg.CONF.set_override('worker_nodes_subnet',
node_subnet_id,
group='pod_vif_nested')
node_fixed_ip = mock.sentinel.node_fixed_ip
pod_status = mock.MagicMock()
pod_status.__getitem__.return_value = node_fixed_ip
pod = mock.MagicMock()
pod.__getitem__.return_value = pod_status
ports = {'ports': []}
neutron.list_ports.return_value = ports
self.assertRaises(k_exc.K8sNodeTrunkPortFailure,
cls._get_parent_port, m_driver, neutron, pod)
fixed_ips = ['subnet_id=%s' % str(node_subnet_id),
'ip_address=%s' % str(node_fixed_ip)]
neutron.list_ports.assert_called_once_with(fixed_ips=fixed_ips)
def test_add_subport(self):
cls = nested_vlan_vif.NestedVlanPodVIFDriver
m_driver = mock.Mock(spec=cls)

View File

@ -18,17 +18,17 @@ import mock
from kuryr.lib import constants as kl_const
from neutronclient.common import exceptions as n_exc
from kuryr_kubernetes.controller.drivers import generic_vif
from kuryr_kubernetes.controller.drivers import neutron_vif
from kuryr_kubernetes import exceptions as k_exc
from kuryr_kubernetes.tests import base as test_base
from kuryr_kubernetes.tests.unit import kuryr_fixtures as k_fix
class GenericPodVIFDriver(test_base.TestCase):
class NeutronPodVIFDriver(test_base.TestCase):
@mock.patch('kuryr_kubernetes.os_vif_util.neutron_to_osvif_vif')
def test_request_vif(self, m_to_vif):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
@ -56,7 +56,7 @@ class GenericPodVIFDriver(test_base.TestCase):
m_to_vif.assert_called_once_with(vif_plugin, port, subnets)
def test_release_vif(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
@ -68,7 +68,7 @@ class GenericPodVIFDriver(test_base.TestCase):
neutron.delete_port.assert_called_once_with(vif.id)
def test_release_vif_not_found(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
@ -81,7 +81,7 @@ class GenericPodVIFDriver(test_base.TestCase):
neutron.delete_port.assert_called_once_with(vif.id)
def test_activate_vif(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
@ -99,7 +99,7 @@ class GenericPodVIFDriver(test_base.TestCase):
self.assertTrue(vif.active)
def test_activate_vif_active(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
@ -112,7 +112,7 @@ class GenericPodVIFDriver(test_base.TestCase):
neutron.show_port.assert_not_called()
def test_activate_vif_not_ready(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
neutron = self.useFixture(k_fix.MockNeutronClient()).client
@ -128,7 +128,7 @@ class GenericPodVIFDriver(test_base.TestCase):
m_driver, pod, vif)
def _test_get_port_request(self, m_to_fips, security_groups):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
pod = mock.sentinel.pod
@ -179,7 +179,7 @@ class GenericPodVIFDriver(test_base.TestCase):
self._test_get_port_request(m_to_fips, security_groups)
def test_get_vif_plugin(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
vif_plugin = mock.sentinel.vif_plugin
port = {'binding:vif_type': vif_plugin}
@ -188,7 +188,7 @@ class GenericPodVIFDriver(test_base.TestCase):
@mock.patch('kuryr_kubernetes.os_vif_util.osvif_to_neutron_network_ids')
def test_get_network_id(self, m_to_net_ids):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
subnets = mock.sentinel.subnets
network_id = mock.sentinel.network_id
@ -199,7 +199,7 @@ class GenericPodVIFDriver(test_base.TestCase):
@mock.patch('kuryr_kubernetes.os_vif_util.osvif_to_neutron_network_ids')
def test_get_network_id_invalid(self, m_to_net_ids):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
subnets = mock.sentinel.subnets
m_to_net_ids.return_value = []
@ -208,7 +208,7 @@ class GenericPodVIFDriver(test_base.TestCase):
subnets)
def test_get_port_name(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
pod_name = mock.sentinel.pod_name
pod = {'metadata': {'name': pod_name}}
@ -216,7 +216,7 @@ class GenericPodVIFDriver(test_base.TestCase):
self.assertEqual(pod_name, cls._get_port_name(m_driver, pod))
def test_get_device_id(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
pod_uid = mock.sentinel.pod_uid
pod = {'metadata': {'uid': pod_uid}}
@ -224,7 +224,7 @@ class GenericPodVIFDriver(test_base.TestCase):
self.assertEqual(pod_uid, cls._get_device_id(m_driver, pod))
def test_get_host_id(self):
cls = generic_vif.GenericPodVIFDriver
cls = neutron_vif.NeutronPodVIFDriver
m_driver = mock.Mock(spec=cls)
node = mock.sentinel.pod_uid
pod = {'spec': {'nodeName': node}}