diff --git a/doc/source/data/lbaas.csv b/doc/source/data/lbaas.csv index 7b570d2..ed4925d 100644 --- a/doc/source/data/lbaas.csv +++ b/doc/source/data/lbaas.csv @@ -3,11 +3,11 @@ lbaas-healthmonitor-delete,,LBaaS v2 Delete a given healthmonitor. lbaas-healthmonitor-list,,LBaaS v2 List healthmonitors that belong to a given tenant. lbaas-healthmonitor-show,,LBaaS v2 Show information of a given healthmonitor. lbaas-healthmonitor-update,,LBaaS v2 Update a given healthmonitor. -lbaas-l7policy-create,,LBaaS v2 Create L7 policy. -lbaas-l7policy-delete,,LBaaS v2 Delete a given L7 policy. -lbaas-l7policy-list,,LBaaS v2 List L7 policies that belong to a given listener. -lbaas-l7policy-show,,LBaaS v2 Show information of a given L7 policy. -lbaas-l7policy-update,,LBaaS v2 Update a given L7 policy. +lbaas-l7policy-create,loadbalancer l7policy create,LBaaS v2 Create L7 policy. +lbaas-l7policy-delete,loadbalancer l7policy delete,LBaaS v2 Delete a given L7 policy. +lbaas-l7policy-list,loadbalancer l7policy list,LBaaS v2 List L7 policies that belong to a given listener. +lbaas-l7policy-show,loadbalancer l7policy show,LBaaS v2 Show information of a given L7 policy. +lbaas-l7policy-update,loadbalancer l7policy set,LBaaS v2 Update a given L7 policy. lbaas-l7rule-create,,LBaaS v2 Create L7 rule. lbaas-l7rule-delete,,LBaaS v2 Delete a given L7 rule. lbaas-l7rule-list,,LBaaS v2 List L7 rules that belong to a given L7 policy. diff --git a/doc/source/usage/osc/v2/load-balancer.rst b/doc/source/usage/osc/v2/load-balancer.rst index 7abedb4..8f487a1 100644 --- a/doc/source/usage/osc/v2/load-balancer.rst +++ b/doc/source/usage/osc/v2/load-balancer.rst @@ -691,3 +691,162 @@ Delete a member from a pool .. describe:: ID or name of the member to update. + +======== +l7policy +======== + +loadbalancer l7policy list +-------------------------- + +List l7policies + +.. program:: loadbalancer l7policy delete +.. code:: bash + + openstack loadbalancer l7policy list + +loadbalancer l7policy show +-------------------------- + +Show the details of a single l7policy + +.. program:: loadbalancer l7policy delete +.. code:: bash + + openstack loadbalancer l7policy show + + +.. _loadbalancer_l7policy_show-policy: +.. describe:: + + Name or UUID of the l7policy. + + +loadbalancer l7policy create +---------------------------- + +Create a l7policy + +.. program:: loadbalancer l7policy delete +.. code:: bash + + openstack loadbalancer l7policy create + [--name ] + [--description ] + [--redirect-pool ] + --action {'REDIRECT_TO_URL','REDIRECT_TO_POOL','REJECT'} + [--redirect-url ] + [--project ] + [--position ] + [--enable | --disable] + + +.. option:: --name + + Set the l7policy name. + +.. option:: --description + + Set l7policy description. + +.. option:: --redirect-pool + + Set the pool to redirect requests to (name or ID). + +.. option:: --action {'REDIRECT_TO_URL','REDIRECT_TO_POOL','REJECT'} + + Set the action of the policy. + +.. option:: --redirect-url + + Set the URL to redirect requests to. + +.. option:: --position + + Sequence number of this L7 Policy. + +.. option:: --enable + + Enable l7policy (default). + +.. option:: --disable + + Disable l7policy. + +.. _loadbalancer_l7policy_create-listener: +.. describe:: + + Listener to add l7policy to (name or ID). + +loadbalancer l7policy set +------------------------- + +Update a l7policy + +.. program:: loadbalancer l7policy set +.. code:: bash + + openstack loadbalancer l7policy set + [--listener ] + [--name ] + [--description ] + [--redirect-pool ] + [--action {'REDIRECT_TO_URL','REDIRECT_TO_POOL','REJECT'}] + [--redirect-url ] + [--position ] + [--enable | --disable] + + +.. option:: --name + + Set l7policy name. + +.. option:: --description + + Set l7policy description. + +.. option:: --redirect-pool + + Set the pool to redirect requests to (name or ID). + +.. option:: --action {'REDIRECT_TO_URL','REDIRECT_TO_POOL','REJECT'} + + Set the action of the policy. + +.. option:: --redirect-url + + Set the URL to redirect requests to. + +.. option:: --position + + Set sequence number of this L7 Policy. + +.. option:: --enable + + Enable l7policy. + +.. option:: --disable + + Disable l7policy. + +.. _loadbalancer_l7policy_set-policy: +.. describe:: + + L7policy to update (name or ID). + +loadbalancer l7policy delete +---------------------------- + +Delete a l7policy + +.. program:: loadbalancer l7policy delete +.. code:: bash + + openstack loadbalancer l7policy delete + + +.. _loadbalancer_l7policy_delete-policy: +.. describe:: + + L7policy to delete (name or ID). diff --git a/octaviaclient/api/constants.py b/octaviaclient/api/constants.py index ddc0d3e..2f75efc 100644 --- a/octaviaclient/api/constants.py +++ b/octaviaclient/api/constants.py @@ -25,3 +25,8 @@ BASE_SINGLE_MEMBER_URL = BASE_MEMBER_URL + '/{member_id}' BASE_MONITOR_URL = '/healthmonitors' BASE_SINGLE_MONITOR_URL = '/healthmonitors/{uuid}' + +BASE_L7POLICY_URL = '/l7policies' +BASE_SINGLE_L7POLICY_URL = BASE_L7POLICY_URL + '/{policy_uuid}' +BASE_L7RULE_URL = BASE_SINGLE_L7POLICY_URL + '/rules' +BASE_SINGLE_L7RULE_URL = BASE_SINGLE_L7POLICY_URL + '/{rule_uuid}' diff --git a/octaviaclient/api/load_balancer_v2.py b/octaviaclient/api/load_balancer_v2.py index c28b6d1..fc3c585 100644 --- a/octaviaclient/api/load_balancer_v2.py +++ b/octaviaclient/api/load_balancer_v2.py @@ -309,6 +309,74 @@ class APIv2(api.BaseAPI): """ url = const.BASE_SINGLE_MEMBER_URL.format(pool_id=pool_id, member_id=member_id) + + response = self.create(url, method='PUT', **kwargs) + + return response + + def l7policy_list(self, **kwargs): + """List all l7policies + + :param kwargs: + Parameters to filter on (not implemented) + :return: + List of l7policies + """ + url = const.BASE_L7POLICY_URL + policy_list = self.list(url, **kwargs) + + return policy_list + + def l7policy_create(self, **kwargs): + """Create a l7policy + + :param kwargs: + Parameters to create a l7policy with (expects json=) + :return: + A dict of the created l7policy's settings + """ + url = const.BASE_L7POLICY_URL + policy = self.create(url, **kwargs) + + return policy + + def l7policy_delete(self, l7policy_id): + """Delete a l7policy + + :param string l7policy_id: + ID of of listener to delete + :return: + Response Code from the API + """ + url = const.BASE_SINGLE_L7POLICY_URL.format(policy_uuid=l7policy_id) + response = self.delete(url) + + return response + + def l7policy_show(self, l7policy_id): + """Show a l7policy's settings + + :param string l7policy_id: + ID of the l7policy to show + :return: + Dict of the specified l7policy's settings + """ + l7policy = self.find(path=const.BASE_L7POLICY_URL, value=l7policy_id) + + return l7policy + + def l7policy_set(self, l7policy_id, **kwargs): + """Update a l7policy's settings + + :param l7policy_id: + ID of the l7policy to update + :param kwargs: + A dict of arguments to update a l7policy + :return: + Response Code from the API + """ + url = const.BASE_SINGLE_L7POLICY_URL.format(policy_uuid=l7policy_id) + response = self.create(url, method='PUT', **kwargs) return response diff --git a/octaviaclient/osc/v2/constants.py b/octaviaclient/osc/v2/constants.py index 3576c7a..dc7d2d6 100644 --- a/octaviaclient/osc/v2/constants.py +++ b/octaviaclient/osc/v2/constants.py @@ -119,3 +119,29 @@ MEMBER_COLUMNS = ( 'protocol_port', 'operating_status', 'weight') + +L7POLICY_ROWS = ( + 'listener_id', + 'description', + 'admin_state_up', + 'rules', + 'project_id', + 'created_at', + 'provisioning_status', + 'updated_at', + 'redirect_pool_id', + 'redirect_url', + 'action', + 'position', + 'id', + 'operating_status', + 'name') + +L7POLICY_COLUMNS = ( + 'id', + 'name', + 'project_id', + 'provisioning_status', + 'action', + 'position', + 'admin_state_up') diff --git a/octaviaclient/osc/v2/l7policy.py b/octaviaclient/osc/v2/l7policy.py new file mode 100644 index 0000000..23596c1 --- /dev/null +++ b/octaviaclient/osc/v2/l7policy.py @@ -0,0 +1,244 @@ +# 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. +# + +"""L7policy action implementation""" + +from cliff import lister +from osc_lib.command import command +from osc_lib import utils + +from octaviaclient.osc.v2 import constants as const +from octaviaclient.osc.v2 import utils as v2_utils + +ACTION_CHOICES = ['REDIRECT_TO_URL', 'REDIRECT_TO_POOL', 'REJECT'] + + +class CreateL7Policy(command.ShowOne): + """Create a l7policy""" + + def get_parser(self, prog_name): + parser = super(CreateL7Policy, self).get_parser(prog_name) + + parser.add_argument( + 'listener', + metavar='', + help="Listener to add to l7policy (name or ID)" + ) + parser.add_argument( + '--name', + metavar='', + help="New l7policy name" + ) + parser.add_argument( + '--description', + metavar='', + help="Set l7policy description" + ) + parser.add_argument( + '--redirect-pool', + metavar='', + help="Redirect pool (name or ID)" + ) + parser.add_argument( + '--action', + metavar='', + required=True, + choices=ACTION_CHOICES, + help="Policy action" + ) + parser.add_argument( + '--redirect-url', + metavar='', + help="Redirect URL" + ) + parser.add_argument( + '--position', + metavar='', + type=int, + help="Sequence number of this L7 Policy." + ) + admin_group = parser.add_mutually_exclusive_group() + admin_group.add_argument( + '--enable', + action='store_true', + default=True, + help="Enable l7policy (default)" + ) + admin_group.add_argument( + '--disable', + action='store_true', + default=None, + help="Disable l7policy" + ) + + return parser + + def take_action(self, parsed_args): + rows = const.L7POLICY_ROWS + attrs = v2_utils.get_l7policy_attrs(self.app.client_manager, + parsed_args) + v2_utils.check_l7policy_attrs(attrs) + body = {"l7policy": attrs} + + data = self.app.client_manager.load_balancer.l7policy_create( + json=body) + + formatters = {'rules': v2_utils.format_list} + + return (rows, (utils.get_dict_properties( + data['l7policy'], rows, formatters=formatters))) + + +class DeleteL7Policy(command.Command): + """Delete a l7policy""" + + def get_parser(self, prog_name): + parser = super(DeleteL7Policy, self).get_parser(prog_name) + + parser.add_argument( + 'l7policy', + metavar="", + help="l7policy to delete (name or ID)" + ) + + return parser + + def take_action(self, parsed_args): + attrs = v2_utils.get_l7policy_attrs(self.app.client_manager, + parsed_args) + + l7policy_id = attrs.pop('l7policy_id') + + self.app.client_manager.load_balancer.l7policy_delete( + l7policy_id=l7policy_id) + + +class ListL7Policy(lister.Lister): + """List l7policies""" + + def get_parser(self, prog_name): + parser = super(ListL7Policy, self).get_parser(prog_name) + + return parser + + def take_action(self, parsed_args): + columns = const.L7POLICY_COLUMNS + + data = self.app.client_manager.load_balancer.l7policy_list() + formatters = {'rules': v2_utils.format_list} + + return (columns, + (utils.get_dict_properties( + s, columns, + formatters=formatters) for s in data['l7policies'])) + + +class ShowL7Policy(command.ShowOne): + """Show the details of a single l7policy""" + + def get_parser(self, prog_name): + parser = super(ShowL7Policy, self).get_parser(prog_name) + + parser.add_argument( + 'l7policy', + metavar='', + help='Name or UUID of the l7policy' + ) + + return parser + + def take_action(self, parsed_args): + rows = const.L7POLICY_ROWS + attrs = v2_utils.get_l7policy_attrs(self.app.client_manager, + parsed_args) + + l7policy_id = attrs.pop('l7policy_id') + + data = self.app.client_manager.load_balancer.l7policy_show( + l7policy_id=l7policy_id, + ) + formatters = {'rules': v2_utils.format_list} + + return (rows, (utils.get_dict_properties( + data, rows, formatters=formatters))) + + +class SetL7Policy(command.Command): + """Update a l7policy""" + + def get_parser(self, prog_name): + parser = super(SetL7Policy, self).get_parser(prog_name) + + parser.add_argument( + 'l7policy', + metavar='', + help="L7policy to update (name or ID)" + ) + parser.add_argument( + '--name', + metavar='', + help="Set l7policy name" + ) + parser.add_argument( + '--description', + metavar='', + help="Set l7policy description" + ) + parser.add_argument( + '--redirect-pool', + metavar='', + help="Set redirect pool (name or ID)" + ) + parser.add_argument( + '--action', + metavar='', + choices=ACTION_CHOICES, + help="Set policy action" + ) + parser.add_argument( + '--redirect-url', + metavar='', + help="Set redirect URL" + ) + parser.add_argument( + '--position', + metavar='', + type=int, + help="Set sequence number of this L7 Policy." + ) + admin_group = parser.add_mutually_exclusive_group() + admin_group.add_argument( + '--enable', + action='store_true', + default=None, + help="Enable l7policy (default)" + ) + admin_group.add_argument( + '--disable', + action='store_true', + default=None, + help="Disable l7policy" + ) + + return parser + + def take_action(self, parsed_args): + attrs = v2_utils.get_l7policy_attrs(self.app.client_manager, + parsed_args) + + l7policy_id = attrs.pop('l7policy_id') + + body = {'l7policy': attrs} + + self.app.client_manager.load_balancer.l7policy_set( + l7policy_id, json=body) diff --git a/octaviaclient/osc/v2/utils.py b/octaviaclient/osc/v2/utils.py index b39e32f..4de09e3 100644 --- a/octaviaclient/osc/v2/utils.py +++ b/octaviaclient/osc/v2/utils.py @@ -43,7 +43,13 @@ def get_resource_id(resource, resource_name, name): if re.get('id') == name['member_id'] or re.get('name') == name['member_id']] name = name['member_id'] - return names[0].get('id') + if len(names) > 1: + msg = ("{0} {1} found with name or ID of {2}. Please try " + "again with UUID".format(len(names), resource_name, + name)) + raise exceptions.CommandError(msg) + else: + return names[0].get('id') else: names = [re for re in resource()[resource_name] if re.get('name') == name or re.get('id') == name] @@ -214,7 +220,7 @@ def get_member_attrs(client_manager, parsed_args): ), 'weight': ('weight', int), 'subnet_id': ( - 'vip_subnet_id', + 'subnet_id', 'subnets', client_manager.neutronclient.list_subnets ), @@ -226,12 +232,59 @@ def get_member_attrs(client_manager, parsed_args): _attrs = vars(parsed_args) attrs = _map_attrs(_attrs, attr_map) - # Need to convert vip_subnet_id name - if 'vip_subnet_id' in attrs: - attrs['subnet_id'] = attrs.pop('vip_subnet_id') + return attrs +def get_l7policy_attrs(client_manager, parsed_args): + attr_map = { + 'name': ('name', str), + 'description': ('description', str), + 'redirect_url': ('redirect_url', str), + 'l7policy': ( + 'l7policy_id', + 'l7policies', + client_manager.load_balancer.l7policy_list + ), + 'redirect_pool': ( + 'redirect_pool_id', + 'pools', + client_manager.load_balancer.pool_list + ), + 'listener': ( + 'listener_id', + 'listeners', + client_manager.load_balancer.listener_list + ), + 'action': ('action', str), + 'project': ( + 'project_id', + 'projects', + client_manager.identity + ), + 'position': ('position', int), + 'enable': ('admin_state_up', lambda x: True), + 'disable': ('admin_state_up', lambda x: False) + } + + _attrs = vars(parsed_args) + attrs = _map_attrs(_attrs, attr_map) + + return attrs + + +def check_l7policy_attrs(attrs): + msg = None + if attrs['action'] == 'REDIRECT_TO_POOL': + if 'redirect_pool_id' not in attrs: + msg = 'Missing argument: --redirect-pool' + elif attrs['action'] == 'REDIRECT_TO_URL': + if 'redirect_url' not in attrs: + msg = 'Missing argument: --redirect-url' + if msg is not None: + raise exceptions.CommandError(msg) + + def format_list(data): return '\n'.join(i['id'] for i in data) @@ -281,4 +334,5 @@ def _map_attrs(attrs, attr_map): child[1], {child[0]: str(v), parent[0]: str(parent_id)} ) + return mapped_attrs diff --git a/octaviaclient/tests/unit/api/test_load_balancer.py b/octaviaclient/tests/unit/api/test_load_balancer.py index 0a5400b..bd3627f 100644 --- a/octaviaclient/tests/unit/api/test_load_balancer.py +++ b/octaviaclient/tests/unit/api/test_load_balancer.py @@ -28,6 +28,8 @@ FAKE_LB = uuidutils.generate_uuid() FAKE_LI = uuidutils.generate_uuid() FAKE_PO = uuidutils.generate_uuid() FAKE_ME = uuidutils.generate_uuid() +FAKE_L7PO = uuidutils.generate_uuid() + LIST_LB_RESP = { 'loadbalancers': @@ -53,6 +55,11 @@ LIST_ME_RESP = { {'name': 'mem2'}] } +LIST_L7PO_RESP = [ + {'name': 'l71'}, + {'name': 'l72'}, +] + SINGLE_LB_RESP = {'loadbalancer': {'id': FAKE_LB, 'name': 'lb1'}} SINGLE_LB_UPDATE = {"loadbalancer": {"admin_state_up": False}} @@ -60,7 +67,10 @@ SINGLE_LI_RESP = {'listener': {'id': FAKE_LI, 'name': 'li1'}} SINGLE_LI_UPDATE = {"listener": {"admin_state_up": False}} SINGLE_PO_RESP = {'pool': {'id': FAKE_PO, 'name': 'li1'}} -SINGLE_PO_UPDATE = {"pool": {"admin_state_up": False}} +SINGLE_PO_UPDATE = {'pool': {'admin_state_up': False}} + +SINGLE_L7PO_RESP = {'l7policy': {'id': FAKE_L7PO, 'name': 'l71'}} +SINGLE_L7PO_UPDATE = {'l7policy': {'admin_state_up': False}} SINGLE_ME_RESP = {'member': {'id': FAKE_ME, 'name': 'mem1'}} SINGLE_ME_UPDATE = {"member": {"admin_state_up": False}} @@ -273,3 +283,52 @@ class TestLoadBalancer(TestLoadBalancerv2): ) ret = self.api.member_delete(pool_id=FAKE_PO, member_id=FAKE_ME) self.assertEqual(200, ret.status_code) + + def test_list_l7policy_no_options(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL + 'l7policies', + json=LIST_L7PO_RESP, + status_code=200, + ) + ret = self.api.l7policy_list() + self.assertEqual(LIST_L7PO_RESP, ret) + + def test_show_l7policy(self): + self.requests_mock.register_uri( + 'GET', + FAKE_URL + 'l7policies/' + FAKE_L7PO, + json=SINGLE_L7PO_RESP, + status_code=200 + ) + ret = self.api.l7policy_show(FAKE_L7PO) + self.assertEqual(SINGLE_L7PO_RESP['l7policy'], ret) + + def test_create_l7policy(self): + self.requests_mock.register_uri( + 'POST', + FAKE_URL + 'l7policies', + json=SINGLE_L7PO_RESP, + status_code=200 + ) + ret = self.api.l7policy_create(json=SINGLE_L7PO_RESP) + self.assertEqual(SINGLE_L7PO_RESP, ret) + + def test_set_l7policy(self): + self.requests_mock.register_uri( + 'PUT', + FAKE_URL + 'l7policies/' + FAKE_L7PO, + json=SINGLE_L7PO_UPDATE, + status_code=200 + ) + ret = self.api.l7policy_set(FAKE_L7PO, json=SINGLE_L7PO_UPDATE) + self.assertEqual(SINGLE_L7PO_UPDATE, ret) + + def test_delete_l7policy(self): + self.requests_mock.register_uri( + 'DELETE', + FAKE_URL + 'l7policies/' + FAKE_L7PO, + status_code=200 + ) + ret = self.api.l7policy_delete(FAKE_L7PO) + self.assertEqual(200, ret.status_code) diff --git a/octaviaclient/tests/unit/osc/v2/fakes.py b/octaviaclient/tests/unit/osc/v2/fakes.py index 4b37404..634a994 100644 --- a/octaviaclient/tests/unit/osc/v2/fakes.py +++ b/octaviaclient/tests/unit/osc/v2/fakes.py @@ -110,7 +110,7 @@ class FakeListener(object): class FakePool(object): - """Fake one or more listeners.""" + """Fake one or more pool.""" @staticmethod def create_one_pool(attrs=None): @@ -165,3 +165,32 @@ class FakeMember(object): mem = fakes.FakeResource(info=copy.deepcopy(member), loaded=True) return mem + + +class FakeL7Policy(object): + """Fake one or more L7policy.""" + + @staticmethod + def create_one_l7policy(attrs=None): + attrs = attrs or {} + + l7po_info = { + "listener_id": str(uuid.uuid4()), + "description": 'fake desc', + "admin_state_up": True, + "rules": [{'id': str(uuid.uuid4())}], + "provisioning_status": 'active', + "redirect_pool_id": str(uuid.uuid4()), + "action": 'POOL_REDIRECT', + "position": 1, + "project_id": str(uuid.uuid4()), + "id": str(uuid.uuid4()), + "name": 'l7po-name-' + uuid.uuid4().hex + } + l7po_info.update(attrs) + + l7po = fakes.FakeResource( + info=copy.deepcopy(l7po_info), + loaded=True) + + return l7po diff --git a/octaviaclient/tests/unit/osc/v2/test_l7policy.py b/octaviaclient/tests/unit/osc/v2/test_l7policy.py new file mode 100644 index 0000000..51528f0 --- /dev/null +++ b/octaviaclient/tests/unit/osc/v2/test_l7policy.py @@ -0,0 +1,210 @@ +# 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 copy +import mock + +from osc_lib import exceptions + +from octaviaclient.osc.v2 import l7policy +from octaviaclient.tests.unit.osc.v2 import fakes as po_fakes + +AUTH_TOKEN = "foobar" +AUTH_URL = "http://192.0.2.2" + + +class TestL7Policy(po_fakes.TestLoadBalancerv2): + + _l7po = po_fakes.FakeL7Policy.create_one_l7policy() + + columns = ( + 'id', + 'name', + 'project_id', + 'provisioning_status', + 'action', + 'position', + 'admin_state_up' + ) + + datalist = ( + ( + _l7po.id, + _l7po.name, + _l7po.project_id, + _l7po.provisioning_status, + _l7po.action, + _l7po.position, + _l7po.admin_state_up + ), + ) + + info = {'l7policies': [{ + 'listener_id': _l7po.listener_id, + 'description': _l7po.description, + 'admin_state_up': _l7po.admin_state_up, + 'rules': _l7po.rules, + 'provisioning_status': _l7po.provisioning_status, + 'redirect_pool_id': _l7po.redirect_pool_id, + 'action': _l7po.action, + 'position': _l7po.position, + 'project_id': _l7po.project_id, + 'id': _l7po.id, + 'name': _l7po.name + }]} + l7po_info = copy.deepcopy(info) + + def setUp(self): + super(TestL7Policy, self).setUp() + self.l7po_mock = self.app.client_manager.load_balancer.load_balancers + self.l7po_mock.reset_mock() + + self.api_mock = mock.Mock() + self.api_mock.l7policy_list.return_value = self.l7po_info + lb_client = self.app.client_manager + lb_client.load_balancer = self.api_mock + + +class TestL7PolicyList(TestL7Policy): + + def setUp(self): + super(TestL7PolicyList, self).setUp() + self.cmd = l7policy.ListL7Policy(self.app, None) + + def test_l7policy_list_no_options(self): + arglist = [] + verifylist = [] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.api_mock.l7policy_list.assert_called_with() + self.assertEqual(self.columns, columns) + self.assertEqual(self.datalist, tuple(data)) + + +class TestL7PolicyDelete(TestL7Policy): + + def setUp(self): + super(TestL7PolicyDelete, self).setUp() + self.cmd = l7policy.DeleteL7Policy(self.app, None) + + def test_l7policy_delete(self): + arglist = [self._l7po.id] + verifylist = [ + ('l7policy', self._l7po.id) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.api_mock.l7policy_delete.assert_called_with( + l7policy_id=self._l7po.id) + + def test_l7policy_delete_failure(self): + arglist = ['unknown_policy'] + verifylist = [ + ('l7policy', 'unknown_policy') + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + self.assertNotCalled(self.api_mock.l7policy_delete) + + +class TestL7PolicyCreate(TestL7Policy): + + def setUp(self): + super(TestL7PolicyCreate, self).setUp() + self.api_mock = mock.Mock() + self.api_mock.l7policy_create.return_value = { + 'l7policy': self.l7po_info} + lb_client = self.app.client_manager + lb_client.load_balancer = self.api_mock + + self.cmd = l7policy.CreateL7Policy(self.app, None) + + @mock.patch('octaviaclient.osc.v2.utils.get_l7policy_attrs') + def test_l7policy_create(self, mock_attrs): + mock_attrs.return_value = { + 'listener_id': self._l7po.listener_id, + 'name': self._l7po.name, + 'action': 'REDIRECT_TO_POOL', + 'redirect_pool_id': self._l7po.redirect_pool_id + } + arglist = ['mock_li_id', + '--name', self._l7po.name, + '--action', 'REDIRECT_TO_POOL', + '--redirect-pool', self._l7po.redirect_pool_id] + + verifylist = [ + ('listener', 'mock_li_id'), + ('name', self._l7po.name), + ('action', 'REDIRECT_TO_POOL'), + ('redirect_pool', self._l7po.redirect_pool_id) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.api_mock.l7policy_create.assert_called_with( + json={'l7policy': { + 'listener_id': self._l7po.listener_id, + 'name': self._l7po.name, + 'action': 'REDIRECT_TO_POOL', + 'redirect_pool_id': self._l7po.redirect_pool_id + }}) + + +class TestL7PolicyShow(TestL7Policy): + + def setUp(self): + super(TestL7PolicyShow, self).setUp() + self.api_mock = mock.Mock() + self.api_mock.l7policy_list.return_value = [{'id': self._l7po.id}] + self.api_mock.l7policy_show.return_value = { + 'l7policy': self.l7po_info} + lb_client = self.app.client_manager + lb_client.load_balancer = self.api_mock + + self.cmd = l7policy.ShowL7Policy(self.app, None) + + @mock.patch('octaviaclient.osc.v2.utils.get_l7policy_attrs') + def test_l7policy_show(self, mock_attrs): + mock_attrs.return_value = {'l7policy_id': self._l7po.id} + arglist = [self._l7po.id] + verifylist = [ + ('l7policy', self._l7po.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.api_mock.l7policy_show.assert_called_with( + l7policy_id=self._l7po.id) + + +class TestL7PolicySet(TestL7Policy): + + def setUp(self): + super(TestL7PolicySet, self).setUp() + self.cmd = l7policy.SetL7Policy(self.app, None) + + def test_l7policy_set(self): + arglist = [self._l7po.id, '--name', 'new_name'] + verifylist = [ + ('l7policy', self._l7po.id), + ('name', 'new_name') + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.api_mock.l7policy_set.assert_called_with( + self._l7po.id, json={'l7policy': {'name': 'new_name'}}) diff --git a/setup.cfg b/setup.cfg index e3a9586..5b89d07 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,6 +47,11 @@ openstack.load_balancer.v2 = loadbalancer_member_show = octaviaclient.osc.v2.member:ShowMember loadbalancer_member_delete = octaviaclient.osc.v2.member:DeleteMember loadbalancer_member_set = octaviaclient.osc.v2.member:SetMember + loadbalancer_l7policy_create = octaviaclient.osc.v2.l7policy:CreateL7Policy + loadbalancer_l7policy_list = octaviaclient.osc.v2.l7policy:ListL7Policy + loadbalancer_l7policy_show = octaviaclient.osc.v2.l7policy:ShowL7Policy + loadbalancer_l7policy_delete = octaviaclient.osc.v2.l7policy:DeleteL7Policy + loadbalancer_l7policy_set = octaviaclient.osc.v2.l7policy:SetL7Policy [build_sphinx] source-dir = doc/source