]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Merge remote-tracking branch 'origin/feature/qos' into merge-branch
authorIhar Hrachyshka <ihrachys@redhat.com>
Wed, 5 Aug 2015 15:15:40 +0000 (17:15 +0200)
committerIhar Hrachyshka <ihrachys@redhat.com>
Wed, 5 Aug 2015 15:15:40 +0000 (17:15 +0200)
Change-Id: I683102e617202e0ffc953a0d3cc179879f8faf82

20 files changed:
1  2 
doc/source/devref/index.rst
etc/neutron.conf
neutron/agent/common/ovs_lib.py
neutron/cmd/sanity/checks.py
neutron/common/constants.py
neutron/common/exceptions.py
neutron/db/db_base_plugin_common.py
neutron/db/migration/alembic_migrations/versions/liberty/expand/48153cb5f051_qos_db_changes.py
neutron/db/migration/models/head.py
neutron/plugins/ml2/drivers/mech_sriov/agent/pci_lib.py
neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py
neutron/plugins/ml2/plugin.py
neutron/plugins/ml2/rpc.py
neutron/tests/api/base.py
neutron/tests/functional/agent/test_ovs_lib.py
neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_pci_lib.py
neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py
neutron/tests/unit/plugins/ml2/test_rpc.py
requirements.txt
setup.cfg

Simple merge
index ca3baa9cf3262e7753534b7c52aa4d713e9833d2,29a4095f813dfdbfb03b294937a277addf32a59e..52ca260a548fa27437d9817f3c6b6f50ec21c821
mode 100644,100755..100644
Simple merge
index 37f0947f2db31763cc3e710aa91b67532d74b6d5,c3ef8a3c98640009879074738a00c74093305dda..659c02e67462862c161c20f186a2dfdc655f4f16
@@@ -127,9 -127,10 +127,11 @@@ def arp_header_match_supported()
  
  
  def vf_management_supported():
+     is_supported = True
      required_caps = (
          ip_link_support.IpLinkConstants.IP_LINK_CAPABILITY_STATE,
-         ip_link_support.IpLinkConstants.IP_LINK_CAPABILITY_SPOOFCHK)
++        ip_link_support.IpLinkConstants.IP_LINK_CAPABILITY_SPOOFCHK,
+         ip_link_support.IpLinkConstants.IP_LINK_CAPABILITY_RATE)
      try:
          vf_section = ip_link_support.IpLinkSupport.get_vf_mgmt_section()
          for cap in required_caps:
Simple merge
Simple merge
Simple merge
index 0000000000000000000000000000000000000000,940b4def58c956956fbd394d3078babc0de178ef..99f4f1f12b2e5e3bd96f573ad546a07f52158ef6
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,69 +1,69 @@@
 -Revises: 8675309a5c4f
