Browse Source

Merge "remove deprecated drivers with out-of-tree alternatives"

Zuul 7 months ago
parent
commit
ea112b1f65

+ 49
- 48
doc/source/user/drivers/index.rst View File

@@ -19,52 +19,53 @@ supported with each driver.
19 19
 Driver Compatibility Matrix
20 20
 ---------------------------
21 21
 
22
-+----------------------------------------------++----------------------------------------------------+
23
-|               API                            ||                        Driver                      |
24
-+---------------------+------------------------++-----------++--------------++--------------++-------+
25
-|      Object         |     Attribute          || Neutron   || OpenContrail || OpenDaylight || Nuage |
26
-|                     |                        || (bagpipe) ||              ||              ||       |
27
-|                     |                        ||           ++-------+------++-------+------++       |
28
-|                     |                        ||           ||v1 [#]_|  v2  ||   v1  |  v2  ||       |
29
-+=====================+========================++===========++=======+======++=======+======++=======+
30
-|      bgpvpn         |    base object         ||   ✔       ||  ✔    |  ✔   ||  ✔    | ✔    ||   ✔   |
31
-+---------------------+-------+----------------++-----------++-------+------++-------+------++-------+
32
-|                     |       |     L3         ||   ✔       ||  ✔    |  ✔   ||  ✔    | ✔    ||   ✔   |
33
-|                     | type  +----------------++-----------++-------+------++-------+------++-------+
34
-|                     |       |     L2         ||   ✔       ||       |  ✔   ||       | ✔    ||       |
35
-|                     +-------+----------------++-----------++-------+------++-------+------++-------+
36
-|                     |    route_targets       ||   ✔       ||  ✔    |  ✔   ||  ✔    | ✔    ||   ✔   |
37
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
38
-|                     |    import_targets      ||   ✔       ||  ✔    |  ✔   ||  ✔    | ✔    ||   ✔   |
39
-|                     +------------------------++-----------++-------+------++-------+------++-------+
40
-|                     |    export_targets      ||   ✔       ||  ✔    |  ✔   ||  ✔    | ✔    ||   ✔   |
41
-|                     +------------------------++-----------++-------+------++-------+------++-------+
42
-|                     | route_distinguishers   ||           ||              ||  ✔    | ✔    ||   ✔   |
43
-|                     +------------------------++-----------++-------+------++-------+------++-------+
44
-|                     |         vni            ||   ✔       ||              ||       | ✔    ||       |
45
-|                     +------------------------++-----------++-------+------++-------+------++-------+
46
-|                     |     local_pref         ||   ✔       ||              ||              ||       |
47
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
48
-| network_association |    base object         ||   ✔       ||  ✔    |  ✔   ||  ✔    | ✔    ||       |
49
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
50
-| router_association  |    base object         ||   ✔       ||       |  ✔   ||  ✔    | ✔    ||   ✔   |
51
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
52
-|                     | advertise_extra_routes ||           ||              || [#]_         ||       |
53
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
54
-| port_association    |    base object         ||   ✔       ||              ||              ||       |
55
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
56
-|                     |  advertise_fixed_ips   ||   ✔       ||              ||              ||       |
57
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
58
-|                     |     routes:prefix      ||   ✔       ||              ||              ||       |
59
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
60
-|                     |     routes:bgpvpn      ||   ✔       ||              ||              ||       |
61
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
62
-|                     |    routes:local_pref   ||   ✔       ||              ||              ||       |
63
-+---------------------+------------------------++-----------++-------+------++-------+------++-------+
22
++----------------------------------------------+-------------------------------------------------+
23
+|               API                            |                        Driver                   |
24
++---------------------+------------------------+-----------+--------------+--------------+-------+
25
+|      Object         |     Attribute          | Neutron   | OpenContrail | OpenDaylight | Nuage |
26
+|                     |                        | (bagpipe) |      [#]_    |      [#]_    |       |
27
++=====================+========================+===========+==============+==============+=======+
28
+|      bgpvpn         |    base object         |   ✔       |       ✔      |       ✔      |   ✔   |
29
++---------------------+-------+----------------+-----------+--------------+--------------+-------+
30
+|                     |       |     L3         |   ✔       |       ✔      |       ✔      |   ✔   |
31
+|                     | type  +----------------+-----------+--------------+--------------+-------+
32
+|                     |       |     L2         |   ✔       |       ✔      |       ✔      |       |
33
+|                     +-------+----------------+-----------+--------------+--------------+-------+
34
+|                     |    route_targets       |   ✔       |       ✔      |       ✔      |   ✔   |
35
++---------------------+------------------------+-----------+--------------+--------------+-------+
36
+|                     |    import_targets      |   ✔       |       ✔      |       ✔      |   ✔   |
37
+|                     +------------------------+-----------+--------------+--------------+-------+
38
+|                     |    export_targets      |   ✔       |       ✔      |       ✔      |   ✔   |
39
+|                     +------------------------+-----------+--------------+--------------+-------+
40
+|                     | route_distinguishers   |           |              |       ✔      |   ✔   |
41
+|                     +------------------------+-----------+--------------+--------------+-------+
42
+|                     |         vni            |   ✔       |              |       ✔      |       |
43
+|                     +------------------------+-----------+--------------+--------------+-------+
44
+|                     |     local_pref         |   ✔       |              |              |       |
45
++---------------------+------------------------+-----------+--------------+--------------+-------+
46
+| network_association |    base object         |   ✔       |       ✔      |       ✔      |       |
47
++---------------------+------------------------+-----------+--------------+--------------+-------+
48
+| router_association  |    base object         |   ✔       |       ✔      |       ✔      |   ✔   |
49
++---------------------+------------------------+-----------+--------------+--------------+-------+
50
+|                     | advertise_extra_routes |           |              |     [#]_     |       |
51
++---------------------+------------------------+-----------+--------------+--------------+-------+
52
+| port_association    |    base object         |   ✔       |              |              |       |
53
++---------------------+------------------------+-----------+--------------+--------------+-------+
54
+|                     |  advertise_fixed_ips   |   ✔       |              |              |       |
55
++---------------------+------------------------+-----------+--------------+--------------+-------+
56
+|                     |     routes:prefix      |   ✔       |              |              |       |
57
++---------------------+------------------------+-----------+--------------+--------------+-------+
58
+|                     |     routes:bgpvpn      |   ✔       |              |              |       |
59
++---------------------+------------------------+-----------+--------------+--------------+-------+
60
+|                     |    routes:local_pref   |   ✔       |              |              |       |
61
++---------------------+------------------------+-----------+--------------+--------------+-------+
64 62
 
65
-.. [#] OpenContrail driver v1 has been deprecated in favor of the production
66
-   ready `driver v2`_. Warning, **no** migration path is planned.
67
-.. [#] The behavior corresponding to advertise_extra_routes ``True``, is
68
-       supported as the default with ODL, for both v1 and v2 drivers,
69
-       without support in the API for turning it off.
70
-.. _driver v2: https://github.com/Juniper/contrail-neutron-plugin/tree/master/neutron_plugin_contrail/plugins/opencontrail/networking_bgpvpn
63
+.. [#] This applies to the `current BGPVPN Contrail driver <https://github.com/Juniper/contrail-neutron-plugin/tree/master/neutron_plugin_contrail/plugins/opencontrail/networking_bgpvpn>`_
64
+       sometimes called *v2 driver*, which is different from the now
65
+       obsolete *v1 driver* that was under ``networking_bgpvpn``.
66
+.. [#] This applies to the `current BGPVPN ODL v2 driver <https://git.openstack.org/cgit/openstack/networking-odl/tree/networking_odl/bgpvpn/odl_v2.py>`_
67
+       sometimes called *v2 driver*, which is different from the now
68
+       obsolete *v1 driver* that was under ``networking_bgpvpn``.
69
+.. [#] The behavior corresponding to ``advertise_extra_routes: true``, is
70
+       supported as the default with ODL, without support in the API for
71
+       turning it off.

+ 6
- 5
doc/source/user/drivers/opencontrail/index.rst View File

@@ -9,11 +9,13 @@ The **OpenContrail** driver for the BGPVPN service plugin is designed to work
9 9
 jointly with the `OpenContrail SDN controller`_ (`GitHub`_). The BGP VPN driver
10 10
 can be found in the `monolithic Neutron plugin tree`__ [#]_.
11 11
 
12
-.. Warning::
12
+.. Note::
13 13
 
14
-   The `old OpenContail driver`_ has been deprecated in Queens release in favor
15
-   of the production ready `driver`_ and plan to be completly removed in Rocky
16
-   release. Be careful, **no** migration path is planned.
14
+   The BGPVPN Contrail driver that was under ``networking_bgpvpn`` (``networking_bgpvpn.neutron.services.service_drivers.opencontrail.opencontrail.OpenContrailBGPVPNDriver``)
15
+   has been deprecated in Queens release, and has been completly removed in
16
+   Stein release. The documentation below refers to the production ready
17
+   `driver`_ under ``Juniper/contrail-neutron-plugin``. Be careful, **no**
18
+   migration path is planned.
17 19
 
18 20
 Limitations
19 21
 -----------
@@ -98,7 +100,6 @@ A `devstack plugin`_ can be used to setup an OpenContrail dev/test platform.
98 100
 .. _GitHub: https://github.com/Juniper/contrail-controller
99 101
 .. _driver: https://github.com/Juniper/contrail-neutron-plugin/tree/master/neutron_plugin_contrail/plugins/opencontrail/networking_bgpvpn
100 102
 __ driver_
101
-.. _old OpenContail driver: https://github.com/openstack/networking-bgpvpn/tree/stable/queens/networking_bgpvpn/neutron/services/service_drivers/opencontrail
102 103
 .. _route distinguisher: https://developer.openstack.org/api-ref/networking/v2/#on-route-distinguishers-rds
103 104
 .. _router associations: https://developer.openstack.org/api-ref/networking/v2/#router-associations
104 105
 .. _network associations: https://developer.openstack.org/api-ref/networking/v2/#network-associations

+ 9
- 1
doc/source/user/drivers/opendaylight/index.rst View File

@@ -9,6 +9,14 @@ OpenDaylight driver requires `networking-odl plugin`_ which comes with its own
9 9
 devstack scripts. Details on how to configure devstack for OpenDaylight
10 10
 plugin can be found at `networking-odl/devstack`_.
11 11
 
12
+.. note::
13
+
14
+   The legacy BGPVPN *v1 driver* for ODL that was hosted in
15
+   ``networking-bgpvpn`` tree (``networking_bgpvpn.neutron.services.service_drivers.opendaylight.odl.OpenDaylightBgpvpnDriver``)
16
+   has been deprecated in Rocky OpenStack release, and removed in Stein
17
+   OpenStack release. The documentation below refers to the newer *v2 driver*
18
+   in the ``networking-odl`` project.
19
+
12 20
 * add the following to local.conf to enable networking-odl plugin:
13 21
 
14 22
   .. code-block:: none
@@ -19,7 +27,7 @@ plugin can be found at `networking-odl/devstack`_.
19 27
 
20 28
   .. code-block:: ini
21 29
 
22
-     NETWORKING_BGPVPN_DRIVER="BGPVPN:OpenDaylight:networking_bgpvpn.neutron.services.service_drivers.opendaylight.odl.OpenDaylightBgpvpnDriver:default"
30
+     NETWORKING_BGPVPN_DRIVER="BGPVPN:OpenDaylight:networking_odl.bgpvpn.odl_v2.OpenDaylightBgpvpnDriver:default"
23 31
 
24 32
 * Run stack.sh:
25 33
 

+ 0
- 9
networking_bgpvpn/neutron/opts.py View File

@@ -13,9 +13,6 @@
13 13
 from neutron.conf.services import provider_configuration
14 14
 from oslo_config import cfg
15 15
 
16
-from networking_bgpvpn.neutron.services.service_drivers.opencontrail \
17
-    import opencontrail_client
18
-
19 16
 
20 17
 def list_service_provider():
21 18
     return [
@@ -35,9 +32,3 @@ _dummy_bgpvpn_provider = ':'.join([
35 32
 def set_service_provider_default():
36 33
     cfg.set_defaults(provider_configuration.serviceprovider_opts,
37 34
                      service_provider=[_dummy_bgpvpn_provider])
38
-
39
-
40
-def list_opencontrail_driver_opts():
41
-    return [
42
-        ('apiserver', opencontrail_client.opencontrail_opts),
43
-    ]

+ 0
- 0
networking_bgpvpn/neutron/services/service_drivers/opencontrail/__init__.py View File


+ 0
- 65
networking_bgpvpn/neutron/services/service_drivers/opencontrail/exceptions.py View File

@@ -1,65 +0,0 @@
1
-# Copyright (C) 2015 Cloudwatt
2
-# All Rights Reserved.
3
-#
4
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
-#    not use this file except in compliance with the License. You may obtain
6
-#    a copy of the License at
7
-#
8
-#         http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-#    Unless required by applicable law or agreed to in writing, software
11
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
-#    License for the specific language governing permissions and limitations
14
-#    under the License.
15
-
16
-from neutron_lib import exceptions as n_exc
17
-
18
-from networking_bgpvpn._i18n import _
19
-
20
-# OpenContrail client API exceptions
21
-
22
-
23
-class OpenContrailAPIFailed(n_exc.NeutronException):
24
-    message = _("Could not reach OpenContrail API server : %(url)s "
25
-                "Exception: %(excption)s.")
26
-
27
-
28
-class OpenContrailAPIError(n_exc.NeutronException):
29
-    message = _('OpenContrail API returned %(status)s %(reason)s')
30
-
31
-
32
-class OpenContrailAPINotSupported(n_exc.BadRequest):
33
-    message = _('OpenContrail API client cannot %(action)s on %(resource)s')
34
-
35
-
36
-class OpenContrailAPIBadFqName(n_exc.BadRequest):
37
-    message = _("Bad fq_name for forming a fq_name to ID request")
38
-
39
-
40
-class OpenContrailAPIBadUUID(n_exc.BadRequest):
41
-    message = _("Bad UUID for forming a UUID to fq_name request")
42
-
43
-
44
-class OpenContrailAPIBadKVAttributes(n_exc.BadRequest):
45
-    message = _("Bad attributes for forming a key/value store request")
46
-
47
-
48
-class OpenContrailAPINotAuthorized(n_exc.NotAuthorized):
49
-    pass
50
-
51
-
52
-class OpenContrailAPINotFound(n_exc.NotFound):
53
-    message = _("%(resource)s %(id)s does not exist")
54
-
55
-
56
-class OpenContrailAPIConflict(n_exc.Conflict):
57
-    message = _("OpenContrail API conflict: %(reason)s")
58
-
59
-
60
-class OpenContrailAPIBadRequest(n_exc.BadRequest):
61
-    message = _("OpenContrail API bad request: %(reason)s")
62
-
63
-
64
-class OpenContrailMalformedUUID(n_exc.BadRequest):
65
-    message = _("Malformed UUID: %(uuid)s")

+ 0
- 431
networking_bgpvpn/neutron/services/service_drivers/opencontrail/opencontrail.py View File

@@ -1,431 +0,0 @@
1
-# Copyright (c) 2015 Cloudwatt.
2
-# All Rights Reserved.
3
-#
4
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
-#    not use this file except in compliance with the License. You may obtain
6
-#    a copy of the License at
7
-#
8
-#         http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-#    Unless required by applicable law or agreed to in writing, software
11
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
-#    License for the specific language governing permissions and limitations
14
-#    under the License.
15
-
16
-import uuid
17
-
18
-from debtcollector import removals
19
-from oslo_log import log
20
-from oslo_serialization import jsonutils
21
-from oslo_utils import uuidutils
22
-
23
-from neutron_lib import exceptions as n_exc
24
-
25
-from networking_bgpvpn.neutron.extensions import bgpvpn as bgpvpn_ext
26
-from networking_bgpvpn.neutron.services.common import constants
27
-from networking_bgpvpn.neutron.services.common import utils
28
-from networking_bgpvpn.neutron.services.service_drivers import driver_api
29
-from networking_bgpvpn.neutron.services.service_drivers.opencontrail import \
30
-    exceptions as oc_exc
31
-from networking_bgpvpn.neutron.services.service_drivers.opencontrail import \
32
-    opencontrail_client
33
-
34
-OPENCONTRAIL_BGPVPN_DRIVER_NAME = 'OpenContrail'
35
-
36
-LOG = log.getLogger(__name__)
37
-
38
-MESSAGE = ("replaced by a new driver which could be found in the Contrail "
39
-           "Neutron monolithic core plugin tree: 'neutron_plugin_contrail."
40
-           "plugins.opencontrail.networking_bgpvpn.contrail."
41
-           "ContrailBGPVPNDriver'")
42
-
43
-
44
-@removals.removed_class('OpenContrailBGPVPNDriver', version='Queens',
45
-                        removal_version='Rocky', message=MESSAGE)
46
-class OpenContrailBGPVPNDriver(driver_api.BGPVPNDriverBase):
47
-    """BGP VPN Service Driver class for OpenContrail."""
48
-
49
-    def __init__(self, service_plugin):
50
-        super(OpenContrailBGPVPNDriver, self).__init__(service_plugin)
51
-        LOG.debug("OpenContrailBGPVPNDriver service_plugin : %s",
52
-                  service_plugin)
53
-
54
-    def _get_opencontrail_api_client(self, context):
55
-        return opencontrail_client.OpenContrailAPIBaseClient()
56
-
57
-    def _locate_rt(self, oc_client, rt_fq_name):
58
-        try:
59
-            rt_uuid = oc_client.fqname_to_id('route-target', rt_fq_name)
60
-        except oc_exc.OpenContrailAPINotFound:
61
-            body = {
62
-                'route-target': {
63
-                    "fq_name": [':'.join(rt_fq_name)]
64
-                }
65
-            }
66
-            rt_uuid = oc_client.create('Route Target', body)['uuid']
67
-
68
-        return rt_uuid
69
-
70
-    def _clean_route_targets(self, oc_client, rts_fq_name):
71
-        for rt_fq_name in rts_fq_name:
72
-            try:
73
-                rt_uuid = oc_client.fqname_to_id('route-target', rt_fq_name)
74
-            except oc_exc.OpenContrailAPINotFound:
75
-                continue
76
-
77
-            rt = oc_client.show('Route Target', rt_uuid)
78
-            if 'routing_instance_back_refs' not in rt.keys():
79
-                # rt not use anymore, remove it
80
-                rt = oc_client.remove('Route Target', rt_uuid)
81
-
82
-    def _update_rt_ri_association(self, oc_client, operation, ri_id,
83
-                                  rt_fq_name, import_export=None):
84
-        rt_uuid = self._locate_rt(oc_client, rt_fq_name)
85
-
86
-        kwargs = {
87
-            "operation": operation,
88
-            "resource_type": "routing-instance",
89
-            "resource_uuid": ri_id,
90
-            "ref_type": "route-target",
91
-            "ref_fq_name": rt_fq_name,
92
-            "ref_uuid": rt_uuid,
93
-            "attributes": {
94
-                "import_export": import_export
95
-            }
96
-        }
97
-        oc_client.ref_update(**kwargs)
98
-
99
-        if operation == 'DELETE':
100
-            self._clean_route_targets(oc_client, [rt_fq_name])
101
-
102
-    def _get_ri_id_of_network(self, oc_client, network_id):
103
-        try:
104
-            network = oc_client.show('Virtual Network', network_id)
105
-            ri_fq_name = network['fq_name'] + [network['fq_name'][-1]]
106
-            for ri_ref in network.get('routing_instances', []):
107
-                if ri_ref['to'] == ri_fq_name:
108
-                    return ri_ref['uuid']
109
-        except (oc_exc.OpenContrailAPINotFound, IndexError):
110
-            raise n_exc.NetworkNotFound(net_id=network_id)
111
-        raise n_exc.NetworkNotFound(net_id=network_id)
112
-
113
-    def _set_bgpvpn_association(self, oc_client, operation, bgpvpn,
114
-                                networks=None):
115
-        if networks is None:
116
-            networks = []
117
-        for network_id in networks:
118
-            try:
119
-                net_ri_id = self._get_ri_id_of_network(oc_client, network_id)
120
-            except n_exc.NetworkNotFound:
121
-                LOG.info("Network %s not found, cleanup route targets",
122
-                         network_id)
123
-                rts_fq_name = (bgpvpn['route_targets'] +
124
-                               bgpvpn['import_targets'] +
125
-                               bgpvpn['export_targets'])
126
-                rts_fq_name = [['target'] + rt.split(':') for rt in
127
-                               rts_fq_name]
128
-                self._clean_route_targets(oc_client, rts_fq_name)
129
-                return bgpvpn
130
-            if bgpvpn['type'] == constants.BGPVPN_L3:
131
-                for rt in bgpvpn['route_targets']:
132
-                    rt_fq_name = ['target'] + rt.split(':')
133
-                    self._update_rt_ri_association(oc_client, operation,
134
-                                                   net_ri_id, rt_fq_name)
135
-
136
-                for rt in bgpvpn['import_targets']:
137
-                    rt_fq_name = ['target'] + rt.split(':')
138
-                    self._update_rt_ri_association(oc_client, operation,
139
-                                                   net_ri_id, rt_fq_name,
140
-                                                   import_export="import")
141
-
142
-                for rt in bgpvpn['export_targets']:
143
-                    rt_fq_name = ['target'] + rt.split(':')
144
-                    self._update_rt_ri_association(oc_client, operation,
145
-                                                   net_ri_id, rt_fq_name,
146
-                                                   import_export="export")
147
-
148
-        return bgpvpn
149
-
150
-    # Check if tenant ID exists by reading it from the Contrail API;
151
-    # if not, it sends an exception
152
-    def _check_tenant_id(self, oc_client, tenant_id):
153
-        try:
154
-            tenant_id = str(uuid.UUID(tenant_id))
155
-        except ValueError:
156
-            raise oc_exc.OpenContrailMalformedUUID(uuid=tenant_id)
157
-        oc_client.show('Project', tenant_id)
158
-
159
-    def create_bgpvpn(self, context, bgpvpn):
160
-        LOG.debug("create_bgpvpn_ called with %s" % bgpvpn)
161
-
162
-        # Only support l3 technique
163
-        if not bgpvpn['type']:
164
-            bgpvpn['type'] = constants.BGPVPN_L3
165
-        elif bgpvpn['type'] != constants.BGPVPN_L3:
166
-            raise bgpvpn_ext.BGPVPNTypeNotSupported(
167
-                driver=OPENCONTRAIL_BGPVPN_DRIVER_NAME, type=bgpvpn['type'])
168
-
169
-        # Does not support to set route distinguisher
170
-        if 'route_distinguishers' in bgpvpn and bgpvpn['route_distinguishers']:
171
-            raise bgpvpn_ext.BGPVPNRDNotSupported(
172
-                driver=OPENCONTRAIL_BGPVPN_DRIVER_NAME)
173
-
174
-        oc_client = self._get_opencontrail_api_client(context)
175
-
176
-        # Check if tenant ID exists;
177
-        # if not, it sends an exception
178
-        self._check_tenant_id(oc_client, bgpvpn['tenant_id'])
179
-
180
-        bgpvpn['id'] = uuidutils.generate_uuid()
181
-
182
-        oc_client.kv_store('STORE', key=bgpvpn['id'], value={'bgpvpn': bgpvpn})
183
-
184
-        return utils.make_bgpvpn_dict(bgpvpn)
185
-
186
-    def get_bgpvpns(self, context, filters=None, fields=None):
187
-        LOG.debug("get_bgpvpns called, fields = %s, filters = %s"
188
-                  % (fields, filters))
189
-
190
-        oc_client = self._get_opencontrail_api_client(context)
191
-
192
-        bgpvpns = []
193
-        for kv_dict in oc_client.kv_store('RETRIEVE'):
194
-            try:
195
-                value = jsonutils.loads(kv_dict['value'])
196
-            except ValueError:
197
-                continue
198
-            if (isinstance(value, dict) and
199
-                    'bgpvpn' in value and
200
-                    utils.filter_resource(value['bgpvpn'], filters)):
201
-                bgpvpn = value['bgpvpn']
202
-                if not fields or 'networks' in fields:
203
-                    bgpvpn['networks'] = \
204
-                        [net_assoc['network_id'] for net_assoc in
205
-                         self.get_net_assocs(context, bgpvpn['id'])]
206
-                bgpvpns.append(utils.make_bgpvpn_dict(bgpvpn, fields))
207
-
208
-        return bgpvpns
209
-
210
-    def _clean_bgpvpn_assoc(self, oc_client, bgpvpn_id):
211
-        for kv_dict in oc_client.kv_store('RETRIEVE'):
212
-            try:
213
-                value = jsonutils.loads(kv_dict['value'])
214
-            except ValueError:
215
-                continue
216
-            if (isinstance(value, dict) and
217
-                    'bgpvpn_net_assoc' in value and
218
-                    value['bgpvpn_net_assoc']['bgpvpn_id'] == bgpvpn_id):
219
-                assoc_id = value['bgpvpn_net_assoc']['id']
220
-                oc_client.kv_store('DELETE', key=assoc_id)
221
-
222
-    def get_bgpvpn(self, context, id, fields=None):
223
-        LOG.debug("get_bgpvpn called for id %s with fields = %s"
224
-                  % (id, fields))
225
-
226
-        oc_client = self._get_opencontrail_api_client(context)
227
-
228
-        try:
229
-            bgpvpn = jsonutils.loads(oc_client.kv_store('RETRIEVE', key=id))
230
-        except (oc_exc.OpenContrailAPINotFound, ValueError):
231
-            raise bgpvpn_ext.BGPVPNNotFound(id=id)
232
-
233
-        if (not isinstance(bgpvpn, dict) or 'bgpvpn' not in bgpvpn):
234
-            raise bgpvpn_ext.BGPVPNNotFound(id=id)
235
-
236
-        bgpvpn = bgpvpn['bgpvpn']
237
-        if not fields or 'networks' in fields:
238
-            bgpvpn['networks'] = [net_assoc['network_id'] for net_assoc in
239
-                                  self.get_net_assocs(context, id)]
240
-        return utils.make_bgpvpn_dict(bgpvpn, fields)
241
-
242
-    def update_bgpvpn(self, context, id, new_bgpvpn):
243
-        LOG.debug("update_bgpvpn called with %s for %s" % (new_bgpvpn, id))
244
-
245
-        oc_client = self._get_opencontrail_api_client(context)
246
-
247
-        old_bgpvpn = self.get_bgpvpn(context, id)
248
-        networks = old_bgpvpn.get('networks', [])
249
-        bgpvpn = old_bgpvpn.copy()
250
-        bgpvpn.update(new_bgpvpn)
251
-
252
-        (added_keys, removed_keys, changed_keys) = \
253
-            utils.get_bgpvpn_differences(bgpvpn, old_bgpvpn)
254
-        if not (added_keys or removed_keys or changed_keys):
255
-            return utils.make_bgpvpn_dict(bgpvpn)
256
-
257
-        # Does not support to update route distinguisher
258
-        if 'route_distinguishers' in added_keys | removed_keys | changed_keys:
259
-            raise bgpvpn_ext.BGPVPNRDNotSupported(
260
-                driver=OPENCONTRAIL_BGPVPN_DRIVER_NAME)
261
-
262
-        rt_keys = set(['route_targets',
263
-                       'import_targets',
264
-                       'export_targets'])
265
-
266
-        if (rt_keys & added_keys or
267
-                rt_keys & changed_keys or
268
-                rt_keys & removed_keys):
269
-            self._set_bgpvpn_association(oc_client, 'DELETE', old_bgpvpn,
270
-                                         networks)
271
-            self._set_bgpvpn_association(oc_client, 'ADD', bgpvpn, networks)
272
-
273
-        oc_client.kv_store('STORE', key=id, value={'bgpvpn': bgpvpn})
274
-        return utils.make_bgpvpn_dict(bgpvpn)
275
-
276
-    def delete_bgpvpn(self, context, id):
277
-        LOG.debug("delete_bgpvpn called for id %s" % id)
278
-
279
-        bgpvpn = self.get_bgpvpn(context, id)
280
-        networks = bgpvpn.get('networks', [])
281
-        oc_client = self._get_opencontrail_api_client(context)
282
-
283
-        self._set_bgpvpn_association(oc_client, 'DELETE', bgpvpn, networks)
284
-        self._clean_bgpvpn_assoc(oc_client, id)
285
-        oc_client.kv_store('DELETE', key=id)
286
-
287
-    def create_net_assoc(self, context, bgpvpn_id, network_association):
288
-        LOG.debug("create_net_assoc called for bgpvpn %s with network %s"
289
-                  % (bgpvpn_id, network_association['network_id']))
290
-
291
-        bgpvpn = self.get_bgpvpn(context, bgpvpn_id)
292
-        oc_client = self._get_opencontrail_api_client(context)
293
-
294
-        network_id = network_association['network_id']
295
-        if network_id not in bgpvpn.get('networks', []):
296
-            assoc_uuid = uuidutils.generate_uuid()
297
-            self._set_bgpvpn_association(oc_client, 'ADD', bgpvpn,
298
-                                         [network_id])
299
-
300
-            assoc_dict = utils.make_net_assoc_dict(
301
-                assoc_uuid, network_association['tenant_id'],
302
-                bgpvpn_id, network_association['network_id'])
303
-            oc_client.kv_store('STORE', key=assoc_uuid,
304
-                               value={'bgpvpn_net_assoc': assoc_dict})
305
-            return assoc_dict
306
-        else:
307
-            # the tuple (bgpvpn_id, network_id) is necessarily unique
308
-            return self.get_net_assocs(context, bgpvpn_id,
309
-                                       filters={'network_id': network_id})[0]
310
-
311
-    def get_net_assoc(self, context, assoc_id, bgpvpn_id, fields=None):
312
-        LOG.debug("get_net_assoc called for %s for BGPVPN %s, with fields = %s"
313
-                  % (assoc_id, bgpvpn_id, fields))
314
-
315
-        oc_client = self._get_opencontrail_api_client(context)
316
-
317
-        try:
318
-            net_assoc = jsonutils.loads(
319
-                oc_client.kv_store('RETRIEVE', key=assoc_id))
320
-        except (oc_exc.OpenContrailAPINotFound, ValueError):
321
-            raise bgpvpn_ext.BGPVPNNetAssocNotFound(id=assoc_id,
322
-                                                    bgpvpn_id=bgpvpn_id)
323
-
324
-        if (not isinstance(net_assoc, dict) or
325
-                'bgpvpn_net_assoc' not in net_assoc):
326
-            raise bgpvpn_ext.BGPVPNNetAssocNotFound(id=assoc_id,
327
-                                                    bgpvpn_id=bgpvpn_id)
328
-        net_assoc = net_assoc['bgpvpn_net_assoc']
329
-
330
-        if net_assoc['bgpvpn_id'] != bgpvpn_id:
331
-            raise bgpvpn_ext.BGPVPNNetAssocNotFound(id=assoc_id,
332
-                                                    bgpvpn_id=bgpvpn_id)
333
-
334
-        # It the bgpvpn was deleted, the 'get_bgpvpn' will clean all related
335
-        # associations and replaces BGPVPNNotFound by a BGPVPNNetAssocNotFound
336
-        try:
337
-            get_fields = ['tenant_id', 'route_targets', 'import_targets',
338
-                          'export_targets']
339
-            bgpvpn = self.get_bgpvpn(context, net_assoc['bgpvpn_id'],
340
-                                     fields=get_fields)
341
-        except bgpvpn_ext.BGPVPNNotFound:
342
-            raise bgpvpn_ext.BGPVPNNetAssocNotFound(id=assoc_id,
343
-                                                    bgpvpn_id=bgpvpn_id)
344
-
345
-        # If the network was delete all bgpvpn related association should be
346
-        # deleted also
347
-        try:
348
-            oc_client.id_to_fqname(net_assoc['network_id'])
349
-        except oc_exc.OpenContrailAPINotFound:
350
-            self._set_bgpvpn_association(oc_client, 'DELETE', bgpvpn,
351
-                                         [net_assoc['network_id']])
352
-            oc_client.kv_store('DELETE', key=assoc_id)
353
-            raise bgpvpn_ext.BGPVPNNetAssocNotFound(id=assoc_id,
354
-                                                    bgpvpn_id=bgpvpn_id)
355
-
356
-        net_assoc = utils.make_net_assoc_dict(net_assoc['id'],
357
-                                              net_assoc['tenant_id'],
358
-                                              net_assoc['bgpvpn_id'],
359
-                                              net_assoc['network_id'],
360
-                                              fields)
361
-        return net_assoc
362
-
363
-    def get_net_assocs(self, context, bgpvpn_id, filters=None, fields=None):
364
-        LOG.debug("get_net_assocs called for bgpvpn %s, fields = %s, "
365
-                  "filters = %s" % (bgpvpn_id, fields, filters))
366
-
367
-        oc_client = self._get_opencontrail_api_client(context)
368
-
369
-        get_fields = ['tenant_id', 'route_targets', 'import_targets',
370
-                      'export_targets']
371
-        bgpvpn = self.get_bgpvpn(context, bgpvpn_id, fields=get_fields)
372
-
373
-        bgpvpn_net_assocs = []
374
-        for kv_dict in oc_client.kv_store('RETRIEVE'):
375
-            try:
376
-                value = jsonutils.loads(kv_dict['value'])
377
-            except ValueError:
378
-                continue
379
-            if (isinstance(value, dict) and
380
-                    'bgpvpn_net_assoc' in value and
381
-                    utils.filter_resource(value['bgpvpn_net_assoc'],
382
-                                          filters) and
383
-                    value['bgpvpn_net_assoc']['bgpvpn_id'] == bgpvpn_id):
384
-                net_assoc = value['bgpvpn_net_assoc']
385
-                # If the network was delete all bgpvpn related association
386
-                # should be deleted also
387
-                try:
388
-                    oc_client.id_to_fqname(net_assoc['network_id'])
389
-                except oc_exc.OpenContrailAPINotFound:
390
-                    self._set_bgpvpn_association(oc_client, 'DELETE', bgpvpn,
391
-                                                 [net_assoc['network_id']])
392
-                    oc_client.kv_store('DELETE', key=net_assoc['id'])
393
-                    continue
394
-                net_assoc = utils.make_net_assoc_dict(net_assoc['id'],
395
-                                                      net_assoc['tenant_id'],
396
-                                                      net_assoc['bgpvpn_id'],
397
-                                                      net_assoc['network_id'],
398
-                                                      fields)
399
-                bgpvpn_net_assocs.append(net_assoc)
400
-
401
-        return bgpvpn_net_assocs
402
-
403
-    def delete_net_assoc(self, context, assoc_id, bgpvpn_id):
404
-        LOG.debug("delete_net_assoc called for %s" % assoc_id)
405
-        net_assoc = self.get_net_assoc(context, assoc_id, bgpvpn_id)
406
-        fields = ['type', 'route_targets', 'import_targets', 'export_targets']
407
-        bgpvpn = self.get_bgpvpn(context, net_assoc['bgpvpn_id'],
408
-                                 fields=fields)
409
-        oc_client = self._get_opencontrail_api_client(context)
410
-
411
-        self._set_bgpvpn_association(oc_client, 'DELETE', bgpvpn,
412
-                                     [net_assoc['network_id']])
413
-        oc_client.kv_store('DELETE', key=assoc_id)
414
-
415
-        return net_assoc
416
-
417
-    def create_router_assoc(self, context, bgpvpn_id, router_association):
418
-        raise bgpvpn_ext.BGPVPNRouterAssociationNotSupported(
419
-            driver=OPENCONTRAIL_BGPVPN_DRIVER_NAME)
420
-
421
-    def get_router_assoc(self, context, assoc_id, bgpvpn_id, fields=None):
422
-        raise bgpvpn_ext.BGPVPNRouterAssociationNotSupported(
423
-            driver=OPENCONTRAIL_BGPVPN_DRIVER_NAME)
424
-
425
-    def get_router_assocs(self, context, bgpvpn_id, filters=None, fields=None):
426
-        raise bgpvpn_ext.BGPVPNRouterAssociationNotSupported(
427
-            driver=OPENCONTRAIL_BGPVPN_DRIVER_NAME)
428
-
429
-    def delete_router_assoc(self, context, assoc_id, bgpvpn_id):
430
-        raise bgpvpn_ext.BGPVPNRouterAssociationNotSupported(
431
-            driver=OPENCONTRAIL_BGPVPN_DRIVER_NAME)

+ 0
- 359
networking_bgpvpn/neutron/services/service_drivers/opencontrail/opencontrail_client.py View File

@@ -1,359 +0,0 @@
1
-# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
2
-# All Rights Reserved.
3
-#
4
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
-#    not use this file except in compliance with the License. You may obtain
6
-#    a copy of the License at
7
-#
8
-#         http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-#    Unless required by applicable law or agreed to in writing, software
11
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
-#    License for the specific language governing permissions and limitations
14
-#    under the License.
15
-
16
-from networking_bgpvpn._i18n import _
17
-from networking_bgpvpn.neutron.services.service_drivers.opencontrail import \
18
-    exceptions as oc_exc
19
-
20
-from oslo_config import cfg
21
-from oslo_log import log
22
-from oslo_serialization import jsonutils
23
-from oslo_utils import uuidutils
24
-
25
-import requests
26
-from six.moves import http_client as httplib
27
-from six.moves.urllib import parse as urlparse
28
-
29
-LOG = log.getLogger(__name__)
30
-
31
-CONF = cfg.CONF
32
-opencontrail_opts = [
33
-    cfg.IntOpt('request_timeout', default=30,
34
-               help='Timeout seconds for HTTP requests. Set it to None to '
35
-                    'disable timeout.'),
36
-]
37
-CONF.register_opts(opencontrail_opts, 'APISERVER')
38
-
39
-
40
-def get_auth_token():
41
-    DEFAULT_HEADERS = {
42
-        'Content-type': 'application/json; charset="UTF-8"',
43
-        'X-Contrail-Useragent': 'bgppn_opencontrail_client',
44
-    }
45
-    admin_user = cfg.CONF.keystone_authtoken.admin_user
46
-    admin_password = cfg.CONF.keystone_authtoken.admin_password
47
-    admin_tenant_name = cfg.CONF.keystone_authtoken.admin_tenant_name
48
-    auth_body = {
49
-        "auth": {
50
-            "passwordCredentials": {
51
-                "username": admin_user,
52
-                "password": admin_password
53
-            },
54
-            "tenantName": admin_tenant_name
55
-        }
56
-    }
57
-    try:
58
-        auth_type = CONF.keystone_authtoken.auth_type
59
-    except cfg.NoSuchOptError:
60
-        auth_type = "keystone"
61
-    if auth_type != "keystone":
62
-        return
63
-    try:
64
-        auth_url = cfg.CONF.keystone_authtoken.auth_url
65
-    except cfg.NoSuchOptError:
66
-        try:
67
-            auth_host = cfg.CONF.keystone_authtoken.auth_host
68
-        except cfg.NoSuchOptError:
69
-            auth_host = "127.0.0.1"
70
-        try:
71
-            auth_protocol = cfg.CONF.keystone_authtoken.auth_protocol
72
-        except cfg.NoSuchOptError:
73
-            auth_protocol = "http"
74
-        try:
75
-            auth_port = cfg.CONF.keystone_authtoken.auth_port
76
-        except cfg.NoSuchOptError:
77
-            auth_port = "35357"
78
-        auth_url = "%s://%s:%s" % (auth_protocol, auth_host, auth_port)
79
-    url = auth_url + '/v2.0/tokens'
80
-    response = requests.post(url, data=jsonutils.dumps(auth_body),
81
-                             headers=DEFAULT_HEADERS)
82
-
83
-    if response.status_code == 200:
84
-        auth_content = jsonutils.loads(response.text)
85
-        return auth_content['access']['token']['id']
86
-    else:
87
-        raise RuntimeError(_("Authentication failure. Code: %(code)d, "
88
-                             "reason: %(reason)s")
89
-                           % {'code': response.status_code,
90
-                              'reason': response.reason})
91
-
92
-
93
-class RequestHandler(object):
94
-    """Handles processing requests."""
95
-
96
-    def __init__(self):
97
-        self._host = CONF.APISERVER.api_server_ip
98
-        self._port = CONF.APISERVER.api_server_port
99
-        self._request_timeout = float(CONF.APISERVER.request_timeout)
100
-        self._api_url = 'http://' + self._host + ':' + str(self._port)
101
-        self._token = get_auth_token()
102
-
103
-        self._pool = requests.Session()
104
-        self._resource = ""
105
-        self._id = ""
106
-
107
-    def delete(self, url, body=None, headers=None, params=None):
108
-        return self._do_request("DELETE", url, body=body,
109
-                                headers=headers, params=params)
110
-
111
-    def get(self, url, body=None, headers=None, params=None):
112
-        return self._do_request("GET", url, body=body,
113
-                                headers=headers, params=params)
114
-
115
-    def post(self, url, body=None, headers=None, params=None):
116
-        return self._do_request("POST", url, body=body,
117
-                                headers=headers, params=params)
118
-
119
-    def put(self, url, body=None, headers=None, params=None):
120
-        return self._do_request("PUT", url, body=body,
121
-                                headers=headers, params=params)
122
-
123
-    def _do_request(self, method, url, body=None, headers=None,
124
-                    params=None, retry_auth=True):
125
-        req_params = self._get_req_params(data=body)
126
-        if headers:
127
-            req_params['headers'].update(headers)
128
-
129
-        url = urlparse.urljoin(self._api_url, url)
130
-        if params and isinstance(params, dict):
131
-            url += '?' + urlparse.urlencode(params, doseq=1)
132
-
133
-        if url[-1] == '/':
134
-            url = url[:-1]
135
-
136
-        self._log_req(method, url, params, req_params)
137
-
138
-        try:
139
-            response = self._pool.request(method, url, **req_params)
140
-        except Exception as e:
141
-            raise oc_exc.OpenContrailAPIFailed(url=url, excption=e)
142
-
143
-        self._log_res(response)
144
-
145
-        if response.status_code == httplib.UNAUTHORIZED and retry_auth:
146
-            self._auth_token = get_auth_token()
147
-            return self._do_request(method, url, body=body, headers=headers,
148
-                                    params=params, retry_auth=False)
149
-        if response.status_code == httplib.UNAUTHORIZED and not retry_auth:
150
-            raise oc_exc.OpenContrailAPINotAuthorized
151
-
152
-        if response.status_code == httplib.NOT_FOUND:
153
-            raise oc_exc.OpenContrailAPINotFound(resource=self._resource,
154
-                                                 id=self._id)
155
-
156
-        if response.status_code == httplib.CONFLICT:
157
-            raise oc_exc.OpenContrailAPIConflict(reason=response.reason)
158
-
159
-        if response.status_code == httplib.BAD_REQUEST:
160
-            raise oc_exc.OpenContrailAPIBadRequest(reason=response.reason)
161
-
162
-        if response.status_code is not httplib.OK:
163
-            raise oc_exc.OpenContrailAPIError(status=response.status_code,
164
-                                              reason=response.reason)
165
-
166
-        if response.content:
167
-            return response.json()
168
-
169
-    def _get_req_params(self, data=None):
170
-        req_params = {
171
-            'headers': {
172
-                'Content-type': 'application/json; charset="UTF-8"',
173
-                'Accept': "application/json",
174
-                'X-Auth-Token': self._token,
175
-            },
176
-            'allow_redirects': False,
177
-            'timeout': self._request_timeout,
178
-        }
179
-
180
-        if data:
181
-            req_params.update({'data': jsonutils.dumps(data)})
182
-
183
-        return req_params
184
-
185
-    @staticmethod
186
-    def _log_req(method, url, params, req_params):
187
-        if not CONF.debug:
188
-            return
189
-
190
-        curl_command = ['REQ: curl -i -X %s ' % method]
191
-
192
-        if params and isinstance(params, dict):
193
-            url += '?' + urlparse.urlencode(params, doseq=1)
194
-
195
-        curl_command.append('"%s" ' % url)
196
-
197
-        for name, value in req_params['headers'].items():
198
-            curl_command.append('-H "%s: %s" ' % (name, value))
199
-
200
-        if ('data' in req_params.keys()
201
-            and (isinstance(req_params['data'], dict)
202
-                 or isinstance(req_params['data'], str))):
203
-            curl_command.append("-d '%s'" % (req_params['data']))
204
-
205
-        LOG.debug(''.join(curl_command))
206
-
207
-    @staticmethod
208
-    def _log_res(resp):
209
-        if CONF.debug:
210
-            dump = ['RES: \n', 'HTTP %.1f %s %s\n' % (resp.raw.version,
211
-                                                      resp.status_code,
212
-                                                      resp.reason)]
213
-            dump.extend('%s: %s\n' % (k, v)
214
-                        for k, v in (resp.headers).items())
215
-            dump.append('\n')
216
-            if resp.content:
217
-                dump.extend([resp.content, '\n'])
218
-
219
-            LOG.debug(''.join(dump))
220
-
221
-
222
-class OpenContrailAPIBaseClient(RequestHandler):
223
-    """OpenContrail Base REST API Client."""
224
-
225
-    resource_path = {
226
-        'FQName to ID': '/fqname-to-id/',
227
-        'ID to FQName': '/id-to-fqname/',
228
-        'Ref Update': "/ref-update/",
229
-        'Virtual Network': '/virtual-networks/',
230
-        'Routing Instance': '/routing-instances/',
231
-        'Route Target': '/route-targets/',
232
-        'Key Value Store': '/useragent-kv/',
233
-        'Project': '/projects/'
234
-    }
235
-
236
-    def list(self, resource, **params):
237
-        """Fetches a list of resources."""
238
-
239
-        res = self.resource_path.get(resource, None)
240
-        if not res:
241
-            raise oc_exc.OpenContrailAPINotSupported(action='list',
242
-                                                     resource=resource)
243
-
244
-        self._resource = resource
245
-        return self.get(res, params=params)
246
-
247
-    def show(self, resource, id, **params):
248
-        """Fetches information of a certain resource."""
249
-
250
-        res = self.resource_path.get(resource, None)
251
-        if not res:
252
-            raise oc_exc.OpenContrailAPINotSupported(action='show',
253
-                                                     resource=resource)
254
-
255
-        if res[-2:] == 's/':
256
-            res = res[:-2] + '/'
257
-
258
-        self._resource = resource
259
-        self._id = id
260
-        return self.get(res + id, params=params).popitem()[1]
261
-
262
-    def create(self, resource, body):
263
-        """Creates a new resource."""
264
-
265
-        res = self.resource_path.get(resource, None)
266
-        if not res:
267
-            raise oc_exc.OpenContrailAPINotSupported(action='create',
268
-                                                     resource=resource)
269
-
270
-        self._resource = resource
271
-        resp = self.post(res, body=body)
272
-        if resp:
273
-            return resp.popitem()[1]
274
-
275
-    def update(self, resource, id, body=None):
276
-        """Updates a resource."""
277
-
278
-        res = self.resource_path.get(resource, None)
279
-        if not res:
280
-            raise oc_exc.OpenContrailAPINotSupported(action='update',
281
-                                                     resource=resource)
282
-
283
-        if res[-2:] == 's/':
284
-            res = res[:-2] + '/'
285
-
286
-        self._resource = resource
287
-        self._id = id
288
-        return self.put(res + id, body=body)
289
-
290
-    def remove(self, resource, id):
291
-        """Removes the specified resource."""
292
-
293
-        res = self.resource_path.get(resource, None)
294
-        if not res:
295
-            raise oc_exc.OpenContrailAPINotSupported(action='delete',
296
-                                                     resource=resource)
297
-
298
-        if res[-2:] == 's/':
299
-            res = res[:-2] + '/'
300
-
301
-        self._resource = resource
302
-        self._id = id
303
-        return self.delete(res + id)
304
-
305
-    def fqname_to_id(self, resource, fq_name):
306
-        """Get UUID resource from an OpenContrail fq_name"""
307
-
308
-        if not isinstance(fq_name, list):
309
-            raise oc_exc.OpenContrailAPIBadFqName
310
-
311
-        body = {'fq_name': fq_name, 'type': resource}
312
-
313
-        return self.create('FQName to ID', body)
314
-
315
-    def id_to_fqname(self, id):
316
-        """Get fq_name resource from an OpenContrail UUID"""
317
-
318
-        if not uuidutils.is_uuid_like(id):
319
-            raise oc_exc.OpenContrailAPIBadUUID
320
-
321
-        body = {'uuid': id}
322
-
323
-        return self.create('ID to FQName', body)
324
-
325
-    def ref_update(self, operation, resource_uuid, resource_type, ref_type,
326
-                   ref_fq_name, ref_uuid, attributes=None):
327
-        """Updates a resource refference"""
328
-
329
-        body = {
330
-            "operation": operation,
331
-            "type": resource_type,
332
-            "uuid": resource_uuid,
333
-            "ref-type": ref_type,
334
-            "ref-fq-name": ref_fq_name,
335
-            "ref-uuid": ref_uuid,
336
-        }
337
-        if attributes and isinstance(attributes, dict):
338
-            body.update({'attr': attributes})
339
-
340
-        return self.create('Ref Update', body)
341
-
342
-    def kv_store(self, operation, key=None, value=None):
343
-        """Use key/value store exposed by the OpenContrail API"""
344
-
345
-        body = {
346
-            'operation': operation,
347
-            'key': None,
348
-        }
349
-
350
-        if operation == 'RETRIEVE' and not key:
351
-            pass
352
-        elif operation in ['RETRIEVE', 'DELETE'] and key:
353
-            body.update({'key': key})
354
-        elif operation == 'STORE' and key and value:
355
-            body.update({'key': key, 'value': jsonutils.dumps(value)})
356
-        else:
357
-            raise oc_exc.OpenContrailAPIBadKVAttributes
358
-
359
-        return self.create('Key Value Store', body)

+ 0
- 0
networking_bgpvpn/neutron/services/service_drivers/opendaylight/__init__.py View File


+ 0
- 127
networking_bgpvpn/neutron/services/service_drivers/opendaylight/odl.py View File

@@ -1,127 +0,0 @@
1
-#
2
-# Copyright (C) 2015 Ericsson India Global Services Pvt Ltd.
3
-#
4
-#  Licensed under the Apache License, Version 2.0 (the "License"); you may
5
-#  not use this file except in compliance with the License. You may obtain
6
-#  a copy of the License at
7
-#
8
-#       http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-#  Unless required by applicable law or agreed to in writing, software
11
-#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
-#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
-#  License for the specific language governing permissions and limitations
14
-#  under the License.
15
-#
16
-
17
-import requests
18
-
19
-from oslo_config import cfg
20
-from oslo_log import log as logging
21
-from oslo_utils import excutils
22
-
23
-from networking_odl.common import client as odl_client
24
-
25
-from networking_bgpvpn.neutron.extensions import bgpvpn as bgpvpn_ext
26
-from networking_bgpvpn.neutron.services.service_drivers import driver_api
27
-
28
-cfg.CONF.import_group('ml2_odl', 'networking_odl.common.config')
29
-
30
-LOG = logging.getLogger(__name__)
31
-BGPVPNS = 'bgpvpns'
32
-OPENDAYLIGHT_BGPVPN_DRIVER_NAME = 'OpenDaylight'
33
-
34
-
35
-class OpenDaylightBgpvpnDriver(driver_api.BGPVPNDriver):
36
-
37
-    """OpenDaylight BGPVPN Driver
38
-
39
-    This code is the backend implementation for the OpenDaylight BGPVPN
40
-    driver for Openstack Neutron.
41
-    """
42
-
43
-    def __init__(self, service_plugin):
44
-        LOG.warning("This OpenDaylight BGPVPN driver has been deprecated"
45
-                    "and will be removed. Switch to new v2 Driver: "
46
-                    "BGPVPN:OpenDaylight:networking_odl.bgpvpn.odl_v2."
47
-                    "OpenDaylightBgpvpnDriver:default")
48
-        super(OpenDaylightBgpvpnDriver, self).__init__(service_plugin)
49
-        self.service_plugin = service_plugin
50
-
51
-        self.client = odl_client.OpenDaylightRestClient.create_client()
52
-
53
-    def create_bgpvpn_precommit(self, context, bgpvpn):
54
-        pass
55
-
56
-    def create_bgpvpn_postcommit(self, context, bgpvpn):
57
-        url = BGPVPNS
58
-        try:
59
-            self.client.sendjson('post', url, {BGPVPNS[:-1]: bgpvpn})
60
-        except requests.exceptions.RequestException:
61
-            with excutils.save_and_reraise_exception():
62
-                # delete from db
63
-                d_bgpvpn = self.bgpvpn_db.delete_bgpvpn(context, bgpvpn['id'])
64
-                LOG.debug("Deleted bgpvpn %s from db", d_bgpvpn)
65
-
66
-    def delete_bgpvpn_postcommit(self, context, bgpvpn):
67
-        url = BGPVPNS + '/' + bgpvpn['id']
68
-        self.client.sendjson('delete', url, None)
69
-
70
-    def update_bgpvpn_postcommit(self, context, old_bgpvpn, bgpvpn):
71
-        url = BGPVPNS + '/' + bgpvpn['id']
72
-        self.client.sendjson('put', url, {BGPVPNS[:-1]: bgpvpn})
73
-
74
-    def create_net_assoc_precommit(self, context, net_assoc):
75
-        bgpvpns = self.bgpvpn_db.get_bgpvpns(
76
-            context,
77
-            filters={
78
-                'networks': [net_assoc['network_id']],
79
-            },
80
-        )
81
-        if len(bgpvpns) > 1:
82
-            raise bgpvpn_ext.BGPVPNNetworkAssocExistsAnotherBgpvpn(
83
-                driver=OPENDAYLIGHT_BGPVPN_DRIVER_NAME,
84
-                network=net_assoc['network_id'],
85
-                bgpvpn=bgpvpns[0]['id'])
86
-
87
-    def create_net_assoc_postcommit(self, context, net_assoc):
88
-        bgpvpn = self.get_bgpvpn(context, net_assoc['bgpvpn_id'])
89
-        url = BGPVPNS + '/' + bgpvpn['id']
90
-        try:
91
-            self.client.sendjson('put', url, {BGPVPNS[:-1]: bgpvpn})
92
-        except requests.exceptions.RequestException:
93
-            with excutils.save_and_reraise_exception():
94
-                # delete from db
95
-                d_netassoc = self.bgpvpn_db.delete_net_assoc(
96
-                    context, net_assoc['id'], net_assoc['bgpvpn_id'])
97
-                LOG.debug("Deleted net_assoc %s from db", d_netassoc)
98
-
99
-    def delete_net_assoc_postcommit(self, context, net_assoc):
100
-        bgpvpn = self.get_bgpvpn(context, net_assoc['bgpvpn_id'])
101
-        url = BGPVPNS + '/' + bgpvpn['id']
102
-        self.client.sendjson('put', url, {BGPVPNS[:-1]: bgpvpn})
103
-
104
-    def create_router_assoc_precommit(self, context, router_assoc):
105
-        associated_routers = self.get_router_assocs(context,
106
-                                                    router_assoc['bgpvpn_id'])
107
-        for assoc_router in associated_routers:
108
-            if(router_assoc["router_id"] != assoc_router["router_id"]):
109
-                raise bgpvpn_ext.BGPVPNMultipleRouterAssocNotSupported(
110
-                    driver=OPENDAYLIGHT_BGPVPN_DRIVER_NAME)
111
-
112
-    def create_router_assoc_postcommit(self, context, router_assoc):
113
-        bgpvpn = self.get_bgpvpn(context, router_assoc['bgpvpn_id'])
114
-        url = BGPVPNS + '/' + bgpvpn['id']
115
-        try:
116
-            self.client.sendjson('put', url, {BGPVPNS[:-1]: bgpvpn})
117
-        except requests.exceptions.RequestException:
118
-            with excutils.save_and_reraise_exception():
119
-                # delete from db
120
-                d_routerassoc = self.bgpvpn_db.delete_router_assoc(
121
-                    context, router_assoc['id'], router_assoc['bgpvpn_id'])
122
-                LOG.debug("Deleted router_assoc %s from db", d_routerassoc)
123
-
124
-    def delete_router_assoc_postcommit(self, context, router_assoc):
125
-        bgpvpn = self.get_bgpvpn(context, router_assoc['bgpvpn_id'])
126
-        url = BGPVPNS + '/' + bgpvpn['id']
127
-        self.client.sendjson('put', url, {BGPVPNS[:-1]: bgpvpn})

+ 0
- 2
networking_bgpvpn/tests/functional/db/test_migrations.py View File

@@ -24,8 +24,6 @@ from networking_bgpvpn.neutron.db import head
24 24
 IGNORED_TABLES_MATCH = (
25 25
     'ml2_route_target_allocations',
26 26
     '_bagpipe_',
27
-    'odl_',
28
-    'opendaylight'
29 27
 )
30 28
 
31 29
 # EXTERNAL_TABLES should contain all names of tables that are not related to

+ 0
- 0
networking_bgpvpn/tests/unit/services/odl/__init__.py View File


+ 0
- 89
networking_bgpvpn/tests/unit/services/odl/test_odl.py View File

@@ -1,89 +0,0 @@
1
-#
2
-# Copyright (C) 2015 Ericsson India Global Services Pvt Ltd.
3
-#
4
-#  Licensed under the Apache License, Version 2.0 (the "License"); you may
5
-#  not use this file except in compliance with the License. You may obtain
6
-#  a copy of the License at
7
-#
8
-#       http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-#  Unless required by applicable law or agreed to in writing, software
11
-#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
-#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
-#  License for the specific language governing permissions and limitations
14
-#  under the License.
15
-#
16
-
17
-import mock
18
-
19
-
20
-from networking_bgpvpn.tests.unit.services import test_plugin
21
-
22
-
23
-class TestBgpvpnOdlCommon(test_plugin.BgpvpnTestCaseMixin):
24
-
25
-    def setUp(self):
26
-        self.mocked_odlclient = mock.patch(
27
-            'networking_odl.common.client'
28
-            '.OpenDaylightRestClient.create_client').start().return_value
29
-
30
-        provider = ('networking_bgpvpn.neutron.services.service_drivers.'
31
-                    'opendaylight.odl.OpenDaylightBgpvpnDriver')
32
-        super(TestBgpvpnOdlCommon, self).setUp(service_provider=provider)
33
-
34
-
35
-class TestOdlServiceDriver(TestBgpvpnOdlCommon):
36
-
37
-    def test_odl_associate_net(self):
38
-        mocked_sendjson = self.mocked_odlclient.sendjson
39
-        with self.port() as port1:
40
-            net_id = port1['port']['network_id']
41
-            with self.bgpvpn() as bgpvpn:
42
-                id = bgpvpn['bgpvpn']['id']
43
-                rt = bgpvpn['bgpvpn']['route_targets']
44
-                mocked_sendjson.reset_mock()
45
-                with self.assoc_net(id, net_id):
46
-                    formatted_bgpvpn = {
47
-                        'bgpvpn':
48
-                        {'export_targets': mock.ANY,
49
-                         'name': mock.ANY,
50
-                         'route_targets': rt,
51
-                         'tenant_id': mock.ANY,
52
-                         'project_id': mock.ANY,
53
-                         'import_targets': mock.ANY,
54
-                         'route_distinguishers': mock.ANY,
55
-                         'type': mock.ANY,
56
-                         'id': id,
57
-                         'networks': [net_id],
58
-                         'routers': [],
59
-                         'ports': []}}
60
-                    mocked_sendjson.assert_called_once_with(mock.ANY,
61
-                                                            mock.ANY,
62
-                                                            formatted_bgpvpn)
63
-
64
-    def test_odl_associate_router(self):
65
-        mocked_sendjson = self.mocked_odlclient.sendjson
66
-        with self.router(tenant_id=self._tenant_id) as router:
67
-            router_id = router['router']['id']
68
-            with self.bgpvpn() as bgpvpn:
69
-                id = bgpvpn['bgpvpn']['id']
70
-                rt = bgpvpn['bgpvpn']['route_targets']
71
-                mocked_sendjson.reset_mock()
72
-                with self.assoc_router(id, router_id):
73
-                    formatted_bgpvpn = {
74
-                        'bgpvpn':
75
-                        {'export_targets': mock.ANY,
76
-                         'name': mock.ANY,
77
-                         'route_targets': rt,
78
-                         'tenant_id': mock.ANY,
79
-                         'project_id': mock.ANY,
80
-                         'import_targets': mock.ANY,
81
-                         'route_distinguishers': mock.ANY,
82
-                         'type': mock.ANY,
83
-                         'id': id,
84
-                         'networks': [],
85
-                         'routers': [router_id],
86
-                         'ports': []}}
87
-                    mocked_sendjson.assert_called_once_with(mock.ANY,
88
-                                                            mock.ANY,
89
-                                                            formatted_bgpvpn)

+ 5
- 0
releasenotes/notes/remove_obsolete_drivers-3706e080098a5cb6.yaml View File

@@ -0,0 +1,5 @@
1
+---
2
+other:
3
+  - |
4
+    The obsolete in-tree drivers for OpenContrail and OpenDaylight have been
5
+    removed, in favor of the out-of-tree drivers provided by these projects.

+ 0
- 1
setup.cfg View File

@@ -43,7 +43,6 @@ neutron.service_plugins =
43 43
     bgpvpn = networking_bgpvpn.neutron.services.plugin:BGPVPNPlugin
44 44
 oslo.config.opts =
45 45
     networking-bgpvpn.service_provider = networking_bgpvpn.neutron.opts:list_service_provider
46
-    networking-bgpvpn.opencontrail_driver = networking_bgpvpn.neutron.opts:list_opencontrail_driver_opts
47 46
 oslo.config.opts.defaults =
48 47
     networking-bgpvpn.service_provider = networking_bgpvpn.neutron.opts:set_service_provider_default
49 48
 

+ 0
- 4
test-requirements.txt View File

@@ -21,7 +21,3 @@ tempest>=17.1.0 # Apache-2.0
21 21
 # OpenStack CI will install the following projects from git
22 22
 # if they are in the required-projects list for a job:
23 23
 networking-bagpipe>=8.0.0 # Apache-2.0
24
-# we can't use >= 13 which currently can't be properly installed
25
-# (requires ceilometer which, not being on pypy, is required withi
26
-# "-e git", which does not play nice with "pip install -c")
27
-networking-odl>=12.0.0,<13 # Apache-2.0

Loading…
Cancel
Save