Update CIF creation request body
The CIF API got updated in new v3 builds. Here is what changed: 1. The information like ip, mac, vlan, host_cif_id which was intially opaque and just provided as a key value pair inside the context body, now have explicit properties. 2. The context now contains container_host_vif_id, and vlan_tag as explicit properties. It still has a key_values array but no information is needed to be passed in that. That's more reserved for future use cases. 3. The host_vif_id property name is updated to container_host_vif_id. 4. The vlan_id property name is updated to vlan_tag. 5. The IP and mac address of the port are moved out of the context. This was previously being duplicated as we pass that information in address bindings already. Here is the sample request body. { "resource_type": "LogicalPort", "attachment": { "attachment_type": "CIF", "id": "test-2", "context": { "vlan_tag": 122, "container_host_vif_id": "c6f817a0-4e36-421e-98a6-8a2faed880bc", "key_values": [], "resource_type": "CifAttachmentContext" } }, "admin_state": "UP", "logical_switch_id": "<logical-switch-id>", "address_bindings": [ { "ip_address": "192.168.1.110", "mac_address": "aa:bb:cc:dd:ee:ff" } ], } This patch makes the plugin send the expected request body to the backend. Also this patch updates default argument in the create_port and update_port method from parent_name to parent_vif_id DocImpact Change-Id: Icf9109839284df9217877342182df4dce4ca2787
This commit is contained in:
parent
91fecee67c
commit
47bb0a8a6c
@ -236,40 +236,31 @@ class LogicalPort(AbstractRESTResource):
|
||||
|
||||
return body
|
||||
|
||||
def _prepare_attachment(self, vif_uuid, parent_name, parent_tag,
|
||||
def _prepare_attachment(self, vif_uuid, parent_vif_id, parent_tag,
|
||||
address_bindings, attachment_type):
|
||||
# NOTE(arosen): if a parent_name is specified we need to use the
|
||||
# CIF's attachment.
|
||||
key_values = None
|
||||
if parent_name:
|
||||
attachment_type = nsx_constants.ATTACHMENT_CIF
|
||||
key_values = [
|
||||
{'key': 'VLAN_ID', 'value': parent_tag},
|
||||
{'key': 'Host_VIF_ID', 'value': parent_name},
|
||||
{'key': 'IP', 'value': address_bindings[0].ip_address},
|
||||
{'key': 'MAC', 'value': address_bindings[0].mac_address}]
|
||||
# NOTE(arosen): The above api body structure might change
|
||||
# in the future
|
||||
|
||||
if attachment_type and vif_uuid:
|
||||
attachment = {'attachment_type': attachment_type,
|
||||
'id': vif_uuid}
|
||||
|
||||
if key_values:
|
||||
attachment['context'] = {'key_values': key_values}
|
||||
attachment['context']['resource_type'] = \
|
||||
nsx_constants.CIF_RESOURCE_TYPE
|
||||
if parent_vif_id:
|
||||
context = {'vlan_tag': parent_tag,
|
||||
'container_host_vif_id': parent_vif_id,
|
||||
'resource_type': nsx_constants.CIF_RESOURCE_TYPE}
|
||||
attachment['context'] = context
|
||||
return attachment
|
||||
|
||||
def create(self, lswitch_id, vif_uuid, tags=None,
|
||||
attachment_type=nsx_constants.ATTACHMENT_VIF,
|
||||
admin_state=True, name=None, address_bindings=None,
|
||||
parent_name=None, parent_tag=None,
|
||||
parent_vif_id=None, parent_tag=None,
|
||||
switch_profile_ids=None):
|
||||
tags = tags or []
|
||||
|
||||
body = {'logical_switch_id': lswitch_id}
|
||||
attachment = self._prepare_attachment(vif_uuid, parent_name,
|
||||
# NOTE(arosen): If parent_vif_id is specified we need to use
|
||||
# CIF attachment type.
|
||||
if parent_vif_id:
|
||||
attachment_type = nsx_constants.ATTACHMENT_CIF
|
||||
attachment = self._prepare_attachment(vif_uuid, parent_vif_id,
|
||||
parent_tag, address_bindings,
|
||||
attachment_type)
|
||||
body.update(self._build_body_attrs(
|
||||
@ -294,12 +285,12 @@ class LogicalPort(AbstractRESTResource):
|
||||
address_bindings=None, switch_profile_ids=None,
|
||||
tags_update=None,
|
||||
attachment_type=nsx_constants.ATTACHMENT_VIF,
|
||||
parent_name=None, parent_tag=None):
|
||||
parent_vif_id=None, parent_tag=None):
|
||||
lport = self.get(lport_id)
|
||||
tags = lport.get('tags', [])
|
||||
if tags_update:
|
||||
tags = utils.update_v3_tags(tags, tags_update)
|
||||
attachment = self._prepare_attachment(vif_uuid, parent_name,
|
||||
attachment = self._prepare_attachment(vif_uuid, parent_vif_id,
|
||||
parent_tag, address_bindings,
|
||||
attachment_type)
|
||||
lport.update(self._build_body_attrs(
|
||||
|
@ -1245,7 +1245,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
admin_state=port_data['admin_state_up'],
|
||||
address_bindings=address_bindings,
|
||||
attachment_type=attachment_type,
|
||||
parent_name=parent_name, parent_tag=tag,
|
||||
parent_vif_id=parent_name, parent_tag=tag,
|
||||
switch_profile_ids=profiles)
|
||||
except nsx_exc.ManagerError as inst:
|
||||
# we may fail if the QoS is not supported for this port
|
||||
@ -1754,7 +1754,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
updated_device_id)
|
||||
|
||||
vif_uuid = updated_port['id']
|
||||
parent_name, tag = self._get_data_from_binding_profile(
|
||||
parent_vif_id, tag = self._get_data_from_binding_profile(
|
||||
context, updated_port)
|
||||
attachment_type = nsx_constants.ATTACHMENT_VIF
|
||||
if (not updated_device_owner or
|
||||
@ -1803,7 +1803,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
address_bindings=address_bindings,
|
||||
switch_profile_ids=switch_profile_ids,
|
||||
tags_update=tags_update,
|
||||
parent_name=parent_name,
|
||||
parent_vif_id=parent_vif_id,
|
||||
parent_tag=tag)
|
||||
except nsx_exc.ManagerError as inst:
|
||||
# we may fail if the QoS is not supported for this port
|
||||
|
@ -56,6 +56,52 @@ FAKE_PORT = {
|
||||
]
|
||||
}
|
||||
|
||||
FAKE_CONTAINER_PORT = {
|
||||
"id": FAKE_PORT_UUID,
|
||||
"display_name": FAKE_NAME,
|
||||
"resource_type": "LogicalPort",
|
||||
"address_bindings": [
|
||||
{
|
||||
"ip_address": "192.168.1.110",
|
||||
"mac_address": "aa:bb:cc:dd:ee:ff"
|
||||
}
|
||||
],
|
||||
"logical_switch_id": FAKE_SWITCH_UUID,
|
||||
"admin_state": "UP",
|
||||
"attachment": {
|
||||
"id": "9ca8d413-f7bf-4276-b4c9-62f42516bdb2",
|
||||
"attachment_type": "CIF",
|
||||
"context": {
|
||||
"vlan_tag": 122,
|
||||
"container_host_vif_id": "c6f817a0-4e36-421e-98a6-8a2faed880bc",
|
||||
"key_values": [],
|
||||
"resource_type": "CifAttachmentContext",
|
||||
}
|
||||
},
|
||||
"switching_profile_ids": [
|
||||
{
|
||||
"value": "64814784-7896-3901-9741-badeff705639",
|
||||
"key": "IpDiscoverySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fad98876-d7ff-11e4-b9d6-1681e6b88ec1",
|
||||
"key": "SpoofGuardSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "93b4b7e8-f116-415d-a50c-3364611b5d09",
|
||||
"key": "PortMirroringSwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "fbc4fb17-83d9-4b53-a286-ccdf04301888",
|
||||
"key": "SwitchSecuritySwitchingProfile"
|
||||
},
|
||||
{
|
||||
"value": "f313290b-eba8-4262-bd93-fab5026e9495",
|
||||
"key": "QosSwitchingProfile"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
FAKE_QOS_PROFILE = {
|
||||
"resource_type": "QosSwitchingProfile",
|
||||
"id": uuidutils.generate_uuid(),
|
||||
|
@ -235,28 +235,36 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
return self.mocked_resource(
|
||||
resources.LogicalPort, session_response=session_response)
|
||||
|
||||
def _get_profile_dicts(self, fake_port):
|
||||
fake_profile_dicts = []
|
||||
for profile_id in fake_port['switching_profile_ids']:
|
||||
fake_profile_dicts.append({'resource_type': profile_id['key'],
|
||||
'id': profile_id['value']})
|
||||
return fake_profile_dicts
|
||||
|
||||
def _get_pktcls_bindings(self):
|
||||
fake_pkt_classifiers = []
|
||||
fake_binding_repr = []
|
||||
for i in range(0, 3):
|
||||
ip = "9.10.11.%s" % i
|
||||
mac = "00:0c:29:35:4a:%sc" % i
|
||||
fake_pkt_classifiers.append(resources.PacketAddressClassifier(
|
||||
ip, mac, None))
|
||||
fake_binding_repr.append({
|
||||
'ip_address': ip,
|
||||
'mac_address': mac
|
||||
})
|
||||
return fake_pkt_classifiers, fake_binding_repr
|
||||
|
||||
def test_create_logical_port(self):
|
||||
"""
|
||||
Test creating a port returns the correct response and 200 status
|
||||
"""
|
||||
fake_port = test_constants_v3.FAKE_PORT.copy()
|
||||
|
||||
profile_dicts = []
|
||||
for profile_id in fake_port['switching_profile_ids']:
|
||||
profile_dicts.append({'resource_type': profile_id['key'],
|
||||
'id': profile_id['value']})
|
||||
profile_dicts = self._get_profile_dicts(fake_port)
|
||||
|
||||
pkt_classifiers = []
|
||||
binding_repr = []
|
||||
for i in range(0, 3):
|
||||
ip = "9.10.11.%s" % i
|
||||
mac = "00:0c:29:35:4a:%sc" % i
|
||||
pkt_classifiers.append(resources.PacketAddressClassifier(
|
||||
ip, mac, None))
|
||||
binding_repr.append({
|
||||
'ip_address': ip,
|
||||
'mac_address': mac
|
||||
})
|
||||
pkt_classifiers, binding_repr = self._get_pktcls_bindings()
|
||||
|
||||
fake_port['address_bindings'] = binding_repr
|
||||
|
||||
@ -286,6 +294,54 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
'https://1.2.3.4/api/v1/logical-ports',
|
||||
data=jsonutils.dumps(resp_body, sort_keys=True))
|
||||
|
||||
def test_create_logical_port_with_attachtype_cif(self):
|
||||
"""
|
||||
Test creating a port returns the correct response and 200 status
|
||||
"""
|
||||
fake_port = test_constants_v3.FAKE_CONTAINER_PORT.copy()
|
||||
|
||||
profile_dicts = self._get_profile_dicts(fake_port)
|
||||
|
||||
pkt_classifiers, binding_repr = self._get_pktcls_bindings()
|
||||
|
||||
fake_port['address_bindings'] = binding_repr
|
||||
|
||||
mocked_resource = self._mocked_lport()
|
||||
switch_profile = resources.SwitchingProfile
|
||||
fake_port_ctx = fake_port['attachment']['context']
|
||||
|
||||
fake_container_host_vif_id = fake_port_ctx['container_host_vif_id']
|
||||
|
||||
mocked_resource.create(
|
||||
fake_port['logical_switch_id'],
|
||||
fake_port['attachment']['id'],
|
||||
parent_vif_id=fake_container_host_vif_id,
|
||||
parent_tag=fake_port_ctx['vlan_tag'],
|
||||
address_bindings=pkt_classifiers,
|
||||
switch_profile_ids=switch_profile.build_switch_profile_ids(
|
||||
mock.Mock(), *profile_dicts))
|
||||
|
||||
resp_body = {
|
||||
'logical_switch_id': fake_port['logical_switch_id'],
|
||||
'switching_profile_ids': fake_port['switching_profile_ids'],
|
||||
'attachment': {
|
||||
'attachment_type': 'CIF',
|
||||
'id': fake_port['attachment']['id'],
|
||||
'context': {
|
||||
'vlan_tag': fake_port_ctx['vlan_tag'],
|
||||
'container_host_vif_id': fake_container_host_vif_id,
|
||||
'resource_type': 'CifAttachmentContext'
|
||||
}
|
||||
},
|
||||
'admin_state': 'UP',
|
||||
'address_bindings': fake_port['address_bindings']
|
||||
}
|
||||
|
||||
test_client.assert_json_call(
|
||||
'post', mocked_resource,
|
||||
'https://1.2.3.4/api/v1/logical-ports',
|
||||
data=jsonutils.dumps(resp_body, sort_keys=True))
|
||||
|
||||
def test_create_logical_port_admin_down(self):
|
||||
"""
|
||||
Test creating port with admin_state down
|
||||
|
Loading…
Reference in New Issue
Block a user