+ # Copyright 2015 Huawei Technologies India Pvt Ltd, 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.
+ #
+ """qos db changes
+ Revision ID: 48153cb5f051
 -down_revision = '8675309a5c4f'
++Revises: 1c844d1677f7
+ Create Date: 2015-06-24 17:03:34.965101
+ """
+ # revision identifiers, used by Alembic.
+ revision = '48153cb5f051'
++down_revision = '1c844d1677f7'
+ from alembic import op
+ import sqlalchemy as sa
+ from neutron.api.v2 import attributes as attrs
+ def upgrade():
+     op.create_table(
+         'qos_policies',
+         sa.Column('id', sa.String(length=36), primary_key=True),
+         sa.Column('name', sa.String(length=attrs.NAME_MAX_LEN)),
+         sa.Column('description', sa.String(length=attrs.DESCRIPTION_MAX_LEN)),
+         sa.Column('shared', sa.Boolean(), nullable=False),
+         sa.Column('tenant_id', sa.String(length=attrs.TENANT_ID_MAX_LEN),
+                   index=True))
+     op.create_table(
+         'qos_network_policy_bindings',
+         sa.Column('policy_id', sa.String(length=36),
+                   sa.ForeignKey('qos_policies.id', ondelete='CASCADE'),
+                   nullable=False),
+         sa.Column('network_id', sa.String(length=36),
+                   sa.ForeignKey('networks.id', ondelete='CASCADE'),
+                   nullable=False, unique=True))
+     op.create_table(
+         'qos_port_policy_bindings',
+         sa.Column('policy_id', sa.String(length=36),
+                   sa.ForeignKey('qos_policies.id', ondelete='CASCADE'),
+                   nullable=False),
+         sa.Column('port_id', sa.String(length=36),
+                   sa.ForeignKey('ports.id', ondelete='CASCADE'),
+                   nullable=False, unique=True))
+     op.create_table(
+         'qos_bandwidth_limit_rules',
+         sa.Column('id', sa.String(length=36), primary_key=True),
+         sa.Column('qos_policy_id', sa.String(length=36),
+                   sa.ForeignKey('qos_policies.id', ondelete='CASCADE'),
+                   nullable=False, unique=True),
+         sa.Column('max_kbps', sa.Integer()),
+         sa.Column('max_burst_kbps', sa.Integer()))
index 8680b06a4f47723a776da017552203eeaad556ff,85aaa6882021f99531058a612e0b86ffa3f7f007..3c3da37b35ea6a92c79ec2620f41b3e0329ca3da
@@@ -41,7 -41,8 +41,8 @@@ from neutron.db import model_bas
  from neutron.db import models_v2  # noqa
  from neutron.db import portbindings_db  # noqa
  from neutron.db import portsecurity_db  # noqa
 -from neutron.db import quota_db  # noqa
+ from neutron.db.qos import models as qos_models  # noqa
 +from neutron.db.quota import models  # noqa
  from neutron.db import rbac_db_models  # noqa
  from neutron.db import securitygroups_db  # noqa
  from neutron.db import servicetype_db  # noqa
