Network L3 Router Commands
SDK implementation of L3 Agent commands which would allow for list, add, remove of routers to L3 Agents. Partially Implements: blueprint network-l3-commands Change-Id: Iab11cfae17153a64f09590b6577c3c800dec0266
This commit is contained in:
parent
991b9ebb20
commit
96f025afce
|
@ -2255,6 +2255,62 @@ class Proxy(proxy2.BaseProxy):
|
|||
"""
|
||||
return router.remove_gateway(self.session, **body)
|
||||
|
||||
def routers_hosting_l3_agents(self, router, **query):
|
||||
"""Return a generator of L3 agent hosting a router
|
||||
|
||||
:param router: Either the router id or an instance of
|
||||
:class:`~openstack.network.v2.router.Router`
|
||||
:param kwargs \*\*query: Optional query parameters to be sent to limit
|
||||
the resources returned
|
||||
|
||||
:returns: A generator of Router L3 Agents
|
||||
:rtype: :class:`~openstack.network.v2.router.RouterL3Agents`
|
||||
"""
|
||||
router = self._get_resource(_router.Router, router)
|
||||
return self._list(_agent.RouterL3Agent, paginated=False,
|
||||
router_id=router.id, **query)
|
||||
|
||||
def agent_hosted_routers(self, agent, **query):
|
||||
"""Return a generator of routers hosted by a L3 agent
|
||||
|
||||
:param agent: Either the agent id of an instance of
|
||||
:class:`~openstack.network.v2.network_agent.Agent`
|
||||
:param kwargs \*\*query: Optional query parameters to be sent to limit
|
||||
the resources returned
|
||||
|
||||
:returns: A generator of routers
|
||||
:rtype: :class:`~openstack.network.v2.agent.L3AgentRouters`
|
||||
"""
|
||||
agent = self._get_resource(_agent.Agent, agent)
|
||||
return self._list(_router.L3AgentRouter, paginated=False,
|
||||
agent_id=agent.id, **query)
|
||||
|
||||
def add_router_to_agent(self, agent, router):
|
||||
"""Add router to L3 agent
|
||||
|
||||
:param agent: Either the id of an agent
|
||||
:class:`~openstack.network.v2.agent.Agent` instance
|
||||
:param router: A router instance
|
||||
:returns: Agent with attached router
|
||||
:rtype: :class:`~openstack.network.v2.agent.Agent`
|
||||
"""
|
||||
agent = self._get_resource(_agent.Agent, agent)
|
||||
router = self._get_resource(_router.Router, router)
|
||||
return agent.add_router_to_agent(self.session, router.id)
|
||||
|
||||
def remove_router_from_agent(self, agent, router):
|
||||
"""Remove router from L3 agent
|
||||
|
||||
:param agent: Either the id of an agent or an
|
||||
:class:`~openstack.network.v2.agent.Agent` instance
|
||||
:param router: A router instance
|
||||
:returns: Agent with removed router
|
||||
:rtype: :class:`~openstack.network.v2.agent.Agent`
|
||||
"""
|
||||
agent = self._get_resource(_agent.Agent, agent)
|
||||
router = self._get_resource(_router.Router, router)
|
||||
return agent.remove_router_from_agent(self.session, router.id)
|
||||
|
||||
def create_security_group(self, **attrs):
|
||||
"""Create a new security group from attributes
|
||||
|
||||
|
|
|
@ -75,6 +75,17 @@ class Agent(resource.Resource):
|
|||
network_id)
|
||||
session.delete(url, endpoint_filter=self.service, json=body)
|
||||
|
||||
def add_router_to_agent(self, session, router):
|
||||
body = {'router_id': router}
|
||||
url = utils.urljoin(self.base_path, self.id, 'l3-routers')
|
||||
resp = session.post(url, endpoint_filter=self.service, json=body)
|
||||
return resp.json()
|
||||
|
||||
def remove_router_from_agent(self, session, router):
|
||||
body = {'router_id': router}
|
||||
url = utils.urljoin(self.base_path, self.id, 'l3-routers', router)
|
||||
session.delete(url, endpoint_filter=self.service, json=body)
|
||||
|
||||
|
||||
class NetworkHostingDHCPAgent(Agent):
|
||||
resource_key = 'agent'
|
||||
|
@ -91,3 +102,20 @@ class NetworkHostingDHCPAgent(Agent):
|
|||
allow_list = True
|
||||
|
||||
# NOTE: Doesn't support query yet.
|
||||
|
||||
|
||||
class RouterL3Agent(Agent):
|
||||
resource_key = 'agent'
|
||||
resources_key = 'agents'
|
||||
base_path = '/routers/%(router_id)s/l3-agents'
|
||||
resource_name = 'l3-agent'
|
||||
service = network_service.NetworkService()
|
||||
|
||||
# capabilities
|
||||
allow_create = False
|
||||
allow_retrieve = True
|
||||
allow_update = False
|
||||
allow_delete = False
|
||||
allow_list = True
|
||||
|
||||
# NOTE: No query parameter is supported
|
||||
|
|
|
@ -128,3 +128,20 @@ class Router(resource.Resource):
|
|||
'remove_gateway_router')
|
||||
resp = session.put(url, endpoint_filter=self.service, json=body)
|
||||
return resp.json()
|
||||
|
||||
|
||||
class L3AgentRouter(Router):
|
||||
resource_key = 'router'
|
||||
resources_key = 'routers'
|
||||
base_path = '/agents/%(agent_id)s/l3-routers'
|
||||
resource_name = 'l3-router'
|
||||
service = network_service.NetworkService()
|
||||
|
||||
# capabilities
|
||||
allow_create = False
|
||||
allow_retrieve = True
|
||||
allow_update = False
|
||||
allow_delete = False
|
||||
allow_list = True
|
||||
|
||||
# NOTE: No query parameter is supported
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# 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.
|
||||
|
||||
import uuid
|
||||
|
||||
from openstack.network.v2 import router
|
||||
from openstack.tests.functional import base
|
||||
|
||||
|
||||
class TestAgentRouters(base.BaseFunctionalTest):
|
||||
|
||||
ROUTER_NAME = 'router-name-' + uuid.uuid4().hex
|
||||
ROUTER_ID = None
|
||||
AGENT = None
|
||||
AGENT_ID = None
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestAgentRouters, cls).setUpClass()
|
||||
|
||||
rot = cls.conn.network.create_router(name=cls.ROUTER_NAME)
|
||||
assert isinstance(rot, router.Router)
|
||||
cls.ROUTER_ID = rot.id
|
||||
agent_list = list(cls.conn.network.agents())
|
||||
agents = [agent for agent in agent_list
|
||||
if agent.agent_type == 'L3 agent']
|
||||
cls.AGENT = agents[0]
|
||||
cls.AGENT_ID = cls.AGENT.id
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
rot = cls.conn.network.delete_router(cls.ROUTER_ID,
|
||||
ignore_missing=False)
|
||||
cls.assertIs(None, rot)
|
||||
|
||||
def test_add_router_to_agent(self):
|
||||
sot = self.AGENT.add_router_to_agent(self.conn.session,
|
||||
router_id=self.ROUTER_ID)
|
||||
self._verify_add(sot)
|
||||
|
||||
def test_remove_router_from_agent(self):
|
||||
sot = self.AGENT.remove_router_from_agent(self.conn.session,
|
||||
router_id=self.ROUTER_ID)
|
||||
self._verify_remove(sot)
|
||||
|
||||
def _verify_add(self, sot):
|
||||
rots = self.conn.network.agent_hosted_routers(self.AGENT_ID)
|
||||
routers = [router.id for router in rots]
|
||||
self.assertIn(self.ROUTER_ID, routers)
|
||||
|
||||
def _verify_remove(self, sot):
|
||||
rots = self.conn.network.agent_hosted_routers(self.AGENT_ID)
|
||||
routers = [router.id for router in rots]
|
||||
self.assertNotIn(self.ROUTER_ID, routers)
|
|
@ -89,6 +89,33 @@ class TestAgent(testtools.TestCase):
|
|||
sess.delete.assert_called_with('agents/IDENTIFIER/dhcp-networks/',
|
||||
endpoint_filter=net.service, json=body)
|
||||
|
||||
def test_add_router_to_agent(self):
|
||||
# Add router to agent
|
||||
sot = agent.Agent(**EXAMPLE)
|
||||
response = mock.Mock()
|
||||
response.body = {'router_id': '1'}
|
||||
response.json = mock.Mock(return_value=response.body)
|
||||
sess = mock.Mock()
|
||||
sess.post = mock.Mock(return_value=response)
|
||||
router_id = '1'
|
||||
self.assertEqual(response.body,
|
||||
sot.add_router_to_agent(sess, router_id))
|
||||
body = {'router_id': router_id}
|
||||
url = 'agents/IDENTIFIER/l3-routers'
|
||||
sess.post.assert_called_with(url, endpoint_filter=sot.service,
|
||||
json=body)
|
||||
|
||||
def test_remove_router_from_agent(self):
|
||||
# Remove router from agent
|
||||
sot = agent.Agent(**EXAMPLE)
|
||||
sess = mock.Mock()
|
||||
router_id = {}
|
||||
self.assertIsNone(sot.remove_router_from_agent(sess, router_id))
|
||||
body = {'router_id': {}}
|
||||
|
||||
sess.delete.assert_called_with('agents/IDENTIFIER/l3-routers/',
|
||||
endpoint_filter=sot.service, json=body)
|
||||
|
||||
|
||||
class TestNetworkHostingDHCPAgent(testtools.TestCase):
|
||||
|
||||
|
@ -104,3 +131,19 @@ class TestNetworkHostingDHCPAgent(testtools.TestCase):
|
|||
self.assertFalse(net.allow_update)
|
||||
self.assertFalse(net.allow_delete)
|
||||
self.assertTrue(net.allow_list)
|
||||
|
||||
|
||||
class TestRouterL3Agent(testtools.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
sot = agent.RouterL3Agent()
|
||||
self.assertEqual('agent', sot.resource_key)
|
||||
self.assertEqual('agents', sot.resources_key)
|
||||
self.assertEqual('/routers/%(router_id)s/l3-agents', sot.base_path)
|
||||
self.assertEqual('l3-agent', sot.resource_name)
|
||||
self.assertEqual('network', sot.service.service_type)
|
||||
self.assertFalse(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertFalse(sot.allow_update)
|
||||
self.assertFalse(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
|
|
@ -55,6 +55,7 @@ QOS_POLICY_ID = 'qos-policy-id-' + uuid.uuid4().hex
|
|||
QOS_RULE_ID = 'qos-rule-id-' + uuid.uuid4().hex
|
||||
NETWORK_ID = 'network-id-' + uuid.uuid4().hex
|
||||
AGENT_ID = 'agent-id-' + uuid.uuid4().hex
|
||||
ROUTER_ID = 'router-id-' + uuid.uuid4().hex
|
||||
|
||||
|
||||
class TestNetworkProxy(test_proxy_base2.TestProxyBase):
|
||||
|
@ -739,6 +740,24 @@ class TestNetworkProxy(test_proxy_base2.TestProxyBase):
|
|||
def test_router_update(self):
|
||||
self.verify_update(self.proxy.update_router, router.Router)
|
||||
|
||||
def test_router_hosting_l3_agents_list(self):
|
||||
self.verify_list(
|
||||
self.proxy.routers_hosting_l3_agents,
|
||||
agent.RouterL3Agent,
|
||||
paginated=False,
|
||||
method_kwargs={'router': ROUTER_ID},
|
||||
expected_kwargs={'router_id': ROUTER_ID},
|
||||
)
|
||||
|
||||
def test_agent_hosted_routers_list(self):
|
||||
self.verify_list(
|
||||
self.proxy.agent_hosted_routers,
|
||||
router.L3AgentRouter,
|
||||
paginated=False,
|
||||
method_kwargs={'agent': AGENT_ID},
|
||||
expected_kwargs={'agent_id': AGENT_ID},
|
||||
)
|
||||
|
||||
def test_security_group_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_security_group,
|
||||
security_group.SecurityGroup)
|
||||
|
|
|
@ -203,3 +203,19 @@ class TestRouter(testtools.TestCase):
|
|||
url = 'routers/IDENTIFIER/remove_gateway_router'
|
||||
sess.put.assert_called_with(url, endpoint_filter=sot.service,
|
||||
json=body)
|
||||
|
||||
|
||||
class TestL3AgentRouters(testtools.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
sot = router.L3AgentRouter()
|
||||
self.assertEqual('router', sot.resource_key)
|
||||
self.assertEqual('routers', sot.resources_key)
|
||||
self.assertEqual('/agents/%(agent_id)s/l3-routers', sot.base_path)
|
||||
self.assertEqual('l3-router', sot.resource_name)
|
||||
self.assertEqual('network', sot.service.service_type)
|
||||
self.assertFalse(sot.allow_create)
|
||||
self.assertTrue(sot.allow_retrieve)
|
||||
self.assertFalse(sot.allow_update)
|
||||
self.assertFalse(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
|
Loading…
Reference in New Issue