Add router add/remove route operations

Add methods to the SDK to call the two new member actions introduced by
new Neutron extension: extraroute-atomic.

Change-Id: I6417735b0fb784d500f9d33adca4fcd92cdf7966
Depends-On: https://review.opendev.org/670851
Partial-Bug: #1826396 (rfe)
Related-Change: https://review.opendev.org/655680 (spec)
This commit is contained in:
Bence Romsics 2019-07-31 16:15:49 +02:00
parent 93d0a7166a
commit 28fcf6e313
6 changed files with 133 additions and 0 deletions

View File

@ -63,6 +63,8 @@ Router Operations
.. automethod:: openstack.network.v2._proxy.Proxy.remove_gateway_from_router
.. automethod:: openstack.network.v2._proxy.Proxy.add_interface_to_router
.. automethod:: openstack.network.v2._proxy.Proxy.remove_interface_from_router
.. automethod:: openstack.network.v2._proxy.Proxy.add_extra_routes_to_router
.. automethod:: openstack.network.v2._proxy.Proxy.remove_extra_routes_from_router
Floating IP Operations
^^^^^^^^^^^^^^^^^^^^^^

View File

@ -2585,6 +2585,30 @@ class Proxy(proxy.Proxy):
router = self._get_resource(_router.Router, router)
return router.remove_interface(self, **body)
def add_extra_routes_to_router(self, router, body):
"""Add extra routes to a router
:param router: Either the router ID or an instance of
:class:`~openstack.network.v2.router.Router`
:param body: The request body as documented in the api-ref.
:returns: Router with updated extra routes
:rtype: :class: `~openstack.network.v2.router.Router`
"""
router = self._get_resource(_router.Router, router)
return router.add_extra_routes(self, body=body)
def remove_extra_routes_from_router(self, router, body):
"""Remove extra routes from a router
:param router: Either the router ID or an instance of
:class:`~openstack.network.v2.router.Router`
:param body: The request body as documented in the api-ref.
:returns: Router with updated extra routes
:rtype: :class: `~openstack.network.v2.router.Router`
"""
router = self._get_resource(_router.Router, router)
return router.remove_extra_routes(self, body=body)
def add_gateway_to_router(self, router, **body):
"""Add Gateway to a router

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.exceptions import SDKException
from openstack import resource
from openstack import utils
@ -100,6 +101,48 @@ class Router(resource.Resource, resource.TagMixin):
resp = session.put(url, json=body)
return resp.json()
def _put(self, session, url, body):
resp = session.put(url, json=body)
if not resp.ok:
resp_body = resp.json()
message = None
if 'NeutronError' in resp_body:
message = resp_body['NeutronError']['message']
raise SDKException(message=message)
return resp
def add_extra_routes(self, session, body):
"""Add extra routes to a logical router.
:param session: The session to communicate through.
:type session: :class:`~keystoneauth1.adapter.Adapter`
:param dict body: The request body as documented in the api-ref.
:returns: The response as a Router object with the added extra routes.
:raises: :class:`~openstack.exceptions.SDKException` on error.
"""
url = utils.urljoin(self.base_path, self.id, 'add_extraroutes')
resp = self._put(session, url, body)
self._translate_response(resp)
return self
def remove_extra_routes(self, session, body):
"""Remove extra routes from a logical router.
:param session: The session to communicate through.
:type session: :class:`~keystoneauth1.adapter.Adapter`
:param dict body: The request body as documented in the api-ref.
:returns: The response as a Router object with the extra routes left.
:raises: :class:`~openstack.exceptions.SDKException` on error.
"""
url = utils.urljoin(self.base_path, self.id, 'remove_extraroutes')
resp = self._put(session, url, body)
self._translate_response(resp)
return self
def add_gateway(self, session, **body):
"""Add an external gateway to a logical router.

View File

@ -814,6 +814,34 @@ class TestNetworkProxy(test_proxy_base.TestProxyBase):
expected_kwargs={"subnet_id": "SUBNET"})
mock_get.assert_called_once_with(router.Router, "FAKE_ROUTER")
@mock.patch.object(proxy_base.Proxy, '_get_resource')
@mock.patch.object(router.Router, 'add_extra_routes')
def test_add_extra_routes_to_router(
self, mock_add_extra_routes, mock_get):
x_router = router.Router.new(id="ROUTER_ID")
mock_get.return_value = x_router
self._verify("openstack.network.v2.router.Router.add_extra_routes",
self.proxy.add_extra_routes_to_router,
method_args=["FAKE_ROUTER"],
method_kwargs={"body": {"router": {"routes": []}}},
expected_kwargs={"body": {"router": {"routes": []}}})
mock_get.assert_called_once_with(router.Router, "FAKE_ROUTER")
@mock.patch.object(proxy_base.Proxy, '_get_resource')
@mock.patch.object(router.Router, 'remove_extra_routes')
def test_remove_extra_routes_from_router(
self, mock_remove_extra_routes, mock_get):
x_router = router.Router.new(id="ROUTER_ID")
mock_get.return_value = x_router
self._verify("openstack.network.v2.router.Router.remove_extra_routes",
self.proxy.remove_extra_routes_from_router,
method_args=["FAKE_ROUTER"],
method_kwargs={"body": {"router": {"routes": []}}},
expected_kwargs={"body": {"router": {"routes": []}}})
mock_get.assert_called_once_with(router.Router, "FAKE_ROUTER")
@mock.patch.object(proxy_base.Proxy, '_get_resource')
@mock.patch.object(router.Router, 'add_gateway')
def test_add_gateway_to_router(self, mock_add, mock_get):

View File

@ -173,6 +173,38 @@ class TestRouter(base.TestCase):
sess.put.assert_called_with(url,
json=body)
def test_add_extra_routes(self):
r = router.Router(**EXAMPLE)
response = mock.Mock()
response.headers = {}
json_body = {'router': {}}
response.body = json_body
response.json = mock.Mock(return_value=response.body)
response.status_code = 200
sess = mock.Mock()
sess.put = mock.Mock(return_value=response)
ret = r.add_extra_routes(sess, json_body)
self.assertIsInstance(ret, router.Router)
self.assertIsInstance(ret.routes, list)
url = 'routers/IDENTIFIER/add_extraroutes'
sess.put.assert_called_with(url, json=json_body)
def test_remove_extra_routes(self):
r = router.Router(**EXAMPLE)
response = mock.Mock()
response.headers = {}
json_body = {'router': {}}
response.body = json_body
response.json = mock.Mock(return_value=response.body)
response.status_code = 200
sess = mock.Mock()
sess.put = mock.Mock(return_value=response)
ret = r.remove_extra_routes(sess, json_body)
self.assertIsInstance(ret, router.Router)
self.assertIsInstance(ret.routes, list)
url = 'routers/IDENTIFIER/remove_extraroutes'
sess.put.assert_called_with(url, json=json_body)
def test_add_router_gateway(self):
# Add gateway to a router
sot = router.Router(**EXAMPLE_WITH_OPTIONAL)

View File

@ -0,0 +1,4 @@
---
features:
- |
Add support for methods of Neutron extension: ``extraroute-atomic``.