Refactor network APIs

1. Move network related codes into its own dir
2. Initialize network API to interact with neutron

Change-Id: I19f9aeeeac4b75f4d738deb8e3981c4c50d82b78
This commit is contained in:
Zhenguo Niu 2016-12-20 21:00:02 +08:00
parent ac68652f46
commit e90f083aff
7 changed files with 62 additions and 40 deletions

View File

@ -25,6 +25,7 @@ from nimble.common import rpc
from nimble.conf import CONF
from nimble.db import api as dbapi
from nimble.engine import rpcapi
from nimble import network
class BaseEngineManager(periodic_task.PeriodicTasks):
@ -36,6 +37,7 @@ class BaseEngineManager(periodic_task.PeriodicTasks):
self.host = host
self.topic = topic
self.node_cache = {}
self.network_api = network.API()
scheduler_driver = CONF.scheduler.scheduler_driver
self.scheduler = importutils.import_object(scheduler_driver)
self.notifier = rpc.get_notifier()

View File

@ -26,7 +26,6 @@ from nimble.common import exception
from nimble.common import flow_utils
from nimble.common.i18n import _LE
from nimble.common.i18n import _LI
from nimble.common import neutron
from nimble.common import utils
from nimble.engine.baremetal import ironic
from nimble.engine.baremetal import ironic_states
@ -175,10 +174,11 @@ class SetInstanceInfoTask(flow_utils.NimbleTask):
class BuildNetworkTask(flow_utils.NimbleTask):
"""Build network for the instance."""
def __init__(self, ironicclient):
def __init__(self, network_api, ironicclient):
requires = ['instance', 'requested_networks', 'context']
super(BuildNetworkTask, self).__init__(addons=[ACTION],
requires=requires)
self.network_api = network_api
self.ironicclient = ironicclient
# These exception types will trigger the network to be cleaned.
self.network_cleaned_exc_types = [
@ -210,8 +210,8 @@ class BuildNetworkTask(flow_utils.NimbleTask):
# Match the specified port type with physical interface type
if vif.get('port_type') == pif.extra.get('port_type'):
try:
port = neutron.create_port(context, vif['uuid'],
pif.address, instance.uuid)
port = self.network_api.create_port(
context, vif['uuid'], pif.address, instance.uuid)
port_dict = port['port']
network_info[port_dict['id']] = {
'network': port_dict['network_id'],
@ -237,7 +237,7 @@ class BuildNetworkTask(flow_utils.NimbleTask):
ports = instance.network_info.keys()
for port in ports:
neutron.delete_port(context, port, instance.uuid)
self.network_api.delete_port(context, port, instance.uuid)
ironic_ports = ironic.get_ports_from_node(self.ironicclient,
instance.node_uuid,
@ -368,7 +368,8 @@ def get_flow(context, manager, instance, requested_networks, request_spec,
instance_flow.add(ScheduleCreateInstanceTask(manager),
OnFailureRescheduleTask(manager.engine_rpcapi),
SetInstanceInfoTask(manager.ironicclient),
BuildNetworkTask(manager.ironicclient),
BuildNetworkTask(manager.network_api,
manager.ironicclient),
CreateInstanceTask(manager.ironicclient))
# Now load (but do not run) the flow using the provided initial data.

View File

@ -21,7 +21,6 @@ from nimble.common import exception
from nimble.common import flow_utils
from nimble.common.i18n import _LE
from nimble.common.i18n import _LI
from nimble.common import neutron
from nimble.conf import CONF
from nimble.engine.baremetal import ironic
from nimble.engine.baremetal import ironic_states
@ -70,7 +69,7 @@ class EngineManager(base_manager.BaseEngineManager):
ports = instance.network_info.keys()
for port in ports:
neutron.delete_port(context, port, instance.uuid)
self.network_api.delete_port(context, port, instance.uuid)
ironic_ports = ironic.get_ports_from_node(self.ironicclient,
instance.node_uuid,

View File

@ -0,0 +1,17 @@
# 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.
def API():
# Needed to prevent circular import...
import nimble.network.api
return nimble.network.api.API()

View File

@ -58,37 +58,39 @@ def get_client(token=None):
return clientv20.Client(**params)
def create_port(context, network_uuid, mac, instance_uuid):
"""Create neutron port."""
class API(object):
"""API for interacting with the neutron 2.x API."""
client = get_client(context.auth_token)
body = {
'port': {
'network_id': network_uuid,
'mac_address': mac,
def create_port(self, context, network_uuid, mac, instance_uuid):
"""Create neutron port."""
client = get_client(context.auth_token)
body = {
'port': {
'network_id': network_uuid,
'mac_address': mac,
}
}
}
try:
port = client.create_port(body)
except neutron_exceptions.NeutronClientException as e:
msg = (_("Could not create neutron port on network %(net)s for "
"instance %(instance)s. %(exc)s"),
{'net': network_uuid, 'instance': instance_uuid, 'exc': e})
LOG.exception(msg)
raise exception.NetworkError(msg)
return port
try:
port = client.create_port(body)
except neutron_exceptions.NeutronClientException as e:
msg = (_("Could not create neutron port on network %(net)s for "
"instance %(instance)s. %(exc)s"),
{'net': network_uuid, 'instance': instance_uuid, 'exc': e})
LOG.exception(msg)
raise exception.NetworkError(msg)
return port
def delete_port(self, context, port_id, instance_uuid):
"""Delete neutron port."""
def delete_port(context, port_id, instance_uuid):
"""Delete neutron port."""
client = get_client(context.auth_token)
try:
client.delete_port(port_id)
except neutron_exceptions.NeutronClientException as e:
msg = (_('Could not remove VIF %(vif)s of instance %(instance)s, '
'possibly a network issue: %(exc)s') %
{'vif': port_id, 'instance': instance_uuid, 'exc': e})
LOG.exception(msg)
raise exception.NetworkError(msg)
client = get_client(context.auth_token)
try:
client.delete_port(port_id)
except neutron_exceptions.NeutronClientException as e:
msg = (_('Could not remove VIF %(vif)s of instance %(instance)s, '
'possibly a network issue: %(exc)s') %
{'vif': port_id, 'instance': instance_uuid, 'exc': e})
LOG.exception(msg)
raise exception.NetworkError(msg)

View File

@ -77,9 +77,10 @@ class CreateInstanceFlowTestCase(base.TestCase):
@mock.patch.object(create_instance.BuildNetworkTask, '_build_networks')
def test_create_network_task_execute(self, mock_build_networks, mock_save):
fake_ironicclient = mock.MagicMock()
fake_network_api = mock.MagicMock()
fake_requested_networks = mock.MagicMock()
task = create_instance.BuildNetworkTask(
fake_ironicclient)
fake_network_api, fake_ironicclient)
instance_obj = obj_utils.get_test_instance(self.ctxt)
mock_build_networks.side_effect = None
mock_save.side_effect = None

View File

@ -17,10 +17,10 @@
import mock
from nimble.common import neutron
from nimble.engine.baremetal import ironic
from nimble.engine.baremetal import ironic_states
from nimble.engine import manager
from nimble.network import api as network_api
from nimble.tests.unit.db import base as tests_db_base
from nimble.tests.unit.engine import mgr_utils
from nimble.tests.unit.objects import utils as obj_utils
@ -32,7 +32,7 @@ class ManageInstanceTestCase(mgr_utils.ServiceSetUpMixin,
@mock.patch.object(ironic, 'unplug_vif')
@mock.patch.object(ironic, 'get_ports_from_node')
@mock.patch.object(neutron, 'delete_port')
@mock.patch.object(network_api.API, 'delete_port')
def test__destroy_networks(self, delete_port_mock,
get_ports_mock, unplug_vif_mock,
refresh_cache_mock):