index 3e7ec1b1449918f1ed72c867bc9cfa801918b44f,723e4b43d69a95788ff62a682cafcfc08d81241d..a1e31cd66697118eb886e9ec9daa8c9bcdf18580
@@@ -106,22 -106,21 +106,37 @@@ class PciDeviceIPWrapper(ip_lib.IPWrapp
              raise exc.IpCommandError(dev_name=self.dev_name,
                                       reason=e)
  
 +    def set_vf_spoofcheck(self, vf_index, enabled):
 +        """sets vf spoofcheck
 +
 +        @param vf_index: vf index
 +        @param enabled: True to enable spoof checking,
 +                        False to disable
 +        """
 +        setting = "on" if enabled else "off"
 +
 +        try:
 +            self._as_root('', "link", ("set", self.dev_name, "vf",
 +                                       str(vf_index), "spoofchk", setting))
 +        except Exception as e:
 +            raise exc.IpCommandError(dev_name=self.dev_name,
 +                                     reason=str(e))
 +
+     def set_vf_max_rate(self, vf_index, max_tx_rate):
+         """sets vf max rate.
+         @param vf_index: vf index
+         @param max_tx_rate: vf max tx rate
+         """
+         try:
+             self._as_root([], "link", ("set", self.dev_name, "vf",
+                                        str(vf_index), "rate",
+                                        str(max_tx_rate)))
+         except Exception as e:
+             LOG.exception(_LE("Failed executing ip command"))
+             raise exc.IpCommandError(dev_name=self.dev_name,
+                                      reason=e)
      def _get_vf_link_show(self, vf_list, link_show_out):
          """Get link show output for VFs
  
index 7bcf39378ecca8f23d430d6de85a0d17a976516b,aeaf68733a47255a66fc6c1de8a7d4c0b6f77644..55addebe11905db9e00e95f496bc73925f32c142
@@@ -75,7 -75,7 +76,8 @@@ from neutron.plugins.ml2 import driver_
  from neutron.plugins.ml2 import managers
  from neutron.plugins.ml2 import models
  from neutron.plugins.ml2 import rpc
 +from neutron.quota import resource_registry
+ from neutron.services.qos import qos_consts
  
  LOG = log.getLogger(__name__)
  
Simple merge
index 6de00616309aeb8fb6f953fa46cc97e7475ddbc7,30d00b8d6d750dfe08049247570b8b9af0f8ecfa..b8981147a8219cb46ea7e4cb63ceabb27b8e3a6e
@@@ -85,6 -87,9 +85,8 @@@ class BaseNetworkTest(neutron.tests.tem
          cls.metering_label_rules = []
          cls.fw_rules = []
          cls.fw_policies = []
 -        cls.ipsecpolicies = []
+         cls.qos_rules = []
+         cls.qos_policies = []
          cls.ethertype = "IPv" + str(cls._ip_version)
          cls.address_scopes = []
          cls.admin_address_scopes = []
              for fw_rule in cls.fw_rules:
                  cls._try_delete_resource(cls.client.delete_firewall_rule,
                                           fw_rule['id'])
 -            # Clean up ike policies
 -            for ikepolicy in cls.ikepolicies:
 -                cls._try_delete_resource(cls.client.delete_ikepolicy,
 -                                         ikepolicy['id'])
 -            # Clean up vpn services
 -            for vpnservice in cls.vpnservices:
 -                cls._try_delete_resource(cls.client.delete_vpnservice,
 -                                         vpnservice['id'])
+             # Clean up QoS policies
+             for qos_policy in cls.qos_policies:
+                 cls._try_delete_resource(cls.admin_client.delete_qos_policy,
+                                          qos_policy['id'])
+             # Clean up QoS rules
+             for qos_rule in cls.qos_rules:
+                 cls._try_delete_resource(cls.admin_client.delete_qos_rule,
+                                          qos_rule['id'])
              # Clean up floating IPs
              for floating_ip in cls.floating_ips:
                  cls._try_delete_resource(cls.client.delete_floatingip,
index 67ef92de2c4c0f221451259266b4b1fca1f2cb96,38e0eac060d8a81bb86a70936ee236576f1261a3..5512ea95f6b051931ec38c7640fb7cdd0bdb6668
@@@ -111,6 -96,23 +111,23 @@@ class TestPciLib(base.BaseTestCase)
                                 "_execute") as mock_exec:
              mock_exec.side_effect = Exception()
              self.assertRaises(exc.IpCommandError,
 -                              self.pci_wrapper.set_vf_state,
 +                              self.pci_wrapper.set_vf_spoofcheck,
                                self.VF_INDEX,
                                True)
+     def test_set_vf_max_rate(self):
+         with mock.patch.object(self.pci_wrapper, "_as_root") \
+                 as mock_as_root:
+             result = self.pci_wrapper.set_vf_max_rate(self.VF_INDEX, 1000)
+             self.assertIsNone(result)
+         mock_as_root.assert_called_once_with([], "link",
+             ("set", self.DEV_NAME, "vf", str(self.VF_INDEX), "rate", '1000'))
+     def test_set_vf_max_rate_fail(self):
+         with mock.patch.object(self.pci_wrapper,
+                                "_execute") as mock_exec:
+             mock_exec.side_effect = Exception()
+             self.assertRaises(exc.IpCommandError,
+                               self.pci_wrapper.set_vf_max_rate,
+                               self.VF_INDEX,
+                               1000)
index 26a9a30b8f8333272d0962de7e58da5ee727acbf,301a5cf5fb0744456924b8bdca4f20d3a6417032..f1e71843461a99c9b868cc225c720f450d161995
@@@ -402,6 -380,28 +402,29 @@@ class TestOvsNeutronAgent(object)
          self.assertTrue(self._mock_treat_devices_added_updated(
              details, mock.Mock(), 'treat_vif_port'))
  
 -                               'get_devices_details_list',
 -                               return_value=[details]),\
+     def test_treat_devices_added_updated_sends_vif_port_into_extension_manager(
+         self, *args):
+         details = mock.MagicMock()
+         details.__contains__.side_effect = lambda x: True
+         port = mock.MagicMock()
+         def fake_handle_port(context, port):
+             self.assertIn('vif_port', port)
+         with mock.patch.object(self.agent.plugin_rpc,
++                               'get_devices_details_list_and_failed_devices',
++                               return_value={'devices': [details],
++                                             'failed_devices': None}),\
+             mock.patch.object(self.agent.agent_extensions_mgr,
+                               'handle_port', new=fake_handle_port),\
+             mock.patch.object(self.agent.int_br,
+                               'get_vifs_by_ids',
+                               return_value={details['device']: port}),\
+             mock.patch.object(self.agent, 'treat_vif_port',
+                               return_value=False):
+             self.agent.treat_devices_added_or_updated([{}], False)
      def test_treat_devices_added_updated_skips_if_port_not_found(self):
          dev_mock = mock.MagicMock()
          dev_mock.__getitem__.return_value = 'the_skipped_one'
index 72775b9fe800e5cdd115b3918faf03d06566daa2,e039c926137289e314ec2a8988ca658557a46536..5e79eb7619b8b35610a0481b9c626aa2181f2952
@@@ -135,7 -135,35 +136,35 @@@ class RpcCallbacksTestCase(base.BaseTes
          self.callbacks.get_device_details(mock.Mock())
          self.assertTrue(self.plugin.update_port_status.called)
  
 -    def test_get_devices_details_list(self):
+     def test_get_device_details_qos_policy_id_none(self):
+         port = collections.defaultdict(lambda: 'fake_port')
+         self.plugin.get_bound_port_context().current = port
+         self.plugin.get_bound_port_context().network._network = (
+             {"id": "fake_network"})
+         res = self.callbacks.get_device_details(mock.Mock(), host='fake')
+         self.assertIsNone(res['qos_policy_id'])
+     def test_get_device_details_qos_policy_id_inherited_from_network(self):
+         port = collections.defaultdict(lambda: 'fake_port')
+         self.plugin.get_bound_port_context().current = port
+         self.plugin.get_bound_port_context().network._network = (
+             {"id": "fake_network",
+              qos_consts.QOS_POLICY_ID: 'test-policy-id'})
+         res = self.callbacks.get_device_details(mock.Mock(), host='fake')
+         self.assertEqual('test-policy-id', res['qos_policy_id'])
+     def test_get_device_details_qos_policy_id_taken_from_port(self):
+         port = collections.defaultdict(
+             lambda: 'fake_port',
+             {qos_consts.QOS_POLICY_ID: 'test-port-policy-id'})
+         self.plugin.get_bound_port_context().current = port
+         self.plugin.get_bound_port_context().network._network = (
+             {"id": "fake_network",
+              qos_consts.QOS_POLICY_ID: 'test-net-policy-id'})
+         res = self.callbacks.get_device_details(mock.Mock(), host='fake')
+         self.assertEqual('test-port-policy-id', res['qos_policy_id'])
 +    def _test_get_devices_list(self, callback, side_effect, expected):
          devices = [1, 2, 3, 4, 5]
          kwargs = {'host': 'fake_host', 'agent_id': 'fake_agent_id'}
          with mock.patch.object(self.callbacks, 'get_device_details',
Simple merge
diff --cc setup.cfg
index 9cda3e8d214dfd257cb8923f3778296e6f7ec836,b3a3608a44ffb78644fd5121bc4a87c42a0e7fb1..739063a633ab8d5f1f2194e652497a94b7df360b
+++ b/setup.cfg
@@@ -187,6 -196,8 +190,7 @@@ neutron.ml2.extension_drivers 
      test = neutron.tests.unit.plugins.ml2.drivers.ext_test:TestExtensionDriver
      testdb = neutron.tests.unit.plugins.ml2.drivers.ext_test:TestDBExtensionDriver
      port_security = neutron.plugins.ml2.extensions.port_security:PortSecurityExtensionDriver
 -    cisco_n1kv_ext = neutron.plugins.ml2.drivers.cisco.n1kv.n1kv_ext_driver:CiscoN1kvExtensionDriver
+     qos = neutron.plugins.ml2.extensions.qos:QosExtensionDriver
  neutron.openstack.common.cache.backends =
      memory = neutron.openstack.common.cache._backends.memory:MemoryBackend
  neutron.ipam_drivers =