support specifying port_id when attaching interface
Change-Id: I5d3f18a32c357096f5a6090abed1d8d480a93c6f
This commit is contained in:
parent
30a16bc608
commit
817748c6b0
@ -1,3 +1,4 @@
|
||||
{
|
||||
"net_id": "a19ffb45-8207-4771-b0ef-f63c91fb46d6"
|
||||
"port_id": "6cefb080-77bb-4bf9-8695-c10401e86c05"
|
||||
}
|
||||
|
@ -117,6 +117,7 @@ Request
|
||||
|
||||
- server_uuid: server_ident
|
||||
- net_id: network_uuid
|
||||
- port_id: port_uuid
|
||||
|
||||
**Example request to Add (Associate) Interface to a server:**
|
||||
|
||||
|
@ -21,7 +21,11 @@ attach_interface = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'net_id': parameter_types.network_id,
|
||||
'port_id': parameter_types.network_port_id
|
||||
},
|
||||
'required': ['net_id'],
|
||||
'oneOf': [
|
||||
{'required': ['net_id']},
|
||||
{'required': ['port_id']}
|
||||
],
|
||||
'additionalProperties': False
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import pecan
|
||||
from pecan import rest
|
||||
import six
|
||||
from six.moves import http_client
|
||||
from webob import exc
|
||||
import wsme
|
||||
from wsme import types as wtypes
|
||||
|
||||
@ -339,15 +338,12 @@ class InterfaceController(ServerControllerBase):
|
||||
"""
|
||||
validation.check_schema(interface, interface_schemas.attach_interface)
|
||||
|
||||
port_id = interface.get('port_id', None)
|
||||
net_id = interface.get('net_id', None)
|
||||
|
||||
if not net_id:
|
||||
msg = _("Must input network_id")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
server = self._resource or self._get_resource(server_uuid)
|
||||
pecan.request.engine_api.attach_interface(pecan.request.context,
|
||||
server, net_id)
|
||||
server, net_id, port_id)
|
||||
|
||||
@policy.authorize_wsgi("mogan:server", "detach_interface")
|
||||
@expose.expose(None, types.uuid, types.uuid,
|
||||
|
@ -28,6 +28,7 @@ from mogan.common import ironic
|
||||
from mogan.common import states
|
||||
from mogan.conf import CONF
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
_POWER_STATE_MAP = {
|
||||
|
@ -546,9 +546,9 @@ class API(object):
|
||||
return objects.KeyPair.get_by_name(context, user_id, key_name)
|
||||
|
||||
@check_server_lock
|
||||
def attach_interface(self, context, server, net_id):
|
||||
def attach_interface(self, context, server, net_id, port_id):
|
||||
LOG.debug('Going to attach interface to server %s', server.uuid)
|
||||
self.engine_rpcapi.attach_interface(context, server, net_id)
|
||||
self.engine_rpcapi.attach_interface(context, server, net_id, port_id)
|
||||
|
||||
@check_server_lock
|
||||
def detach_interface(self, context, server, port_id):
|
||||
|
@ -530,23 +530,45 @@ class EngineManager(base_manager.BaseEngineManager):
|
||||
'port': parsed_url.port,
|
||||
'internal_access_path': None}
|
||||
|
||||
def attach_interface(self, context, server, net_id=None):
|
||||
LOG.debug("Attaching interface %(net_id) to server %(server)s",
|
||||
{'net_id': net_id, 'server': server})
|
||||
@wrap_server_fault
|
||||
def attach_interface(self, context, server, net_id, port_id):
|
||||
# prepare port to be attached
|
||||
if port_id:
|
||||
LOG.debug("Attaching port %(port_id) to server %(server)s",
|
||||
{'port_id': port_id, 'server': server})
|
||||
try:
|
||||
vif_port = self.network_api.show_port(context, port_id)
|
||||
except Exception:
|
||||
raise exception.PortNotFound(port_id=port_id)
|
||||
|
||||
# self.network_api.check_port_availability(vif_port)
|
||||
|
||||
else:
|
||||
LOG.debug("Attaching network interface %(net_id) to server "
|
||||
"%(server)s", {'net_id': net_id, 'server': server})
|
||||
vif_port = self.network_api.create_port(context, net_id,
|
||||
server.uuid)
|
||||
|
||||
try:
|
||||
port = self.network_api.create_port(context, net_id, server.uuid)
|
||||
self.driver.plug_vif(server.node_uuid, port['id'])
|
||||
vif = self.network_api.bind_port(context, vif_port['id'], server)
|
||||
vif_port = vif['port']
|
||||
self.driver.plug_vif(server.node_uuid, vif_port['id'])
|
||||
nics_obj = objects.ServerNics(context)
|
||||
nic_dict = {'port_id': port['id'],
|
||||
'network_id': port['network_id'],
|
||||
'mac_address': port['mac_address'],
|
||||
'fixed_ips': port['fixed_ips'],
|
||||
nic_dict = {'port_id': vif_port['id'],
|
||||
'network_id': vif_port['network_id'],
|
||||
'mac_address': vif_port['mac_address'],
|
||||
'fixed_ips': vif_port['fixed_ips'],
|
||||
'server_uuid': server.uuid}
|
||||
nics_obj.objects.append(objects.ServerNic(
|
||||
context, **nic_dict))
|
||||
server.nics = nics_obj
|
||||
server.save()
|
||||
except Exception as e:
|
||||
if port_id:
|
||||
self.network_api.unbind_port(context, vif_port)
|
||||
else:
|
||||
self.network_api.delete_port(context, vif_port['id'],
|
||||
server.uuid)
|
||||
raise exception.InterfaceAttachFailed(message=six.text_type(e))
|
||||
LOG.info('Attaching interface successfully')
|
||||
|
||||
@ -569,6 +591,7 @@ class EngineManager(base_manager.BaseEngineManager):
|
||||
except exception.PortNotFound:
|
||||
pass
|
||||
|
||||
@wrap_server_fault
|
||||
def detach_interface(self, context, server, port_id):
|
||||
LOG.debug("Detaching interface %(port_id) from server %(server)s",
|
||||
{'port_id': port_id, 'server': server.uuid})
|
||||
|
@ -83,10 +83,10 @@ class EngineAPI(object):
|
||||
return cctxt.call(context, 'get_serial_console',
|
||||
server=server)
|
||||
|
||||
def attach_interface(self, context, server, net_id):
|
||||
def attach_interface(self, context, server, net_id, port_id):
|
||||
cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
|
||||
cctxt.call(context, 'attach_interface',
|
||||
server=server, net_id=net_id)
|
||||
server=server, net_id=net_id, port_id=port_id)
|
||||
|
||||
def detach_interface(self, context, server, port_id):
|
||||
cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
|
||||
|
@ -23,6 +23,9 @@ from mogan.conf import CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
_NEUTRON_SESSION = None
|
||||
BINDING_PROFILE = 'binding:profile'
|
||||
BINDING_HOST_ID = 'binding:host_id'
|
||||
BINDING_VNIC_TYPE = 'binding:vnic_type'
|
||||
|
||||
|
||||
def _get_neutron_session():
|
||||
@ -205,6 +208,43 @@ class API(object):
|
||||
|
||||
return nets
|
||||
|
||||
def bind_port(self, context, port, server):
|
||||
client = get_client(context.auth_token)
|
||||
req_body = {
|
||||
'port': {
|
||||
'device_id': server.uuid,
|
||||
}
|
||||
}
|
||||
try:
|
||||
port = client.update_port(port, req_body)
|
||||
except neutron_exceptions.PortNotFoundClient:
|
||||
LOG.debug('Unable to bind port %s as it no longer exists.', port)
|
||||
except Exception:
|
||||
LOG.exception("Unable to add device ID for port '%s'", port)
|
||||
return port
|
||||
|
||||
def unbind_port(self, context, port):
|
||||
client = get_client(context.auth_token)
|
||||
port_req_body = {'port': {'device_id': '', 'device_owner': ''}}
|
||||
if port[BINDING_HOST_ID]:
|
||||
port_req_body['port'][BINDING_HOST_ID] = None
|
||||
if port[BINDING_PROFILE]:
|
||||
port_req_body['port'][BINDING_PROFILE] = {}
|
||||
if port[BINDING_VNIC_TYPE] != 'normal':
|
||||
port_req_body['port'][BINDING_VNIC_TYPE] = 'normal'
|
||||
|
||||
try:
|
||||
port = client.update_port(port['id'], port_req_body)
|
||||
except neutron_exceptions.PortNotFoundClient:
|
||||
LOG.debug('Unable to unbind port %s as it no longer exists.',
|
||||
port)
|
||||
except Exception:
|
||||
LOG.exception("Unable to clear device ID for port '%s'", port)
|
||||
|
||||
def check_port_availability(self, port):
|
||||
if port['device_id']:
|
||||
raise exception.PortInUse(port_id=port['id'])
|
||||
|
||||
def _get_available_ports(self, port_ids, client):
|
||||
"""Return a port list available for the tenant."""
|
||||
|
||||
|
@ -172,7 +172,7 @@ class BaremetalComputeAPIServersTest(base.BaseBaremetalComputeTest):
|
||||
nics_before = self.baremetal_compute_client.server_get_networks(
|
||||
self.server_ids[0])
|
||||
self.baremetal_compute_client.server_attach_interface(
|
||||
self.server_ids[0], net_id=self.net_id)
|
||||
self.server_ids[0], net_id=self.net_id, port_id=None)
|
||||
nics_after = self.baremetal_compute_client.server_get_networks(
|
||||
self.server_ids[0])
|
||||
self.assertEqual(len(nics_before) + 1, len(nics_after))
|
||||
|
@ -191,7 +191,7 @@ class BaremetalComputeClient(rest_client.RestClient):
|
||||
body = self.deserialize(body)['nics']
|
||||
return rest_client.ResponseBodyList(resp, body)
|
||||
|
||||
def server_attach_interface(self, server_id, net_id):
|
||||
def server_attach_interface(self, server_id, net_id, port_id):
|
||||
uri = '%s/servers/%s/networks/interfaces' % (self.uri_prefix,
|
||||
server_id)
|
||||
body = {"net_id": net_id}
|
||||
|
Loading…
x
Reference in New Issue
Block a user