]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add missing parameters for port creation
authorSourabh Patwardhan <sopatwar@cisco.com>
Mon, 10 Mar 2014 21:27:26 +0000 (14:27 -0700)
committerSourabh Patwardhan <sopatwar@cisco.com>
Sat, 29 Mar 2014 02:00:53 +0000 (19:00 -0700)
Recent API changes in N1KV controller require parameters such as
subnet id and IP address to handle port creation successfully.
Without these mandatory paramters, the REST call fails.
This patch addresses that by passing in the missing parameters
in the REST body.

Change-Id: I4cec6868051f492b9d1245ab201ff6c1a0837848
Closes-Bug: #1290561

neutron/plugins/cisco/n1kv/n1kv_client.py
neutron/plugins/cisco/n1kv/n1kv_neutron_plugin.py
neutron/tests/unit/cisco/n1kv/fake_client.py [new file with mode: 0755]
neutron/tests/unit/cisco/n1kv/test_n1kv_plugin.py

index 33858f897a9f1363b778a2b3ad04e69b6f56d576..27bab38ae09329212897ca926272c0a9d43b491c 100644 (file)
@@ -383,7 +383,12 @@ class Client(object):
                 'portProfile': policy_profile['name'],
                 'portProfileId': policy_profile['id'],
                 'tenantId': port['tenant_id'],
+                'portId': port['id'],
+                'macAddress': port['mac_address'],
                 }
+        if port.get('fixed_ips'):
+            body['ipAddress'] = port['fixed_ips'][0]['ip_address']
+            body['subnetId'] = port['fixed_ips'][0]['subnet_id']
         return self._post(self.vm_networks_path,
                           body=body)
 
@@ -406,6 +411,7 @@ class Client(object):
                 'macAddress': port['mac_address']}
         if port.get('fixed_ips'):
             body['ipAddress'] = port['fixed_ips'][0]['ip_address']
+            body['subnetId'] = port['fixed_ips'][0]['subnet_id']
         return self._post(self.ports_path % vm_network_name,
                           body=body)
 
index f38db82a4aacd6c1a60b87358de0032e2738eeb1..881fdbbc9788edd0df3ae04aa85a0cd5eb63c1c8 100644 (file)
@@ -885,7 +885,6 @@ class N1kvNeutronPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
             n1kvclient.create_vm_network(port,
                                          vm_network_name,
                                          policy_profile)
-            n1kvclient.create_n1kv_port(port, vm_network_name)
         else:
             vm_network_name = vm_network['name']
             n1kvclient = n1kv_client.Client()
diff --git a/neutron/tests/unit/cisco/n1kv/fake_client.py b/neutron/tests/unit/cisco/n1kv/fake_client.py
new file mode 100755 (executable)
index 0000000..12a36e6
--- /dev/null
@@ -0,0 +1,71 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2014 Cisco Systems, Inc.
+#
+#    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.
+#
+# @author: Abhishek Raut, Cisco Systems Inc.
+# @author: Sourabh Patwardhan, Cisco Systems Inc.
+
+from neutron.openstack.common import log as logging
+from neutron.plugins.cisco.common import cisco_exceptions
+from neutron.plugins.cisco.n1kv.n1kv_client import Client as n1kv_client
+
+LOG = logging.getLogger(__name__)
+
+_resource_metadata = {'port': ['id', 'macAddress', 'ipAddress', 'subnetId'],
+                      'vmnetwork': ['name', 'networkSegmentId',
+                                    'networkSegment', 'portProfile',
+                                    'portProfileId', 'tenantId',
+                                    'portId', 'macAddress',
+                                    'ipAddress', 'subnetId']}
+
+
+class TestClient(n1kv_client):
+
+    def __init__(self, **kwargs):
+        self.broken = False
+        self.inject_params = False
+        super(TestClient, self).__init__()
+
+    def _do_request(self, method, action, body=None, headers=None):
+        if self.broken:
+            raise cisco_exceptions.VSMError(reason='VSM:Internal Server Error')
+        if self.inject_params and body:
+            body['invalidKey'] = 'catchMeIfYouCan'
+        if method == 'POST':
+            return _validate_resource(action, body)
+
+
+class TestClientInvalidRequest(TestClient):
+
+    def __init__(self, **kwargs):
+        super(TestClientInvalidRequest, self).__init__()
+        self.inject_params = True
+
+
+def _validate_resource(action, body=None):
+    if body:
+        body_set = set(body.keys())
+    else:
+        return
+    if 'vm-network' in action and 'port' not in action:
+        vmnetwork_set = set(_resource_metadata['vmnetwork'])
+        if body_set - vmnetwork_set:
+            raise cisco_exceptions.VSMError(reason='Invalid Request')
+    elif 'port' in action:
+        port_set = set(_resource_metadata['port'])
+        if body_set - port_set:
+            raise cisco_exceptions.VSMError(reason='Invalid Request')
+    else:
+        return
index 909df25905a23c22ba48de36538cb6a38bd6dc19..90fb3c4f0d22914b4b3c2f1a05c7e268279a32c8 100644 (file)
@@ -16,6 +16,7 @@
 #
 # @author: Juergen Brendel, Cisco Systems Inc.
 # @author: Abhishek Raut, Cisco Systems Inc.
+# @author: Sourabh Patwardhan, Cisco Systems Inc.
 
 from mock import patch
 from oslo.config import cfg
@@ -33,6 +34,7 @@ from neutron.plugins.cisco.extensions import network_profile
 from neutron.plugins.cisco.n1kv import n1kv_client
 from neutron.plugins.cisco.n1kv import n1kv_neutron_plugin
 from neutron.tests.unit import _test_extension_portbindings as test_bindings
+from neutron.tests.unit.cisco.n1kv import fake_client
 from neutron.tests.unit import test_api_v2
 from neutron.tests.unit import test_db_plugin as test_plugin
 
@@ -344,6 +346,36 @@ class TestN1kvPorts(test_plugin.TestPortsV2,
             # Port update should fail to update policy profile id.
             self.assertEqual(res.status_int, 400)
 
+    def test_create_first_port_invalid_parameters_fail(self):
+        """Test parameters for first port create sent to the VSM."""
+        profile_obj = self._make_test_policy_profile(name='test_profile')
+        with self.network() as network:
+            client_patch = patch(n1kv_client.__name__ + ".Client",
+                                 new=fake_client.TestClientInvalidRequest)
+            client_patch.start()
+            data = {'port': {n1kv.PROFILE_ID: profile_obj.id,
+                             'tenant_id': self.tenant_id,
+                             'network_id': network['network']['id'],
+                             }}
+            port_req = self.new_create_request('ports', data)
+            res = port_req.get_response(self.api)
+            self.assertEqual(res.status_int, 500)
+            client_patch.stop()
+
+    def test_create_next_port_invalid_parameters_fail(self):
+        """Test parameters for subsequent port create sent to the VSM."""
+        with self.port() as port:
+            client_patch = patch(n1kv_client.__name__ + ".Client",
+                                 new=fake_client.TestClientInvalidRequest)
+            client_patch.start()
+            data = {'port': {n1kv.PROFILE_ID: port['port']['n1kv:profile_id'],
+                             'tenant_id': port['port']['tenant_id'],
+                             'network_id': port['port']['network_id']}}
+            port_req = self.new_create_request('ports', data)
+            res = port_req.get_response(self.api)
+            self.assertEqual(res.status_int, 500)
+            client_patch.stop()
+
 
 class TestN1kvNetworks(test_plugin.TestNetworksV2,
                        N1kvPluginTestCase):