Add l7 support
Enable users to create l7 policies and rules on a listener. Change-Id: I29130311346c8627473222491a76777a9dc95f52
This commit is contained in:
parent
e9b3988a9d
commit
5b7326405a
@ -180,6 +180,47 @@ def create_listener(request, **kwargs):
|
||||
return _get_sdk_object_dict(listener)
|
||||
|
||||
|
||||
def create_l7_policy(request, **kwargs):
|
||||
"""Create a new l7 policy.
|
||||
|
||||
"""
|
||||
data = request.DATA
|
||||
|
||||
conn = _get_sdk_connection(request)
|
||||
l7_policy = conn.load_balancer.create_l7_policy(
|
||||
action=data['l7policy']['action'],
|
||||
admin_state_up=data['l7policy'].get('admin_state_up'),
|
||||
description=data['l7policy'].get('description'),
|
||||
listener_id=kwargs['listener_id'],
|
||||
name=data['l7policy'].get('name'),
|
||||
position=data['l7policy'].get('position'),
|
||||
redirect_pool_id=data['l7policy'].get('redirect_pool_id'),
|
||||
redirect_url=data['l7policy'].get('redirect_url'),
|
||||
)
|
||||
|
||||
return _get_sdk_object_dict(l7_policy)
|
||||
|
||||
|
||||
def create_l7_rule(request, **kwargs):
|
||||
"""Create a new l7 rule.
|
||||
|
||||
"""
|
||||
data = request.DATA
|
||||
|
||||
conn = _get_sdk_connection(request)
|
||||
l7_rule = conn.load_balancer.create_l7_rule(
|
||||
admin_state_up=data['l7rule'].get('admin_state_up'),
|
||||
compare_type=data['l7rule']['compare_type'],
|
||||
invert=data['l7rule'].get('invert'),
|
||||
key=data['l7rule'].get('key'),
|
||||
l7_policy=kwargs['l7_policy_id'],
|
||||
type=data['l7rule']['type'],
|
||||
rule_value=data['l7rule']['rule_value'],
|
||||
)
|
||||
|
||||
return _get_sdk_object_dict(l7_rule)
|
||||
|
||||
|
||||
def create_pool(request, **kwargs):
|
||||
"""Create a new pool.
|
||||
|
||||
@ -369,6 +410,50 @@ def update_listener(request, **kwargs):
|
||||
return _get_sdk_object_dict(listener)
|
||||
|
||||
|
||||
def update_l7_policy(request, **kwargs):
|
||||
"""Update a l7 policy.
|
||||
|
||||
"""
|
||||
data = request.DATA
|
||||
l7_policy_id = data['l7policy'].get('id')
|
||||
|
||||
conn = _get_sdk_connection(request)
|
||||
l7_policy = conn.load_balancer.update_l7_policy(
|
||||
action=data['l7policy']['action'],
|
||||
admin_state_up=data['l7policy'].get('admin_state_up'),
|
||||
description=data['l7policy'].get('description'),
|
||||
l7_policy=l7_policy_id,
|
||||
name=data['l7policy'].get('name'),
|
||||
position=data['l7policy'].get('position'),
|
||||
redirect_pool_id=data['l7policy'].get('redirect_pool_id'),
|
||||
redirect_url=data['l7policy'].get('redirect_url'),
|
||||
)
|
||||
|
||||
return _get_sdk_object_dict(l7_policy)
|
||||
|
||||
|
||||
def update_l7_rule(request, **kwargs):
|
||||
"""Update a l7 rule.
|
||||
|
||||
"""
|
||||
data = request.DATA
|
||||
l7_rule_id = data['l7rule'].get('id')
|
||||
|
||||
conn = _get_sdk_connection(request)
|
||||
l7_rule = conn.load_balancer.update_l7_rule(
|
||||
admin_state_up=data['l7rule'].get('admin_state_up'),
|
||||
compare_type=data['l7rule']['compare_type'],
|
||||
invert=data['l7rule'].get('invert'),
|
||||
key=data['l7rule'].get('key'),
|
||||
l7_policy=kwargs['l7_policy_id'],
|
||||
l7rule=l7_rule_id,
|
||||
type=data['l7rule']['type'],
|
||||
rule_value=data['l7rule']['rule_value'],
|
||||
)
|
||||
|
||||
return _get_sdk_object_dict(l7_rule)
|
||||
|
||||
|
||||
def update_pool(request, **kwargs):
|
||||
"""Update a pool.
|
||||
|
||||
@ -674,6 +759,148 @@ class Listener(generic.View):
|
||||
conn.load_balancer.delete_listener(listener_id, ignore_missing=True)
|
||||
|
||||
|
||||
@urls.register
|
||||
class L7Policies(generic.View):
|
||||
"""API for load balancer l7 policies.
|
||||
|
||||
"""
|
||||
url_regex = r'lbaas/l7policies/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""List of l7 policies for the current project.
|
||||
|
||||
The listing result is an object with property "items".
|
||||
"""
|
||||
listener_id = request.GET.get('listenerId')
|
||||
conn = _get_sdk_connection(request)
|
||||
l7_policy_list = _sdk_object_to_list(conn.load_balancer.l7_policies(
|
||||
listener_id=listener_id))
|
||||
return {'items': l7_policy_list}
|
||||
|
||||
@rest_utils.ajax()
|
||||
def post(self, request):
|
||||
"""Create a new l7 policy.
|
||||
|
||||
Creates a new l7 policy as well as other optional resources such as
|
||||
l7 rules.
|
||||
"""
|
||||
kwargs = {'listener_id': request.DATA.get('parentResourceId')}
|
||||
return create_l7_policy(request, **kwargs)
|
||||
|
||||
|
||||
@urls.register
|
||||
class L7Policy(generic.View):
|
||||
"""API for retrieving a single l7 policy.
|
||||
|
||||
"""
|
||||
url_regex = r'lbaas/l7policies/(?P<l7_policy_id>[^/]+)/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request, l7_policy_id):
|
||||
"""Get a specific l7 policy.
|
||||
|
||||
If the param 'includeChildResources' is passed in as a truthy value,
|
||||
the details of all resources that exist under the l7 policy will be
|
||||
returned along with the l7 policy details.
|
||||
|
||||
http://localhost/api/lbaas/l7policies/cc758c90-3d98-4ea1-af44-aab405c9c915
|
||||
"""
|
||||
conn = _get_sdk_connection(request)
|
||||
l7_policy = conn.load_balancer.find_l7_policy(l7_policy_id)
|
||||
l7_policy = _get_sdk_object_dict(l7_policy)
|
||||
|
||||
if request.GET.get('includeChildResources'):
|
||||
resources = {}
|
||||
|
||||
if l7_policy.get('rules'):
|
||||
l7_rules_list = _sdk_object_to_list(
|
||||
conn.load_balancer.l7_rules(l7_policy_id))
|
||||
l7_policy['rules'] = l7_rules_list
|
||||
|
||||
resources['l7policy'] = l7_policy
|
||||
|
||||
return resources
|
||||
else:
|
||||
return l7_policy
|
||||
|
||||
@rest_utils.ajax()
|
||||
def put(self, request, l7_policy_id):
|
||||
"""Edit a l7 policy as well as any resources below it.
|
||||
|
||||
"""
|
||||
kwargs = {'l7_policy_id': l7_policy_id}
|
||||
update_l7_policy(request, **kwargs)
|
||||
|
||||
@rest_utils.ajax()
|
||||
def delete(self, request, l7_policy_id):
|
||||
"""Delete a specific l7 policy.
|
||||
|
||||
http://localhost/api/lbaas/l7policies/cc758c90-3d98-4ea1-af44-aab405c9c915
|
||||
"""
|
||||
conn = _get_sdk_connection(request)
|
||||
conn.load_balancer.delete_l7_policy(l7_policy_id)
|
||||
|
||||
|
||||
@urls.register
|
||||
class L7Rules(generic.View):
|
||||
"""API for load balancer l7 rules.
|
||||
|
||||
"""
|
||||
url_regex = r'lbaas/l7policies/(?P<l7_policy_id>[^/]+)/l7rules/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request, l7_policy_id):
|
||||
"""List of l7 rules for the current project.
|
||||
|
||||
The listing result is an object with property "items".
|
||||
"""
|
||||
conn = _get_sdk_connection(request)
|
||||
l7_rule_list = _sdk_object_to_list(conn.load_balancer.l7_rules(
|
||||
l7_policy_id))
|
||||
return {'items': l7_rule_list}
|
||||
|
||||
@rest_utils.ajax()
|
||||
def post(self, request, l7_policy_id):
|
||||
"""Create a new l7 rule.
|
||||
|
||||
Creates a new l7 rule as well as other optional resources such as
|
||||
l7 rules.
|
||||
"""
|
||||
kwargs = {'l7_policy_id': l7_policy_id}
|
||||
return create_l7_rule(request, **kwargs)
|
||||
|
||||
|
||||
@urls.register
|
||||
class L7Rule(generic.View):
|
||||
"""API for retrieving a single l7 rule.
|
||||
|
||||
"""
|
||||
url_regex = (
|
||||
r'lbaas/l7policies/(?P<l7_policy_id>[^/]+)'
|
||||
r'/l7rules/(?P<l7_rule_id>[^/]+)/$'
|
||||
)
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request, l7_rule_id, l7_policy_id):
|
||||
"""Get a specific l7 rule."""
|
||||
conn = _get_sdk_connection(request)
|
||||
l7_rule = conn.load_balancer.find_l7_rule(l7_rule_id, l7_policy_id)
|
||||
return _get_sdk_object_dict(l7_rule)
|
||||
|
||||
@rest_utils.ajax()
|
||||
def put(self, request, l7_rule_id, l7_policy_id):
|
||||
"""Edit a specific l7 rule."""
|
||||
kwargs = {'l7_rule_id': l7_rule_id, 'l7_policy_id': l7_policy_id}
|
||||
update_l7_rule(request, **kwargs)
|
||||
|
||||
@rest_utils.ajax()
|
||||
def delete(self, request, l7_rule_id, l7_policy_id):
|
||||
"""Delete a specific l7 rule."""
|
||||
conn = _get_sdk_connection(request)
|
||||
conn.load_balancer.delete_l7_rule(l7_rule_id, l7_policy_id)
|
||||
|
||||
|
||||
@urls.register
|
||||
class Pools(generic.View):
|
||||
"""API for load balancer pools.
|
||||
|
@ -46,6 +46,16 @@
|
||||
createListener: createListener,
|
||||
editListener: editListener,
|
||||
deleteListener: deleteListener,
|
||||
getL7Policies: getL7Policies,
|
||||
getL7Policy: getL7Policy,
|
||||
createL7Policy: createL7Policy,
|
||||
editL7Policy: editL7Policy,
|
||||
deleteL7Policy: deleteL7Policy,
|
||||
getL7Rules: getL7Rules,
|
||||
getL7Rule: getL7Rule,
|
||||
createL7Rule: createL7Rule,
|
||||
editL7Rule: editL7Rule,
|
||||
deleteL7Rule: deleteL7Rule,
|
||||
getPools: getPools,
|
||||
getPool: getPool,
|
||||
createPool: createPool,
|
||||
@ -108,8 +118,8 @@
|
||||
* @description
|
||||
* Delete a single load balancer by ID
|
||||
* @param {string} id
|
||||
* @param {boolean} quiet
|
||||
* Specifies the id of the load balancer to delete.
|
||||
* @param {boolean} quiet
|
||||
*/
|
||||
|
||||
function deleteLoadBalancer(id, quiet) {
|
||||
@ -231,8 +241,8 @@
|
||||
* @description
|
||||
* Delete a single listener by ID
|
||||
* @param {string} id
|
||||
* @param {boolean} quiet
|
||||
* Specifies the id of the listener to delete.
|
||||
* @param {boolean} quiet
|
||||
*/
|
||||
|
||||
function deleteListener(id, quiet) {
|
||||
@ -333,8 +343,8 @@
|
||||
* @description
|
||||
* Delete a single pool by ID
|
||||
* @param {string} id
|
||||
* @param {boolean} quiet
|
||||
* Specifies the id of the pool to delete.
|
||||
* @param {boolean} quiet
|
||||
*/
|
||||
|
||||
function deletePool(id, quiet) {
|
||||
@ -344,6 +354,198 @@
|
||||
});
|
||||
}
|
||||
|
||||
// L7 Policies
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.getL7Policies
|
||||
* @description
|
||||
* Get the list of l7 policies.
|
||||
* If a listener ID is passed as a parameter, the returning list of
|
||||
* l7 policies will be filtered to include only those l7 policies under the
|
||||
* specified listener.
|
||||
* @param {string} listenerId
|
||||
* Specifies the id of the listener to request l7policies for.
|
||||
*
|
||||
* The listing result is an object with property "items". Each item is
|
||||
* a l7 policy.
|
||||
*/
|
||||
|
||||
function getL7Policies(listenerId) {
|
||||
var params = $.extend({},
|
||||
{
|
||||
listenerId: listenerId
|
||||
}
|
||||
);
|
||||
if (!$.isEmptyObject(params)) {
|
||||
params = { params: params };
|
||||
}
|
||||
return apiService.get('/api/lbaas/l7policies/', params)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve l7 policies.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.getL7Policy
|
||||
* @description
|
||||
* Get a single L7Policy by ID.
|
||||
* @param {string} id
|
||||
* Specifies the id of the l7 policy to request.
|
||||
* @param {boolean} includeChildResources
|
||||
* If truthy, all child resources below the l7 policy will be included in the response.
|
||||
*/
|
||||
|
||||
function getL7Policy(id, includeChildResources) {
|
||||
var params = includeChildResources
|
||||
? {params: {includeChildResources: includeChildResources}}
|
||||
: {};
|
||||
return apiService.get('/api/lbaas/l7policies/' + id + '/', params)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve l7 policy.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.createL7Policy
|
||||
* @description
|
||||
* Create a new l7 policy
|
||||
* @param {object} spec
|
||||
* Specifies the data used to create the new l7 policy.
|
||||
*/
|
||||
|
||||
function createL7Policy(spec) {
|
||||
return apiService.post('/api/lbaas/l7policies/', spec)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to create l7 policy.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.editL7Policy
|
||||
* @description
|
||||
* Edit a l7 policy
|
||||
* @param {string} id
|
||||
* Specifies the id of the l7 policy to update.
|
||||
* @param {object} spec
|
||||
* Specifies the data used to update the l7 policy.
|
||||
*/
|
||||
|
||||
function editL7Policy(id, spec) {
|
||||
return apiService.put('/api/lbaas/l7policies/' + id + '/', spec)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to update l7 policy.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.deleteL7Policy
|
||||
* @description
|
||||
* Delete a single l7 policy by ID
|
||||
* @param {string} id
|
||||
* Specifies the id of the l7 policy to delete.
|
||||
* @param {boolean} quiet
|
||||
*/
|
||||
|
||||
function deleteL7Policy(id, quiet) {
|
||||
var promise = apiService.delete('/api/lbaas/l7policies/' + id + '/');
|
||||
return quiet ? promise : promise.error(function () {
|
||||
toastService.add('error', gettext('Unable to delete l7 policy.'));
|
||||
});
|
||||
}
|
||||
|
||||
// L7 Rules
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.getL7Rules
|
||||
* @description
|
||||
* Get the list of l7 rules under the specified l7 policy.
|
||||
* @param {string} l7policyId
|
||||
* Specifies the id of the l7 policy to request l7rules for.
|
||||
*
|
||||
* The listing result is an object with property "items".
|
||||
* Each item is a l7 rule.
|
||||
*/
|
||||
|
||||
function getL7Rules(l7policyId) {
|
||||
return apiService.get('/api/lbaas/l7policies/' + l7policyId + '/l7rules/')
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve l7 rules.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.getL7Rule
|
||||
* @description
|
||||
* Get a single L7Rule by ID.
|
||||
* @param {string} l7policyId
|
||||
* Specifies the id of the l7 policy the l7 rule belongs to.
|
||||
* @param {string} l7ruleId
|
||||
* Specifies the id of the l7 rule to request.
|
||||
*/
|
||||
|
||||
function getL7Rule(l7policyId, l7ruleId) {
|
||||
return apiService.get('/api/lbaas/l7policies/' + l7policyId + '/l7rules/' + l7ruleId + '/')
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve l7 rule.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.createL7Rule
|
||||
* @description
|
||||
* Create a new l7 rule
|
||||
* @param {string} l7policyId
|
||||
* Specifies the id of the l7 policy the l7 rule belongs to.
|
||||
* @param {object} spec
|
||||
* Specifies the data used to create the new l7 rule.
|
||||
*/
|
||||
|
||||
function createL7Rule(l7policyId, spec) {
|
||||
return apiService.post('/api/lbaas/l7policies/' + l7policyId + '/l7rules/', spec)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to create l7 rule.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.editL7Rule
|
||||
* @description
|
||||
* Edit a l7 rule
|
||||
* @param {string} l7policyId
|
||||
* Specifies the id of the l7 policy the l7 rule belongs to.
|
||||
* @param {string} l7ruleId
|
||||
* Specifies the id of the l7 rule to update.
|
||||
* @param {object} spec
|
||||
* Specifies the data used to update the l7 rule.
|
||||
*/
|
||||
|
||||
function editL7Rule(l7policyId, l7ruleId, spec) {
|
||||
return apiService.put('/api/lbaas/l7policies/' + l7policyId +
|
||||
'/l7rules/' + l7ruleId + '/', spec)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to update l7 rule.'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.deleteL7Rule
|
||||
* @description
|
||||
* Delete a single l7 rule by ID
|
||||
* @param {string} l7policyId
|
||||
* Specifies the id of the l7 policy the l7 rule belongs to.
|
||||
* @param {string} l7ruleId
|
||||
* Specifies the id of the l7 rule to delete.
|
||||
* @param {boolean} quiet
|
||||
*/
|
||||
|
||||
function deleteL7Rule(l7policyId, l7ruleId, quiet) {
|
||||
var promise = apiService.delete('/api/lbaas/l7policies/' + l7policyId +
|
||||
'/l7rules/' + l7ruleId + '/');
|
||||
return quiet ? promise : promise.error(function () {
|
||||
toastService.add('error', gettext('Unable to delete l7 rule.'));
|
||||
});
|
||||
}
|
||||
|
||||
// Members
|
||||
|
||||
/**
|
||||
@ -493,8 +695,8 @@
|
||||
* @description
|
||||
* Delete a single health monitor by ID
|
||||
* @param {string} id
|
||||
* @param {boolean} quiet
|
||||
* Specifies the id of the health monitor to delete.
|
||||
* @param {boolean} quiet
|
||||
*/
|
||||
|
||||
function deleteHealthMonitor(id, quiet) {
|
||||
|
@ -90,6 +90,65 @@
|
||||
error: 'Unable to retrieve listener.',
|
||||
testInput: [ '1234', false ]
|
||||
},
|
||||
{
|
||||
func: 'getL7Policies',
|
||||
method: 'get',
|
||||
path: '/api/lbaas/l7policies/',
|
||||
error: 'Unable to retrieve l7 policies.',
|
||||
testInput: [ '1234' ],
|
||||
data: { params: { listenerId: '1234' } }
|
||||
},
|
||||
{
|
||||
func: 'getL7Policies',
|
||||
method: 'get',
|
||||
path: '/api/lbaas/l7policies/',
|
||||
data: {},
|
||||
error: 'Unable to retrieve l7 policies.'
|
||||
},
|
||||
{
|
||||
func: 'getL7Policy',
|
||||
method: 'get',
|
||||
path: '/api/lbaas/l7policies/1234/',
|
||||
data: { params: { includeChildResources: true } },
|
||||
error: 'Unable to retrieve l7 policy.',
|
||||
testInput: [ '1234', true ]
|
||||
},
|
||||
{
|
||||
func: 'getL7Policy',
|
||||
method: 'get',
|
||||
path: '/api/lbaas/l7policies/1234/',
|
||||
data: {},
|
||||
error: 'Unable to retrieve l7 policy.',
|
||||
testInput: [ '1234', false ]
|
||||
},
|
||||
{
|
||||
func: 'deleteL7Policy',
|
||||
method: 'delete',
|
||||
path: '/api/lbaas/l7policies/1234/',
|
||||
error: 'Unable to delete l7 policy.',
|
||||
testInput: [ '1234' ]
|
||||
},
|
||||
{
|
||||
func: 'getL7Rules',
|
||||
method: 'get',
|
||||
path: '/api/lbaas/l7policies/1234/l7rules/',
|
||||
error: 'Unable to retrieve l7 rules.',
|
||||
testInput: [ '1234' ]
|
||||
},
|
||||
{
|
||||
func: 'getL7Rule',
|
||||
method: 'get',
|
||||
path: '/api/lbaas/l7policies/1234/l7rules/5678/',
|
||||
error: 'Unable to retrieve l7 rule.',
|
||||
testInput: [ '1234', '5678' ]
|
||||
},
|
||||
{
|
||||
func: 'deleteL7Rule',
|
||||
method: 'delete',
|
||||
path: '/api/lbaas/l7policies/1234/l7rules/5678/',
|
||||
error: 'Unable to delete l7 rule.',
|
||||
testInput: [ '1234', '5678' ]
|
||||
},
|
||||
{
|
||||
func: 'getPools',
|
||||
method: 'get',
|
||||
@ -249,6 +308,38 @@
|
||||
error: 'Unable to delete listener.',
|
||||
testInput: [ '1234' ]
|
||||
},
|
||||
{
|
||||
func: 'createL7Policy',
|
||||
method: 'post',
|
||||
path: '/api/lbaas/l7policies/',
|
||||
error: 'Unable to create l7 policy.',
|
||||
data: { name: 'l7policy-1' },
|
||||
testInput: [ { name: 'l7policy-1' } ]
|
||||
},
|
||||
{
|
||||
func: 'editL7Policy',
|
||||
method: 'put',
|
||||
path: '/api/lbaas/l7policies/1234/',
|
||||
error: 'Unable to update l7 policy.',
|
||||
data: { name: 'l7policy-1' },
|
||||
testInput: [ '1234', { name: 'l7policy-1' } ]
|
||||
},
|
||||
{
|
||||
func: 'createL7Rule',
|
||||
method: 'post',
|
||||
path: '/api/lbaas/l7policies/1234/l7rules/',
|
||||
error: 'Unable to create l7 rule.',
|
||||
data: { name: 'l7rule-1' },
|
||||
testInput: [ '1234', { name: 'l7rule-1' } ]
|
||||
},
|
||||
{
|
||||
func: 'editL7Rule',
|
||||
method: 'put',
|
||||
path: '/api/lbaas/l7policies/1234/l7rules/5678/',
|
||||
error: 'Unable to update l7 rule.',
|
||||
data: { name: 'l7rule-1' },
|
||||
testInput: [ '1234', '5678', { name: 'l7rule-1' } ]
|
||||
},
|
||||
{
|
||||
func: 'createPool',
|
||||
method: 'post',
|
||||
@ -301,6 +392,16 @@
|
||||
expect(service.deleteListener("whatever", true)).toBe("promise");
|
||||
});
|
||||
|
||||
it('supresses the error if instructed for deleteL7Policy', function() {
|
||||
spyOn(apiService, 'delete').and.returnValue("promise");
|
||||
expect(service.deleteL7Policy("whatever", true)).toBe("promise");
|
||||
});
|
||||
|
||||
it('supresses the error if instructed for deleteL7Rule', function() {
|
||||
spyOn(apiService, 'delete').and.returnValue("promise");
|
||||
expect(service.deleteL7Rule("whatever", "whatever", true)).toBe("promise");
|
||||
});
|
||||
|
||||
it('supresses the error if instructed for deletePool', function() {
|
||||
spyOn(apiService, 'delete').and.returnValue("promise");
|
||||
expect(service.deletePool("whatever", true)).toBe("promise");
|
||||
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7policies')
|
||||
.factory('horizon.dashboard.project.lbaasv2.l7policies.actions.create', createService);
|
||||
|
||||
createService.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.l7policies.resourceType',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'$q',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.modal',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngDoc factory
|
||||
* @name horizon.dashboard.project.lbaasv2.l7policies.actions.createService
|
||||
*
|
||||
* @description
|
||||
* Provides the service for creating a l7policy resource.
|
||||
*
|
||||
* @param resourceType The l7policy resource type.
|
||||
* @param actionResultService The horizon action result service.
|
||||
* @param $q The angular service for promises.
|
||||
* @param workflowModal The LBaaS workflow modal service.
|
||||
* @param policy The horizon policy service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
*
|
||||
* @returns The l7policy create service.
|
||||
*/
|
||||
|
||||
function createService(
|
||||
resourceType, actionResultService,
|
||||
$q, workflowModal, policy, gettext
|
||||
) {
|
||||
return workflowModal.init({
|
||||
controller: 'CreateL7PolicyWizardController',
|
||||
message: gettext('A new l7 policy is being created.'),
|
||||
handle: handle,
|
||||
allowed: allowed
|
||||
});
|
||||
|
||||
//////////////
|
||||
|
||||
function allowed() {
|
||||
return $q.all([
|
||||
policy.ifAllowed({ rules: [['neutron', 'create_l7policy']] })
|
||||
]);
|
||||
}
|
||||
|
||||
function handle(response) {
|
||||
return actionResultService.getActionResult()
|
||||
.created(resourceType, response.data.id)
|
||||
.result;
|
||||
}
|
||||
}
|
||||
})();
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Create l7policy Action Service', function() {
|
||||
var policy, service;
|
||||
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('$modal', {
|
||||
open: function() {
|
||||
return {
|
||||
result: {
|
||||
then: function(func) {
|
||||
func({ data: { id: 'listener1' } });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
$provide.value('$routeParams', {});
|
||||
}));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
service = $injector.get('horizon.dashboard.project.lbaasv2.l7policies.actions.create');
|
||||
}));
|
||||
|
||||
it('should not allow creating a l7policy if listenerId is not present', function() {
|
||||
spyOn(policy, 'ifAllowed').and.returnValue(true);
|
||||
var allowed = service.allowed();
|
||||
permissionShouldFail(allowed);
|
||||
});
|
||||
|
||||
it('should handle the action result properly', function() {
|
||||
var result = service.handle({data: {id: 1}});
|
||||
expect(result.created[0].id).toBe(1);
|
||||
});
|
||||
|
||||
function permissionShouldFail(permissions) {
|
||||
permissions.then(
|
||||
function() {
|
||||
expect(false).toBe(true);
|
||||
},
|
||||
function() {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7policies')
|
||||
.controller('CreateL7PolicyWizardController', CreateL7PolicyWizardController);
|
||||
|
||||
CreateL7PolicyWizardController.$inject = [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.model',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.workflow',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function CreateL7PolicyWizardController($scope, $routeParams, model, workflowService, gettext) {
|
||||
var loadbalancerId = $routeParams.loadbalancerId;
|
||||
var listenerId = $routeParams.listenerId;
|
||||
var scope = $scope;
|
||||
scope.model = model;
|
||||
scope.submit = scope.model.submit;
|
||||
scope.workflow = workflowService(
|
||||
gettext('Create L7 Policy'),
|
||||
'fa fa-cloud-download',
|
||||
['l7policy']
|
||||
);
|
||||
scope.model.initialize('l7policy', false, loadbalancerId, listenerId);
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Create L7Policy Wizard Controller', function() {
|
||||
var ctrl;
|
||||
var model = {
|
||||
submit: function() {
|
||||
return 'created';
|
||||
},
|
||||
initialize: angular.noop
|
||||
};
|
||||
var workflow = function() {
|
||||
return 'foo';
|
||||
};
|
||||
var scope = {
|
||||
launchContext: {id: '1234'}
|
||||
};
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module(function ($provide) {
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.model', model);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.workflow', workflow);
|
||||
}));
|
||||
beforeEach(inject(function ($controller) {
|
||||
spyOn(model, 'initialize');
|
||||
ctrl = $controller('CreateL7PolicyWizardController', { $scope: scope });
|
||||
}));
|
||||
|
||||
it('defines the controller', function() {
|
||||
expect(ctrl).toBeDefined();
|
||||
});
|
||||
|
||||
it('calls initialize on the given model', function() {
|
||||
expect(model.initialize).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('sets scope.workflow to the given workflow', function() {
|
||||
expect(scope.workflow).toBe('foo');
|
||||
});
|
||||
|
||||
it('defines scope.submit', function() {
|
||||
expect(scope.submit).toBeDefined();
|
||||
expect(scope.submit()).toBe('created');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7policies')
|
||||
.factory('horizon.dashboard.project.lbaasv2.l7policies.actions.delete', deleteService);
|
||||
|
||||
deleteService.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.l7policies.resourceType',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'$location',
|
||||
'horizon.framework.widgets.modal.deleteModalService',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.app.core.openstack-service-api.policy'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngDoc factory
|
||||
* @name horizon.dashboard.project.lbaasv2.l7policies.actions.deleteService
|
||||
*
|
||||
* @description
|
||||
* Brings up the delete l7policy confirmation modal dialog.
|
||||
* On submit, deletes selected l7policy.
|
||||
* On cancel, does nothing.
|
||||
*
|
||||
* @param resourceType The l7policy resource type.
|
||||
* @param actionResultService The horizon action result service.
|
||||
* @param $location The angular $location service.
|
||||
* @param deleteModal The horizon delete modal service.
|
||||
* @param api The LBaaS v2 API service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @param policy The horizon policy service.
|
||||
*
|
||||
* @returns The l7policy delete service.
|
||||
*/
|
||||
|
||||
function deleteService(
|
||||
resourceType, actionResultService, $location,
|
||||
deleteModal, api, gettext, policy
|
||||
) {
|
||||
var loadbalancerId, listenerId;
|
||||
|
||||
var service = {
|
||||
perform: perform,
|
||||
allowed: allowed,
|
||||
deleteResult: deleteResult // exposed just for testing
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
//////////////
|
||||
|
||||
function allowed(/*item*/) {
|
||||
// This rule is made up and should therefore always pass. I assume at some point there
|
||||
// will be a valid rule similar to this that we will want to use.
|
||||
return policy.ifAllowed({ rules: [['neutron', 'delete_l7policy']] });
|
||||
}
|
||||
|
||||
function perform(items, scope) {
|
||||
var context = { };
|
||||
var l7policies = angular.isArray(items) ? items : [items];
|
||||
context.labels = labelize(l7policies.length);
|
||||
context.deleteEntity = deleteItem;
|
||||
l7policies.map(function(item) {
|
||||
loadbalancerId = item.loadbalancerId;
|
||||
listenerId = item.listenerId;
|
||||
});
|
||||
return deleteModal.open(scope, l7policies, context).then(deleteResult);
|
||||
}
|
||||
|
||||
function labelize(count) {
|
||||
return {
|
||||
title: ngettext(
|
||||
'Confirm Delete L7 Policy',
|
||||
'Confirm Delete L7 Policies', count),
|
||||
|
||||
message: ngettext(
|
||||
'You have selected "%s". Deleted L7 Policy is not recoverable.',
|
||||
'You have selected "%s". Deleted L7 Policies are not recoverable.', count),
|
||||
|
||||
submit: ngettext(
|
||||
'Delete L7 Policy',
|
||||
'Delete L7 Policies', count),
|
||||
|
||||
success: ngettext(
|
||||
'Deleted L7 Policy: %s.',
|
||||
'Deleted L7 Policies: %s.', count),
|
||||
|
||||
error: ngettext(
|
||||
'Unable to delete L7 Policy: %s.',
|
||||
'Unable to delete L7 Policies: %s.', count)
|
||||
};
|
||||
}
|
||||
|
||||
function deleteResult(deleteModalResult) {
|
||||
// To make the result of this action generically useful, reformat the return
|
||||
// from the deleteModal into a standard form
|
||||
var actionResult = actionResultService.getActionResult();
|
||||
deleteModalResult.pass.forEach(function markDeleted(item) {
|
||||
actionResult.deleted(resourceType, item.context.id);
|
||||
});
|
||||
deleteModalResult.fail.forEach(function markFailed(item) {
|
||||
actionResult.failed(resourceType, item.context.id);
|
||||
});
|
||||
|
||||
if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
|
||||
var path = 'project/load_balancer/' + loadbalancerId +
|
||||
'/listeners/' + listenerId;
|
||||
$location.path(path);
|
||||
}
|
||||
return actionResult.result;
|
||||
}
|
||||
|
||||
function deleteItem(id) {
|
||||
return api.deleteL7Policy(id, true);
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 L7Policy Delete Service', function() {
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module('horizon.framework'));
|
||||
|
||||
var deleteModalService, service, lbaasv2API, policyAPI, $location;
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
service = $injector.get('horizon.dashboard.project.lbaasv2.l7policies.actions.delete');
|
||||
lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
|
||||
deleteModalService = $injector.get('horizon.framework.widgets.modal.deleteModalService');
|
||||
policyAPI = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
$location = $injector.get('$location');
|
||||
}));
|
||||
|
||||
describe('perform method', function() {
|
||||
beforeEach(function () {
|
||||
// just need for this to return something that looks like a promise but does nothing
|
||||
spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
|
||||
});
|
||||
|
||||
it('should open the modal with correct label', function () {
|
||||
service.perform({name: 'spam'});
|
||||
var labels = deleteModalService.open.calls.argsFor(0)[2].labels;
|
||||
expect(deleteModalService.open).toHaveBeenCalled();
|
||||
angular.forEach(labels, function eachLabel(label) {
|
||||
expect(label.toLowerCase()).toContain('l7 policy');
|
||||
});
|
||||
});
|
||||
|
||||
it('should open the delete modal with correct entities', function () {
|
||||
service.perform([{name: 'one'}, {name: 'two'}]);
|
||||
var entities = deleteModalService.open.calls.argsFor(0)[1];
|
||||
expect(deleteModalService.open).toHaveBeenCalled();
|
||||
expect(entities.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('should pass in a function that deletes a l7 policy', function () {
|
||||
spyOn(lbaasv2API, 'deleteL7Policy').and.callFake(angular.noop);
|
||||
service.perform({id: 1, name: 'one'});
|
||||
var contextArg = deleteModalService.open.calls.argsFor(0)[2];
|
||||
var deleteFunction = contextArg.deleteEntity;
|
||||
deleteFunction(1);
|
||||
expect(lbaasv2API.deleteL7Policy).toHaveBeenCalledWith(1, true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle the action result properly', function() {
|
||||
spyOn($location, 'path');
|
||||
spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
|
||||
spyOn(lbaasv2API, 'deleteL7Policy').and.callFake(angular.noop);
|
||||
service.perform({loadbalancerId: 1, listenerId: 2, id: 1, name: 'one'});
|
||||
var result = service.deleteResult({
|
||||
fail: [],
|
||||
pass: [{
|
||||
context: {
|
||||
id: 1
|
||||
}
|
||||
}]
|
||||
});
|
||||
var path = 'project/load_balancer/1/listeners/2';
|
||||
expect($location.path).toHaveBeenCalledWith(path);
|
||||
expect(result.deleted[0].id).toBe(1);
|
||||
result = service.deleteResult({
|
||||
pass: [],
|
||||
fail: [{
|
||||
context: {
|
||||
id: 1
|
||||
}
|
||||
}]
|
||||
});
|
||||
expect(result.failed[0].id).toBe(1);
|
||||
});
|
||||
|
||||
describe('allow method', function() {
|
||||
it('should use default policy if batch action', function () {
|
||||
spyOn(policyAPI, 'ifAllowed');
|
||||
service.allowed();
|
||||
expect(policyAPI.ifAllowed).toHaveBeenCalled();
|
||||
});
|
||||
}); // end of allowed
|
||||
|
||||
}); // end of delete
|
||||
|
||||
})();
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7policies')
|
||||
.factory('horizon.dashboard.project.lbaasv2.l7policies.actions.edit', editService);
|
||||
|
||||
editService.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.l7policies.resourceType',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.modal',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngDoc factory
|
||||
* @name horizon.dashboard.project.lbaasv2.l7policies.actions.editService
|
||||
*
|
||||
* @description
|
||||
* Provides the service for editing a l7policy resource.
|
||||
*
|
||||
* @param resourceType The l7policy resource type.
|
||||
* @param actionResultService The horizon action result service.
|
||||
* @param workflowModal The LBaaS workflow modal service.
|
||||
* @param policy The horizon policy service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
*
|
||||
* @returns The l7policy edit service.
|
||||
*/
|
||||
|
||||
function editService(
|
||||
resourceType, actionResultService, workflowModal, policy, gettext
|
||||
) {
|
||||
|
||||
return workflowModal.init({
|
||||
controller: 'EditL7PolicyWizardController',
|
||||
message: gettext('The l7policy has been updated.'),
|
||||
handle: handle,
|
||||
allowed: allowed
|
||||
});
|
||||
|
||||
function allowed(/*item*/) {
|
||||
return policy.ifAllowed({ rules: [['neutron', 'update_l7policy']] });
|
||||
}
|
||||
|
||||
function handle(response) {
|
||||
return actionResultService.getActionResult()
|
||||
.updated(resourceType, response.config.data.l7policy.id)
|
||||
.result;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Edit L7Policy Action Service', function() {
|
||||
var policy, service;
|
||||
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('$modal', {
|
||||
open: function() {
|
||||
return {
|
||||
result: {
|
||||
then: function(func) {
|
||||
func({ data: { id: 'l7policy1' } });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
service = $injector.get('horizon.dashboard.project.lbaasv2.l7policies.actions.edit');
|
||||
}));
|
||||
|
||||
it('should check policy to allow editing a l7policy', function() {
|
||||
spyOn(policy, 'ifAllowed').and.returnValue(true);
|
||||
expect(service.allowed()).toBe(true);
|
||||
expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_l7policy']]});
|
||||
});
|
||||
|
||||
it('should handle the action result properly', function() {
|
||||
var result = service.handle({config: {data: {l7policy: {id: 1}}}});
|
||||
expect(result.updated[0].id).toBe(1);
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.controller('EditL7PolicyWizardController', EditL7PolicyWizardController);
|
||||
|
||||
EditL7PolicyWizardController.$inject = [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'$q',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.model',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.workflow',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name EditL7PolicyWizardController
|
||||
*
|
||||
* @description
|
||||
* Controller for the LBaaS v2 edit l7policy wizard.
|
||||
*
|
||||
* @param $scope The angular scope object.
|
||||
* @param $routeParams The angular $routeParams service.
|
||||
* @param $q The angular service for promises.
|
||||
* @param model The LBaaS V2 workflow model service.
|
||||
* @param workflowService The LBaaS V2 workflow service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function EditL7PolicyWizardController($scope, $routeParams, $q, model, workflowService, gettext) {
|
||||
var scope = $scope;
|
||||
var loadbalancerId = $routeParams.loadbalancerId;
|
||||
var listenerId = $routeParams.listenerId;
|
||||
scope.model = model;
|
||||
scope.submit = scope.model.submit;
|
||||
scope.workflow = workflowService(
|
||||
gettext('Update L7 Policy'),
|
||||
'fa fa-pencil', ['l7policy']);
|
||||
scope.model.initialize('l7policy', scope.launchContext.id, loadbalancerId, listenerId);
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Edit L7Policy Wizard Controller', function() {
|
||||
var ctrl, workflowSpy, $q, scope;
|
||||
var model = {
|
||||
submit: function() {
|
||||
return 'updated';
|
||||
},
|
||||
initialize: function() {
|
||||
var defer = $q.defer();
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
}
|
||||
};
|
||||
var workflow = {
|
||||
steps: [{id: 'l7policy'}],
|
||||
append: angular.noop
|
||||
};
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module(function ($provide) {
|
||||
workflowSpy = jasmine.createSpy('workflow').and.returnValue(workflow);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.model', model);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.workflow', workflowSpy);
|
||||
}));
|
||||
beforeEach(inject(function ($controller, $injector) {
|
||||
$q = $injector.get('$q');
|
||||
scope = $injector.get('$rootScope').$new();
|
||||
scope.launchContext = { id: 'l7policyId' };
|
||||
spyOn(model, 'initialize').and.callThrough();
|
||||
ctrl = $controller('EditL7PolicyWizardController', {
|
||||
$scope: scope,
|
||||
$routeParams: {loadbalancerId: 'loadbalancerId', listenerId: 'listenerId'}});
|
||||
}));
|
||||
|
||||
it('defines the controller', function() {
|
||||
expect(ctrl).toBeDefined();
|
||||
});
|
||||
|
||||
it('calls initialize on the given model', function() {
|
||||
expect(model.initialize).toHaveBeenCalledWith(
|
||||
'l7policy', 'l7policyId', 'loadbalancerId', 'listenerId');
|
||||
});
|
||||
|
||||
it('sets scope.workflow to the given workflow', function() {
|
||||
expect(scope.workflow).toBe(workflow);
|
||||
});
|
||||
|
||||
it('initializes workflow with correct properties', function() {
|
||||
expect(workflowSpy).toHaveBeenCalledWith('Update L7 Policy',
|
||||
'fa fa-pencil', ['l7policy']);
|
||||
});
|
||||
|
||||
it('defines scope.submit', function() {
|
||||
expect(scope.submit).toBe(model.submit);
|
||||
expect(scope.submit()).toBe('updated');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7policies')
|
||||
.controller('L7PolicyDetailController', L7PolicyDetailController);
|
||||
|
||||
L7PolicyDetailController.$inject = [
|
||||
'loadbalancer',
|
||||
'listener',
|
||||
'l7policy',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.service',
|
||||
'horizon.dashboard.project.lbaasv2.l7policies.resourceType',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.framework.widgets.modal-wait-spinner.service',
|
||||
'$q'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name L7PolicyDetailController
|
||||
*
|
||||
* @description
|
||||
* Controller for the LBaaS v2 l7policy detail page.
|
||||
*
|
||||
* @param loadbalancer The loadbalancer object.
|
||||
* @param listener The listener object.
|
||||
* @param l7policy The l7policy object.
|
||||
* @param loadBalancersService The LBaaS v2 load balancers service.
|
||||
* @param resourceType The load balancer resource type.
|
||||
* @param typeRegistry The horizon type registry service.
|
||||
* @param spinnerService The horizon modal wait spinner service.
|
||||
* @param $q The angular service for promises.
|
||||
*
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function L7PolicyDetailController(
|
||||
loadbalancer, listener, l7policy, loadBalancersService,
|
||||
resourceType, typeRegistry, spinnerService, $q
|
||||
) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.operatingStatus = loadBalancersService.operatingStatus;
|
||||
ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
|
||||
ctrl.l7policyAction = loadBalancersService.l7policyAction;
|
||||
ctrl.loadbalancer = loadbalancer;
|
||||
ctrl.listener = listener;
|
||||
ctrl.l7policy = l7policy;
|
||||
ctrl.listFunctionExtraParams = {
|
||||
loadbalancerId: ctrl.loadbalancer.id,
|
||||
listenerId: ctrl.listener.id,
|
||||
l7policyId: ctrl.l7policy.id
|
||||
};
|
||||
ctrl.resourceType = typeRegistry.getResourceType(resourceType);
|
||||
ctrl.context = {};
|
||||
ctrl.context.identifier = l7policy.id;
|
||||
|
||||
ctrl.resultHandler = actionResultHandler;
|
||||
|
||||
function actionResultHandler(returnValue) {
|
||||
return $q.when(returnValue, actionSuccessHandler);
|
||||
}
|
||||
|
||||
function loadData(response) {
|
||||
spinnerService.hideModalSpinner();
|
||||
ctrl.showDetails = true;
|
||||
ctrl.resourceType.initActions();
|
||||
ctrl.l7policy = response.data;
|
||||
ctrl.l7policy.loadbalancerId = ctrl.loadbalancer.id;
|
||||
ctrl.l7policy.listenerId = ctrl.listener.id;
|
||||
}
|
||||
|
||||
function actionSuccessHandler(result) {
|
||||
// The action has completed (for whatever "complete" means to that
|
||||
// action. Notice the view doesn't really need to know the semantics of the
|
||||
// particular action because the actions return data in a standard form.
|
||||
// That return includes the id and type of each created, updated, deleted
|
||||
// and failed item.
|
||||
// Currently just refreshes the display each time.
|
||||
if (result) {
|
||||
if (result.failed.length === 0 && result.deleted.length > 0) {
|
||||
// handle a race condition where the resource is already deleted
|
||||
return;
|
||||
}
|
||||
spinnerService.showModalSpinner(gettext('Please Wait'));
|
||||
ctrl.showDetails = false;
|
||||
ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier);
|
||||
ctrl.context.loadPromise.then(loadData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 L7Policy Detail Controller', function() {
|
||||
var deferred, service, ctrl, scope, $timeout, $q, actionResultService;
|
||||
|
||||
///////////////////////
|
||||
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('$uibModal', {});
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($controller, $rootScope, _$q_, _$timeout_) {
|
||||
$q = _$q_;
|
||||
deferred = $q.defer();
|
||||
service = {
|
||||
getResourceType: function() {
|
||||
return {
|
||||
load: function() { return deferred.promise; },
|
||||
parsePath: function() { return 'my-context'; },
|
||||
itemName: function() { return 'A name'; },
|
||||
initActions: angular.noop
|
||||
};
|
||||
},
|
||||
getDefaultDetailsTemplateUrl: angular.noop
|
||||
};
|
||||
actionResultService = {
|
||||
getIdsOfType: function() { return []; }
|
||||
};
|
||||
$timeout = _$timeout_;
|
||||
scope = $rootScope.$new();
|
||||
ctrl = $controller('L7PolicyDetailController', {
|
||||
$scope: scope,
|
||||
loadbalancer: { id: '123' },
|
||||
listener: { id: '123' },
|
||||
l7policy: { id: '123' },
|
||||
'horizon.framework.conf.resource-type-registry.service': service,
|
||||
'horizon.framework.util.actions.action-result.service': actionResultService,
|
||||
'horizon.framework.widgets.modal-wait-spinner.service': {
|
||||
showModalSpinner: angular.noop,
|
||||
hideModalSpinner: angular.noop
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create a controller', function() {
|
||||
expect(ctrl).toBeDefined();
|
||||
expect(ctrl.loadbalancer).toBeDefined();
|
||||
expect(ctrl.listener).toBeDefined();
|
||||
expect(ctrl.l7policy).toBeDefined();
|
||||
});
|
||||
|
||||
describe('resultHandler', function() {
|
||||
|
||||
it('handles empty results', function() {
|
||||
var result = $q.defer();
|
||||
result.resolve({failed: [], deleted: []});
|
||||
ctrl.resultHandler(result.promise);
|
||||
$timeout.flush();
|
||||
expect(ctrl.showDetails).not.toBe(true);
|
||||
});
|
||||
|
||||
it('handles falsy results', function() {
|
||||
var result = $q.defer();
|
||||
result.resolve(false);
|
||||
ctrl.resultHandler(result.promise);
|
||||
$timeout.flush();
|
||||
expect(ctrl.showDetails).not.toBe(true);
|
||||
});
|
||||
|
||||
it('handles matched results', function() {
|
||||
spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
|
||||
var result = $q.defer();
|
||||
result.resolve({some: 'thing', failed: [], deleted: []});
|
||||
ctrl.resultHandler(result.promise);
|
||||
deferred.resolve({data: {some: 'data'}});
|
||||
$timeout.flush();
|
||||
expect(ctrl.showDetails).toBe(true);
|
||||
});
|
||||
|
||||
it('handles delete race condition', function() {
|
||||
spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
|
||||
var result = $q.defer();
|
||||
result.resolve({some: 'thing', failed: [], deleted: [{id: 1}]});
|
||||
ctrl.resultHandler(result.promise);
|
||||
deferred.resolve({data: {some: 'data'}});
|
||||
$timeout.flush();
|
||||
expect(ctrl.showDetails).toBe(undefined);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,61 @@
|
||||
<div class="page-header">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item-truncate"><translate>Project</translate></li>
|
||||
<li class="breadcrumb-item-truncate"><translate>Network</translate></li>
|
||||
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/"><translate>Load Balancers</translate></a></li>
|
||||
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}">{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</a></li>
|
||||
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}/listeners/{$ ::ctrl.listener.id $}">{$ ::(ctrl.listener.name || ctrl.listener.id) $}</a></li>
|
||||
<li class="breadcrumb-item-truncate active">{$ ::(ctrl.l7policy.name || ctrl.l7policy.id) $}</li>
|
||||
</ol>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-9 text-left">
|
||||
<ul class="list-inline">
|
||||
<li>
|
||||
<strong translate>Action</strong>
|
||||
{$ ::ctrl.l7policy.action | decode:ctrl.l7policyAction $}
|
||||
</li>
|
||||
<li>
|
||||
<strong translate>Operating Status</strong>
|
||||
{$ ctrl.l7policy.operating_status | decode:ctrl.operatingStatus $}
|
||||
</li>
|
||||
<li>
|
||||
<strong translate>Provisioning Status</strong>
|
||||
{$ ctrl.l7policy.provisioning_status | decode:ctrl.provisioningStatus $}
|
||||
</li>
|
||||
<li>
|
||||
<strong translate>Admin State Up</strong>
|
||||
{$ ctrl.l7policy.admin_state_up | yesno $}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-3 text-right details-item-actions">
|
||||
<actions allowed="ctrl.resourceType.itemActions"
|
||||
type="row"
|
||||
item="ctrl.l7policy"
|
||||
ng-if="ctrl.l7policy"
|
||||
class="actions_column pull-right"
|
||||
result-handler="ctrl.resultHandler"></actions>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<uib-tabset class="octavia-tabset">
|
||||
<uib-tab heading="{$ 'Overview' | translate $}">
|
||||
<div class="col-md-6 detail">
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Octavia::L7Policy"
|
||||
cls="dl-horizontal"
|
||||
item="ctrl.l7policy"
|
||||
property-groups="[[
|
||||
'id', 'name', 'description', 'project_id', 'created_at', 'updated_at',
|
||||
'redirect_pool_id', 'redirect_url', 'position', 'listener_id']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
</uib-tab>
|
||||
<uib-tab heading="{$ 'L7 Rules' | translate $}">
|
||||
<hz-resource-table resource-type-name="OS::Octavia::L7Rule"
|
||||
track-by="trackBy"
|
||||
list-function-extra-params="ctrl.listFunctionExtraParams">
|
||||
</hz-resource-table>
|
||||
</uib-tab>
|
||||
</uib-tabset>
|
@ -0,0 +1,9 @@
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Octavia::L7Policy"
|
||||
item="item"
|
||||
property-groups="[
|
||||
['name', 'id', 'project_id'],
|
||||
['created_at', 'updated_at', 'description'],
|
||||
['action', 'redirect_pool_id', 'redirect_url'],
|
||||
['position', 'listener_id']]">
|
||||
</hz-resource-property-list>
|
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @ngname horizon.dashboard.project.lbaasv2.l7policies
|
||||
*
|
||||
* @description
|
||||
* Provides the services and widgets required to support and display the project l7 policies
|
||||
* for the load balancers v2 panel.
|
||||
*/
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7policies', [])
|
||||
.constant('horizon.dashboard.project.lbaasv2.l7policies.resourceType',
|
||||
'OS::Octavia::L7Policy')
|
||||
.run(run);
|
||||
|
||||
run.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.dashboard.project.lbaasv2.basePath',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.service',
|
||||
'horizon.dashboard.project.lbaasv2.l7policies.actions.create',
|
||||
'horizon.dashboard.project.lbaasv2.l7policies.actions.edit',
|
||||
'horizon.dashboard.project.lbaasv2.l7policies.actions.delete',
|
||||
'horizon.dashboard.project.lbaasv2.l7policies.resourceType'
|
||||
];
|
||||
|
||||
function run(
|
||||
registry,
|
||||
basePath,
|
||||
loadBalancerService,
|
||||
createService,
|
||||
editService,
|
||||
deleteService,
|
||||
resourceType
|
||||
) {
|
||||
var l7policyResourceType = registry.getResourceType(resourceType);
|
||||
|
||||
l7policyResourceType
|
||||
.setNames(gettext('L7 Policy'), gettext('L7 Policies'))
|
||||
.setSummaryTemplateUrl(basePath + 'l7policies/details/drawer.html')
|
||||
.setProperties(l7policyProperties(loadBalancerService))
|
||||
.setListFunction(loadBalancerService.getL7PoliciesPromise)
|
||||
.setLoadFunction(loadBalancerService.getL7PolicyPromise)
|
||||
.tableColumns
|
||||
.append({
|
||||
id: 'name',
|
||||
priority: 1,
|
||||
urlFunction: loadBalancerService.getL7PolicyDetailsPath
|
||||
})
|
||||
.append({
|
||||
id: 'position',
|
||||
sortDefault: true,
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'action',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'operating_status',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'provisioning_status',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'admin_state_up',
|
||||
priority: 1
|
||||
});
|
||||
|
||||
l7policyResourceType.itemActions
|
||||
.append({
|
||||
id: 'l7policyEdit',
|
||||
service: editService,
|
||||
template: {
|
||||
text: gettext('Edit L7 Policy')
|
||||
}
|
||||
})
|
||||
.append({
|
||||
id: 'l7policyDelete',
|
||||
service: deleteService,
|
||||
template: {
|
||||
text: gettext('Delete L7 Policy'),
|
||||
type: 'delete'
|
||||
}
|
||||
});
|
||||
|
||||
l7policyResourceType.globalActions
|
||||
.append({
|
||||
id: 'l7policyCreate',
|
||||
service: createService,
|
||||
template: {
|
||||
type: 'create',
|
||||
text: gettext('Create L7 Policy')
|
||||
}
|
||||
});
|
||||
|
||||
l7policyResourceType.batchActions
|
||||
.append({
|
||||
id: 'l7policyBatchDelete',
|
||||
service: deleteService,
|
||||
template: {
|
||||
text: gettext('Delete L7 Policies'),
|
||||
type: 'delete-selected'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function l7policyProperties(loadBalancerService) {
|
||||
return {
|
||||
id: gettext('ID'),
|
||||
name: {
|
||||
label: gettext('Name'),
|
||||
filters: ['noName']
|
||||
},
|
||||
description: {
|
||||
label: gettext('Description'),
|
||||
filters: ['noValue']
|
||||
},
|
||||
provisioning_status: {
|
||||
label: gettext('Provisioning Status'),
|
||||
values: loadBalancerService.provisioningStatus
|
||||
},
|
||||
operating_status: {
|
||||
label: gettext('Operating Status'),
|
||||
values: loadBalancerService.operatingStatus
|
||||
},
|
||||
admin_state_up: {
|
||||
label: gettext('Admin State Up'),
|
||||
filters: ['yesno']
|
||||
},
|
||||
action: {
|
||||
label: gettext('Action'),
|
||||
values: loadBalancerService.l7policyAction
|
||||
},
|
||||
redirect_url: {
|
||||
label: gettext('Redirect URL'),
|
||||
filters: ['noName']
|
||||
},
|
||||
redirect_pool_id: {
|
||||
label: gettext('Redirect Pool ID'),
|
||||
filters: ['noName']
|
||||
},
|
||||
project_id: gettext('Project ID'),
|
||||
created_at: {
|
||||
label: gettext('Created At'),
|
||||
filters: ['noValue']
|
||||
},
|
||||
updated_at: {
|
||||
label: gettext('Updated At'),
|
||||
filters: ['noValue']
|
||||
},
|
||||
position: gettext('Position'),
|
||||
listener_id: gettext('Listener ID'),
|
||||
rules: gettext('Rules')
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 L7Policies Module', function() {
|
||||
it('should exist', function() {
|
||||
expect(angular.module('horizon.dashboard.project.lbaasv2.l7policies')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('LBaaS v2 L7Policies Registry', function () {
|
||||
var registry, resourceType;
|
||||
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
resourceType = $injector.get('horizon.dashboard.project.lbaasv2.l7policies.resourceType');
|
||||
registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
|
||||
}));
|
||||
|
||||
it('should define resourceType', function () {
|
||||
expect(resourceType).toBeDefined();
|
||||
});
|
||||
|
||||
it('should register item actions', function () {
|
||||
var actions = registry.getResourceType(resourceType).itemActions;
|
||||
expect(actionHasId(actions, 'l7policyEdit')).toBe(true);
|
||||
expect(actionHasId(actions, 'l7policyDelete')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register global actions', function () {
|
||||
var actions = registry.getResourceType(resourceType).globalActions;
|
||||
expect(actionHasId(actions, 'l7policyCreate')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register batch actions', function () {
|
||||
var actions = registry.getResourceType(resourceType).batchActions;
|
||||
expect(actionHasId(actions, 'l7policyBatchDelete')).toBe(true);
|
||||
});
|
||||
|
||||
function actionHasId(list, value) {
|
||||
return list.filter(matchesId).length === 1;
|
||||
|
||||
function matchesId(action) {
|
||||
if (action.id === value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7rules')
|
||||
.factory('horizon.dashboard.project.lbaasv2.l7rules.actions.create', createService);
|
||||
|
||||
createService.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.l7rules.resourceType',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'$q',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.modal',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngDoc factory
|
||||
* @name horizon.dashboard.project.lbaasv2.l7rules.actions.createService
|
||||
*
|
||||
* @description
|
||||
* Provides the service for creating a l7rule resource.
|
||||
*
|
||||
* @param resourceType The l7rule resource type.
|
||||
* @param actionResultService The horizon action result service.
|
||||
* @param $q The angular service for promises.
|
||||
* @param workflowModal The LBaaS workflow modal service.
|
||||
* @param policy The horizon policy service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
*
|
||||
* @returns The l7rule create service.
|
||||
*/
|
||||
|
||||
function createService(
|
||||
resourceType, actionResultService,
|
||||
$q, workflowModal, policy, gettext
|
||||
) {
|
||||
return workflowModal.init({
|
||||
controller: 'CreateL7RuleWizardController',
|
||||
message: gettext('A new l7 policy is being created.'),
|
||||
handle: handle,
|
||||
allowed: allowed
|
||||
});
|
||||
|
||||
//////////////
|
||||
|
||||
function allowed() {
|
||||
return $q.all([
|
||||
policy.ifAllowed({ rules: [['neutron', 'create_l7rule']] })
|
||||
]);
|
||||
}
|
||||
|
||||
function handle(response) {
|
||||
return actionResultService.getActionResult()
|
||||
.created(resourceType, response.data.id)
|
||||
.result;
|
||||
}
|
||||
}
|
||||
})();
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Create l7rule Action Service', function() {
|
||||
var policy, service;
|
||||
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('$modal', {
|
||||
open: function() {
|
||||
return {
|
||||
result: {
|
||||
then: function(func) {
|
||||
func({ data: { id: 'listener1' } });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
$provide.value('$routeParams', {});
|
||||
}));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
service = $injector.get('horizon.dashboard.project.lbaasv2.l7rules.actions.create');
|
||||
}));
|
||||
|
||||
it('should not allow creating a l7rule if listenerId is not present', function() {
|
||||
spyOn(policy, 'ifAllowed').and.returnValue(true);
|
||||
var allowed = service.allowed();
|
||||
permissionShouldFail(allowed);
|
||||
});
|
||||
|
||||
it('should handle the action result properly', function() {
|
||||
var result = service.handle({data: {id: 1}});
|
||||
expect(result.created[0].id).toBe(1);
|
||||
});
|
||||
|
||||
function permissionShouldFail(permissions) {
|
||||
permissions.then(
|
||||
function() {
|
||||
expect(false).toBe(true);
|
||||
},
|
||||
function() {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7rules')
|
||||
.controller('CreateL7RuleWizardController', CreateL7RuleWizardController);
|
||||
|
||||
CreateL7RuleWizardController.$inject = [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.model',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.workflow',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function CreateL7RuleWizardController($scope, $routeParams, model, workflowService, gettext) {
|
||||
var loadbalancerId = $routeParams.loadbalancerId;
|
||||
var l7policyId = $routeParams.l7policyId;
|
||||
var scope = $scope;
|
||||
scope.model = model;
|
||||
scope.submit = scope.model.submit;
|
||||
scope.workflow = workflowService(
|
||||
gettext('Create L7 Rule'),
|
||||
'fa fa-cloud-download',
|
||||
['l7rule']
|
||||
);
|
||||
scope.model.initialize('l7rule', false, loadbalancerId, l7policyId);
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Create L7Rule Wizard Controller', function() {
|
||||
var ctrl;
|
||||
var model = {
|
||||
submit: function() {
|
||||
return 'created';
|
||||
},
|
||||
initialize: angular.noop
|
||||
};
|
||||
var workflow = function() {
|
||||
return 'foo';
|
||||
};
|
||||
var scope = {
|
||||
launchContext: {id: '1234'}
|
||||
};
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module(function ($provide) {
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.model', model);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.workflow', workflow);
|
||||
}));
|
||||
beforeEach(inject(function ($controller) {
|
||||
spyOn(model, 'initialize');
|
||||
ctrl = $controller('CreateL7RuleWizardController', { $scope: scope });
|
||||
}));
|
||||
|
||||
it('defines the controller', function() {
|
||||
expect(ctrl).toBeDefined();
|
||||
});
|
||||
|
||||
it('calls initialize on the given model', function() {
|
||||
expect(model.initialize).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('sets scope.workflow to the given workflow', function() {
|
||||
expect(scope.workflow).toBe('foo');
|
||||
});
|
||||
|
||||
it('defines scope.submit', function() {
|
||||
expect(scope.submit).toBeDefined();
|
||||
expect(scope.submit()).toBe('created');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7rules')
|
||||
.factory('horizon.dashboard.project.lbaasv2.l7rules.actions.delete', deleteService);
|
||||
|
||||
deleteService.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.l7rules.resourceType',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'$location',
|
||||
'horizon.framework.widgets.modal.deleteModalService',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.app.core.openstack-service-api.policy'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngDoc factory
|
||||
* @name horizon.dashboard.project.lbaasv2.l7rules.actions.deleteService
|
||||
*
|
||||
* @description
|
||||
* Brings up the delete l7rule confirmation modal dialog.
|
||||
* On submit, deletes selected l7rule.
|
||||
* On cancel, does nothing.
|
||||
*
|
||||
* @param resourceType The l7rule resource type.
|
||||
* @param actionResultService The horizon action result service.
|
||||
* @param $location The angular $location service.
|
||||
* @param deleteModal The horizon delete modal service.
|
||||
* @param api The LBaaS v2 API service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @param policy The horizon policy service.
|
||||
*
|
||||
* @returns The l7rule delete service.
|
||||
*/
|
||||
|
||||
function deleteService(
|
||||
resourceType, actionResultService, $location,
|
||||
deleteModal, api, gettext, policy
|
||||
) {
|
||||
var loadbalancerId, listenerId, l7policyId;
|
||||
|
||||
var service = {
|
||||
perform: perform,
|
||||
allowed: allowed,
|
||||
deleteResult: deleteResult // exposed just for testing
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
//////////////
|
||||
|
||||
function allowed(/*item*/) {
|
||||
// This rule is made up and should therefore always pass. I assume at some point there
|
||||
// will be a valid rule similar to this that we will want to use.
|
||||
return policy.ifAllowed({ rules: [['neutron', 'delete_l7rule']] });
|
||||
}
|
||||
|
||||
function perform(items, scope) {
|
||||
var context = { };
|
||||
var l7rules = angular.isArray(items) ? items : [items];
|
||||
context.labels = labelize(l7rules.length);
|
||||
context.deleteEntity = deleteItem;
|
||||
l7rules.map(function(item) {
|
||||
loadbalancerId = item.loadbalancerId;
|
||||
listenerId = item.listenerId;
|
||||
l7policyId = item.l7policyId;
|
||||
});
|
||||
return deleteModal.open(scope, l7rules, context).then(deleteResult);
|
||||
}
|
||||
|
||||
function labelize(count) {
|
||||
return {
|
||||
title: ngettext(
|
||||
'Confirm Delete L7 Rule',
|
||||
'Confirm Delete L7 Rules', count),
|
||||
|
||||
message: ngettext(
|
||||
'You have selected "%s". Deleted L7 Rule is not recoverable.',
|
||||
'You have selected "%s". Deleted L7 Rules are not recoverable.', count),
|
||||
|
||||
submit: ngettext(
|
||||
'Delete L7 Rule',
|
||||
'Delete L7 Rules', count),
|
||||
|
||||
success: ngettext(
|
||||
'Deleted L7 Rule: %s.',
|
||||
'Deleted L7 Rules: %s.', count),
|
||||
|
||||
error: ngettext(
|
||||
'Unable to delete L7 Rule: %s.',
|
||||
'Unable to delete L7 Rules: %s.', count)
|
||||
};
|
||||
}
|
||||
|
||||
function deleteResult(deleteModalResult) {
|
||||
// To make the result of this action generically useful, reformat the return
|
||||
// from the deleteModal into a standard form
|
||||
var actionResult = actionResultService.getActionResult();
|
||||
deleteModalResult.pass.forEach(function markDeleted(item) {
|
||||
actionResult.deleted(resourceType, item.context.id);
|
||||
});
|
||||
deleteModalResult.fail.forEach(function markFailed(item) {
|
||||
actionResult.failed(resourceType, item.context.id);
|
||||
});
|
||||
|
||||
if (actionResult.result.failed.length === 0 && actionResult.result.deleted.length > 0) {
|
||||
var path = 'project/load_balancer/' + loadbalancerId +
|
||||
'/listeners/' + listenerId +
|
||||
'/l7policies/' + l7policyId;
|
||||
$location.path(path);
|
||||
}
|
||||
return actionResult.result;
|
||||
}
|
||||
|
||||
function deleteItem(id) {
|
||||
return api.deleteL7Rule(l7policyId, id, true);
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 L7Rule Delete Service', function() {
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module('horizon.framework'));
|
||||
|
||||
var deleteModalService, service, lbaasv2API, policyAPI, $location;
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
service = $injector.get('horizon.dashboard.project.lbaasv2.l7rules.actions.delete');
|
||||
lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
|
||||
deleteModalService = $injector.get('horizon.framework.widgets.modal.deleteModalService');
|
||||
policyAPI = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
$location = $injector.get('$location');
|
||||
}));
|
||||
|
||||
describe('perform method', function() {
|
||||
beforeEach(function () {
|
||||
// just need for this to return something that looks like a promise but does nothing
|
||||
spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
|
||||
});
|
||||
|
||||
it('should open the modal with correct label', function () {
|
||||
service.perform({name: 'spam'});
|
||||
var labels = deleteModalService.open.calls.argsFor(0)[2].labels;
|
||||
expect(deleteModalService.open).toHaveBeenCalled();
|
||||
angular.forEach(labels, function eachLabel(label) {
|
||||
expect(label.toLowerCase()).toContain('l7 rule');
|
||||
});
|
||||
});
|
||||
|
||||
it('should open the delete modal with correct entities', function () {
|
||||
service.perform([{name: 'one'}, {name: 'two'}]);
|
||||
var entities = deleteModalService.open.calls.argsFor(0)[1];
|
||||
expect(deleteModalService.open).toHaveBeenCalled();
|
||||
expect(entities.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('should pass in a function that deletes a l7 rule', function () {
|
||||
spyOn(lbaasv2API, 'deleteL7Rule').and.callFake(angular.noop);
|
||||
service.perform({l7policyId: 2, id: 1, name: 'one'});
|
||||
var contextArg = deleteModalService.open.calls.argsFor(0)[2];
|
||||
var deleteFunction = contextArg.deleteEntity;
|
||||
deleteFunction(1);
|
||||
expect(lbaasv2API.deleteL7Rule).toHaveBeenCalledWith(2, 1, true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle the action result properly', function() {
|
||||
spyOn($location, 'path');
|
||||
spyOn(deleteModalService, 'open').and.returnValue({then: angular.noop});
|
||||
spyOn(lbaasv2API, 'deleteL7Rule').and.callFake(angular.noop);
|
||||
service.perform({loadbalancerId: 1, listenerId: 2, l7policyId: 3, id: 1, name: 'one'});
|
||||
var result = service.deleteResult({
|
||||
fail: [],
|
||||
pass: [{
|
||||
context: {
|
||||
id: 1
|
||||
}
|
||||
}]
|
||||
});
|
||||
var path = 'project/load_balancer/1/listeners/2/l7policies/3';
|
||||
expect($location.path).toHaveBeenCalledWith(path);
|
||||
expect(result.deleted[0].id).toBe(1);
|
||||
result = service.deleteResult({
|
||||
pass: [],
|
||||
fail: [{
|
||||
context: {
|
||||
id: 1
|
||||
}
|
||||
}]
|
||||
});
|
||||
expect(result.failed[0].id).toBe(1);
|
||||
});
|
||||
|
||||
describe('allow method', function() {
|
||||
it('should use default policy if batch action', function () {
|
||||
spyOn(policyAPI, 'ifAllowed');
|
||||
service.allowed();
|
||||
expect(policyAPI.ifAllowed).toHaveBeenCalled();
|
||||
});
|
||||
}); // end of allowed
|
||||
|
||||
}); // end of delete
|
||||
|
||||
})();
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7rules')
|
||||
.factory('horizon.dashboard.project.lbaasv2.l7rules.actions.edit', editService);
|
||||
|
||||
editService.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.l7rules.resourceType',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.modal',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngDoc factory
|
||||
* @name horizon.dashboard.project.lbaasv2.l7rules.actions.editService
|
||||
*
|
||||
* @description
|
||||
* Provides the service for editing a l7rule resource.
|
||||
*
|
||||
* @param resourceType The l7rule resource type.
|
||||
* @param actionResultService The horizon action result service.
|
||||
* @param workflowModal The LBaaS workflow modal service.
|
||||
* @param policy The horizon policy service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
*
|
||||
* @returns The l7rule edit service.
|
||||
*/
|
||||
|
||||
function editService(
|
||||
resourceType, actionResultService, workflowModal, policy, gettext
|
||||
) {
|
||||
|
||||
return workflowModal.init({
|
||||
controller: 'EditL7RuleWizardController',
|
||||
message: gettext('The l7rule has been updated.'),
|
||||
handle: handle,
|
||||
allowed: allowed
|
||||
});
|
||||
|
||||
function allowed(/*item*/) {
|
||||
return policy.ifAllowed({ rules: [['neutron', 'update_l7rule']] });
|
||||
}
|
||||
|
||||
function handle(response) {
|
||||
return actionResultService.getActionResult()
|
||||
.updated(resourceType, response.config.data.l7rule.id)
|
||||
.result;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Edit L7Rule Action Service', function() {
|
||||
var policy, service;
|
||||
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('$modal', {
|
||||
open: function() {
|
||||
return {
|
||||
result: {
|
||||
then: function(func) {
|
||||
func({ data: { id: 'l7rule1' } });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
service = $injector.get('horizon.dashboard.project.lbaasv2.l7rules.actions.edit');
|
||||
}));
|
||||
|
||||
it('should check policy to allow editing a l7rule', function() {
|
||||
spyOn(policy, 'ifAllowed').and.returnValue(true);
|
||||
expect(service.allowed()).toBe(true);
|
||||
expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'update_l7rule']]});
|
||||
});
|
||||
|
||||
it('should handle the action result properly', function() {
|
||||
var result = service.handle({config: {data: {l7rule: {id: 1}}}});
|
||||
expect(result.updated[0].id).toBe(1);
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.controller('EditL7RuleWizardController', EditL7RuleWizardController);
|
||||
|
||||
EditL7RuleWizardController.$inject = [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'$q',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.model',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.workflow',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name EditL7RuleWizardController
|
||||
*
|
||||
* @description
|
||||
* Controller for the LBaaS v2 edit l7rule wizard.
|
||||
*
|
||||
* @param $scope The angular scope object.
|
||||
* @param $routeParams The angular $routeParams service.
|
||||
* @param $q The angular service for promises.
|
||||
* @param model The LBaaS V2 workflow model service.
|
||||
* @param workflowService The LBaaS V2 workflow service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function EditL7RuleWizardController($scope, $routeParams, $q, model, workflowService, gettext) {
|
||||
var scope = $scope;
|
||||
var loadbalancerId = $routeParams.loadbalancerId;
|
||||
var l7policyId = $routeParams.l7policyId;
|
||||
scope.model = model;
|
||||
scope.submit = scope.model.submit;
|
||||
scope.workflow = workflowService(
|
||||
gettext('Update L7 Rule'),
|
||||
'fa fa-pencil', ['l7rule']);
|
||||
scope.model.initialize('l7rule', scope.launchContext.id, loadbalancerId, l7policyId);
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Edit L7Rule Wizard Controller', function() {
|
||||
var ctrl, workflowSpy, $q, scope;
|
||||
var model = {
|
||||
submit: function() {
|
||||
return 'updated';
|
||||
},
|
||||
initialize: function() {
|
||||
var defer = $q.defer();
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
}
|
||||
};
|
||||
var workflow = {
|
||||
steps: [{id: 'l7rule'}],
|
||||
append: angular.noop
|
||||
};
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module(function ($provide) {
|
||||
workflowSpy = jasmine.createSpy('workflow').and.returnValue(workflow);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.model', model);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.workflow', workflowSpy);
|
||||
}));
|
||||
beforeEach(inject(function ($controller, $injector) {
|
||||
$q = $injector.get('$q');
|
||||
scope = $injector.get('$rootScope').$new();
|
||||
scope.launchContext = { id: 'l7ruleId' };
|
||||
spyOn(model, 'initialize').and.callThrough();
|
||||
ctrl = $controller('EditL7RuleWizardController', {
|
||||
$scope: scope,
|
||||
$routeParams: {loadbalancerId: 'loadbalancerId', l7policyId: 'l7policyId'}});
|
||||
}));
|
||||
|
||||
it('defines the controller', function() {
|
||||
expect(ctrl).toBeDefined();
|
||||
});
|
||||
|
||||
it('calls initialize on the given model', function() {
|
||||
expect(model.initialize).toHaveBeenCalledWith(
|
||||
'l7rule', 'l7ruleId', 'loadbalancerId', 'l7policyId');
|
||||
});
|
||||
|
||||
it('sets scope.workflow to the given workflow', function() {
|
||||
expect(scope.workflow).toBe(workflow);
|
||||
});
|
||||
|
||||
it('initializes workflow with correct properties', function() {
|
||||
expect(workflowSpy).toHaveBeenCalledWith('Update L7 Rule',
|
||||
'fa fa-pencil', ['l7rule']);
|
||||
});
|
||||
|
||||
it('defines scope.submit', function() {
|
||||
expect(scope.submit).toBe(model.submit);
|
||||
expect(scope.submit()).toBe('updated');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7rules')
|
||||
.controller('L7RuleDetailController', L7RuleDetailController);
|
||||
|
||||
L7RuleDetailController.$inject = [
|
||||
'loadbalancer',
|
||||
'listener',
|
||||
'l7policy',
|
||||
'l7rule',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.service',
|
||||
'horizon.dashboard.project.lbaasv2.l7rules.resourceType',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.framework.widgets.modal-wait-spinner.service',
|
||||
'$q'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name L7RuleDetailController
|
||||
*
|
||||
* @description
|
||||
* Controller for the LBaaS v2 l7rule detail page.
|
||||
*
|
||||
* @param loadbalancer The loadbalancer object.
|
||||
* @param listener The listener object.
|
||||
* @param l7policy The l7policy object.
|
||||
* @param l7rule The l7rule object.
|
||||
* @param loadBalancersService The LBaaS v2 load balancers service.
|
||||
* @param resourceType The load balancer resource type.
|
||||
* @param typeRegistry The horizon type registry service.
|
||||
* @param spinnerService The horizon modal wait spinner service.
|
||||
* @param $q The angular service for promises.
|
||||
*
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function L7RuleDetailController(
|
||||
loadbalancer, listener, l7policy, l7rule, loadBalancersService,
|
||||
resourceType, typeRegistry, spinnerService, $q
|
||||
) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.operatingStatus = loadBalancersService.operatingStatus;
|
||||
ctrl.provisioningStatus = loadBalancersService.provisioningStatus;
|
||||
ctrl.l7ruleType = loadBalancersService.l7ruleType;
|
||||
ctrl.l7ruleCompareType = loadBalancersService.l7ruleCompareType;
|
||||
ctrl.loadbalancer = loadbalancer;
|
||||
ctrl.listener = listener;
|
||||
ctrl.l7policy = l7policy;
|
||||
ctrl.l7rule = l7rule;
|
||||
ctrl.listFunctionExtraParams = {
|
||||
loadbalancerId: ctrl.loadbalancer.id,
|
||||
listenerId: ctrl.listener.id,
|
||||
l7policyId: ctrl.l7policy.id,
|
||||
l7ruleId: ctrl.l7rule.id
|
||||
};
|
||||
ctrl.resourceType = typeRegistry.getResourceType(resourceType);
|
||||
ctrl.context = {};
|
||||
ctrl.context.l7policyId = l7policy.id;
|
||||
ctrl.context.l7ruleId = l7rule.id;
|
||||
|
||||
ctrl.resultHandler = actionResultHandler;
|
||||
|
||||
function actionResultHandler(returnValue) {
|
||||
return $q.when(returnValue, actionSuccessHandler);
|
||||
}
|
||||
|
||||
function loadData(response) {
|
||||
spinnerService.hideModalSpinner();
|
||||
ctrl.showDetails = true;
|
||||
ctrl.resourceType.initActions();
|
||||
ctrl.l7rule = response.data;
|
||||
ctrl.l7rule.loadbalancerId = ctrl.loadbalancer.id;
|
||||
ctrl.l7rule.listenerId = ctrl.listener.id;
|
||||
ctrl.l7rule.l7policyId = ctrl.l7policy.id;
|
||||
}
|
||||
|
||||
function actionSuccessHandler(result) {
|
||||
// The action has completed (for whatever "complete" means to that
|
||||
// action. Notice the view doesn't really need to know the semantics of the
|
||||
// particular action because the actions return data in a standard form.
|
||||
// That return includes the id and type of each created, updated, deleted
|
||||
// and failed item.
|
||||
// Currently just refreshes the display each time.
|
||||
if (result) {
|
||||
if (result.failed.length === 0 && result.deleted.length > 0) {
|
||||
// handle a race condition where the resource is already deleted
|
||||
return;
|
||||
}
|
||||
spinnerService.showModalSpinner(gettext('Please Wait'));
|
||||
ctrl.showDetails = false;
|
||||
ctrl.context.loadPromise = ctrl.resourceType.load(
|
||||
ctrl.context.l7policyId,
|
||||
ctrl.context.l7ruleId
|
||||
);
|
||||
ctrl.context.loadPromise.then(loadData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 L7Rule Detail Controller', function() {
|
||||
var deferred, service, ctrl, scope, $timeout, $q, actionResultService;
|
||||
|
||||
///////////////////////
|
||||
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('$uibModal', {});
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($controller, $rootScope, _$q_, _$timeout_) {
|
||||
$q = _$q_;
|
||||
deferred = $q.defer();
|
||||
service = {
|
||||
getResourceType: function() {
|
||||
return {
|
||||
load: function() { return deferred.promise; },
|
||||
parsePath: function() { return 'my-context'; },
|
||||
itemName: function() { return 'A name'; },
|
||||
initActions: angular.noop
|
||||
};
|
||||
},
|
||||
getDefaultDetailsTemplateUrl: angular.noop
|
||||
};
|
||||
actionResultService = {
|
||||
getIdsOfType: function() { return []; }
|
||||
};
|
||||
$timeout = _$timeout_;
|
||||
scope = $rootScope.$new();
|
||||
ctrl = $controller('L7RuleDetailController', {
|
||||
$scope: scope,
|
||||
loadbalancer: { id: '123' },
|
||||
listener: { id: '123' },
|
||||
l7policy: { id: '123' },
|
||||
l7rule: { id: '123' },
|
||||
'horizon.framework.conf.resource-type-registry.service': service,
|
||||
'horizon.framework.util.actions.action-result.service': actionResultService,
|
||||
'horizon.framework.widgets.modal-wait-spinner.service': {
|
||||
showModalSpinner: angular.noop,
|
||||
hideModalSpinner: angular.noop
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create a controller', function() {
|
||||
expect(ctrl).toBeDefined();
|
||||
expect(ctrl.loadbalancer).toBeDefined();
|
||||
expect(ctrl.listener).toBeDefined();
|
||||
expect(ctrl.l7policy).toBeDefined();
|
||||
expect(ctrl.l7rule).toBeDefined();
|
||||
});
|
||||
|
||||
describe('resultHandler', function() {
|
||||
|
||||
it('handles empty results', function() {
|
||||
var result = $q.defer();
|
||||
result.resolve({failed: [], deleted: []});
|
||||
ctrl.resultHandler(result.promise);
|
||||
$timeout.flush();
|
||||
expect(ctrl.showDetails).not.toBe(true);
|
||||
});
|
||||
|
||||
it('handles falsy results', function() {
|
||||
var result = $q.defer();
|
||||
result.resolve(false);
|
||||
ctrl.resultHandler(result.promise);
|
||||
$timeout.flush();
|
||||
expect(ctrl.showDetails).not.toBe(true);
|
||||
});
|
||||
|
||||
it('handles matched results', function() {
|
||||
spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
|
||||
var result = $q.defer();
|
||||
result.resolve({some: 'thing', failed: [], deleted: []});
|
||||
ctrl.resultHandler(result.promise);
|
||||
deferred.resolve({data: {some: 'data'}});
|
||||
$timeout.flush();
|
||||
expect(ctrl.showDetails).toBe(true);
|
||||
});
|
||||
|
||||
it('handles delete race condition', function() {
|
||||
spyOn(actionResultService, 'getIdsOfType').and.returnValue([1, 2, 3]);
|
||||
var result = $q.defer();
|
||||
result.resolve({some: 'thing', failed: [], deleted: [{id: 1}]});
|
||||
ctrl.resultHandler(result.promise);
|
||||
deferred.resolve({data: {some: 'data'}});
|
||||
$timeout.flush();
|
||||
expect(ctrl.showDetails).toBe(undefined);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,54 @@
|
||||
<div class="page-header">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item-truncate"><translate>Project</translate></li>
|
||||
<li class="breadcrumb-item-truncate"><translate>Network</translate></li>
|
||||
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/"><translate>Load Balancers</translate></a></li>
|
||||
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}">{$ ::(ctrl.loadbalancer.name || ctrl.loadbalancer.id) $}</a></li>
|
||||
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}/listeners/{$ ::ctrl.listener.id $}">{$ ::(ctrl.listener.name || ctrl.listener.id) $}</a></li>
|
||||
<li class="breadcrumb-item-truncate"><a href="project/load_balancer/{$ ::ctrl.loadbalancer.id $}/listeners/{$ ::ctrl.listener.id $}/l7policies/{$ ::ctrl.l7policy.id $}">{$ ::(ctrl.l7policy.name || ctrl.l7policy.id) $}</a></li>
|
||||
<li class="breadcrumb-item-truncate active">{$ :: ctrl.l7rule.id $}</li>
|
||||
</ol>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-9 text-left">
|
||||
<ul class="list-inline">
|
||||
<li>
|
||||
<strong translate>Type</strong>
|
||||
{$ ::ctrl.l7rule.type | decode:ctrl.l7ruleType $}
|
||||
</li>
|
||||
<li>
|
||||
<strong translate>Operating Status</strong>
|
||||
{$ ctrl.l7rule.operating_status | decode:ctrl.operatingStatus $}
|
||||
</li>
|
||||
<li>
|
||||
<strong translate>Provisioning Status</strong>
|
||||
{$ ctrl.l7rule.provisioning_status | decode:ctrl.provisioningStatus $}
|
||||
</li>
|
||||
<li>
|
||||
<strong translate>Admin State Up</strong>
|
||||
{$ ctrl.l7rule.admin_state_up | yesno $}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-3 text-right details-item-actions">
|
||||
<actions allowed="ctrl.resourceType.itemActions"
|
||||
type="row"
|
||||
item="ctrl.l7rule"
|
||||
ng-if="ctrl.l7rule"
|
||||
class="actions_column pull-right"
|
||||
result-handler="ctrl.resultHandler"></actions>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 detail">
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Octavia::L7Rule"
|
||||
cls="dl-horizontal"
|
||||
item="ctrl.l7rule"
|
||||
property-groups="[[
|
||||
'id', 'compare_type', 'project_id', 'created_at', 'updated_at',
|
||||
'key', 'rule_value', 'invert']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
</div?
|
@ -0,0 +1,8 @@
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Octavia::L7Rule"
|
||||
item="item"
|
||||
property-groups="[
|
||||
['type', 'id', 'project_id'],
|
||||
['created_at', 'updated_at', 'compare_type'],
|
||||
['key', 'rule_value', 'invert']]">
|
||||
</hz-resource-property-list>
|
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @ngname horizon.dashboard.project.lbaasv2.l7rules
|
||||
*
|
||||
* @description
|
||||
* Provides the services and widgets required to support and display the project l7 rules
|
||||
* for the load balancers v2 panel.
|
||||
*/
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.l7rules', [])
|
||||
.constant('horizon.dashboard.project.lbaasv2.l7rules.resourceType',
|
||||
'OS::Octavia::L7Rule')
|
||||
.run(run);
|
||||
|
||||
run.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.dashboard.project.lbaasv2.basePath',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.service',
|
||||
'horizon.dashboard.project.lbaasv2.l7rules.actions.create',
|
||||
'horizon.dashboard.project.lbaasv2.l7rules.actions.edit',
|
||||
'horizon.dashboard.project.lbaasv2.l7rules.actions.delete',
|
||||
'horizon.dashboard.project.lbaasv2.l7rules.resourceType'
|
||||
];
|
||||
|
||||
function run(
|
||||
registry,
|
||||
basePath,
|
||||
loadBalancerService,
|
||||
createService,
|
||||
editService,
|
||||
deleteService,
|
||||
resourceType
|
||||
) {
|
||||
var l7ruleResourceType = registry.getResourceType(resourceType);
|
||||
|
||||
l7ruleResourceType
|
||||
.setNames(gettext('L7 Rule'), gettext('L7 Rules'))
|
||||
.setSummaryTemplateUrl(basePath + 'l7rules/details/drawer.html')
|
||||
.setProperties(l7ruleProperties(loadBalancerService))
|
||||
.setListFunction(loadBalancerService.getL7RulesPromise)
|
||||
.setLoadFunction(loadBalancerService.getL7RulePromise)
|
||||
.tableColumns
|
||||
.append({
|
||||
id: 'type',
|
||||
priority: 1,
|
||||
urlFunction: loadBalancerService.getL7RuleDetailsPath
|
||||
})
|
||||
.append({
|
||||
id: 'compare_type',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'key',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'rule_value',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'invert',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'operating_status',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'provisioning_status',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'admin_state_up',
|
||||
priority: 1
|
||||
});
|
||||
|
||||
l7ruleResourceType.itemActions
|
||||
.append({
|
||||
id: 'l7ruleEdit',
|
||||
service: editService,
|
||||
template: {
|
||||
text: gettext('Edit L7 Rule')
|
||||
}
|
||||
})
|
||||
.append({
|
||||
id: 'l7ruleDelete',
|
||||
service: deleteService,
|
||||
template: {
|
||||
text: gettext('Delete L7 Rule'),
|
||||
type: 'delete'
|
||||
}
|
||||
});
|
||||
|
||||
l7ruleResourceType.globalActions
|
||||
.append({
|
||||
id: 'l7ruleCreate',
|
||||
service: createService,
|
||||
template: {
|
||||
type: 'create',
|
||||
text: gettext('Create L7 Rule')
|
||||
}
|
||||
});
|
||||
|
||||
l7ruleResourceType.batchActions
|
||||
.append({
|
||||
id: 'l7ruleBatchDelete',
|
||||
service: deleteService,
|
||||
template: {
|
||||
text: gettext('Delete L7 Rules'),
|
||||
type: 'delete-selected'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function l7ruleProperties(loadBalancerService) {
|
||||
return {
|
||||
id: gettext('ID'),
|
||||
type: {
|
||||
label: gettext('Type'),
|
||||
values: loadBalancerService.l7ruleType
|
||||
},
|
||||
compare_type: {
|
||||
label: gettext('Compare Type'),
|
||||
values: loadBalancerService.l7ruleCompareType
|
||||
},
|
||||
provisioning_status: {
|
||||
label: gettext('Provisioning Status'),
|
||||
values: loadBalancerService.provisioningStatus
|
||||
},
|
||||
operating_status: {
|
||||
label: gettext('Operating Status'),
|
||||
values: loadBalancerService.operatingStatus
|
||||
},
|
||||
admin_state_up: {
|
||||
label: gettext('Admin State Up'),
|
||||
filters: ['yesno']
|
||||
},
|
||||
key: {
|
||||
label: gettext('Key'),
|
||||
filters: ['noName']
|
||||
},
|
||||
rule_value: {
|
||||
label: gettext('Value'),
|
||||
filters: ['noName']
|
||||
},
|
||||
invert: {
|
||||
label: gettext('Invert'),
|
||||
filters: ['yesno']
|
||||
},
|
||||
project_id: gettext('Project ID'),
|
||||
created_at: {
|
||||
label: gettext('Created At'),
|
||||
filters: ['noValue']
|
||||
},
|
||||
updated_at: {
|
||||
label: gettext('Updated At'),
|
||||
filters: ['noValue']
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 L7Rules Module', function() {
|
||||
it('should exist', function() {
|
||||
expect(angular.module('horizon.dashboard.project.lbaasv2.l7rules')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('LBaaS v2 L7Rules Registry', function () {
|
||||
var registry, resourceType;
|
||||
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
resourceType = $injector.get('horizon.dashboard.project.lbaasv2.l7rules.resourceType');
|
||||
registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
|
||||
}));
|
||||
|
||||
it('should define resourceType', function () {
|
||||
expect(resourceType).toBeDefined();
|
||||
});
|
||||
|
||||
it('should register item actions', function () {
|
||||
var actions = registry.getResourceType(resourceType).itemActions;
|
||||
expect(actionHasId(actions, 'l7ruleEdit')).toBe(true);
|
||||
expect(actionHasId(actions, 'l7ruleDelete')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register global actions', function () {
|
||||
var actions = registry.getResourceType(resourceType).globalActions;
|
||||
expect(actionHasId(actions, 'l7ruleCreate')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register batch actions', function () {
|
||||
var actions = registry.getResourceType(resourceType).batchActions;
|
||||
expect(actionHasId(actions, 'l7ruleBatchDelete')).toBe(true);
|
||||
});
|
||||
|
||||
function actionHasId(list, value) {
|
||||
return list.filter(matchesId).length === 1;
|
||||
|
||||
function matchesId(action) {
|
||||
if (action.id === value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})();
|
@ -28,6 +28,8 @@
|
||||
.module('horizon.dashboard.project.lbaasv2', [
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers',
|
||||
'horizon.dashboard.project.lbaasv2.listeners',
|
||||
'horizon.dashboard.project.lbaasv2.l7policies',
|
||||
'horizon.dashboard.project.lbaasv2.l7rules',
|
||||
'horizon.dashboard.project.lbaasv2.pools',
|
||||
'horizon.dashboard.project.lbaasv2.members',
|
||||
'horizon.dashboard.project.lbaasv2.healthmonitors',
|
||||
@ -68,6 +70,8 @@
|
||||
|
||||
var loadbalancers = '/project/load_balancer';
|
||||
var listener = loadbalancers + '/:loadbalancerId/listeners/:listenerId';
|
||||
var listenerL7Policy = listener + '/l7policies/:l7policyId';
|
||||
var listenerL7Rule = listenerL7Policy + '/l7rules/:l7ruleId';
|
||||
var listenerPool = listener + '/pools/:poolId';
|
||||
var listenerPoolMember = listenerPool + '/members/:memberId';
|
||||
var listenerPoolHealthmonitor = listenerPool + '/healthmonitors/:healthmonitorId';
|
||||
@ -129,6 +133,105 @@
|
||||
controller: 'ListenerDetailController',
|
||||
controllerAs: 'ctrl'
|
||||
})
|
||||
.when(listenerL7Policy, {
|
||||
templateUrl: basePath + 'l7policies/details/detail.html',
|
||||
resolve: {
|
||||
loadbalancer: [
|
||||
'$route',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
function($route, api) {
|
||||
return api.getLoadBalancer($route.current.params.loadbalancerId, true).then(
|
||||
function success(response) {
|
||||
response.data.floating_ip_address = response.data.floating_ip.ip;
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
listener: [
|
||||
'$route',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
function($route, api) {
|
||||
return api.getListener($route.current.params.listenerId).then(
|
||||
function success(response) {
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
l7policy: [
|
||||
'$route',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
function($route, api) {
|
||||
return api.getL7Policy($route.current.params.l7policyId).then(
|
||||
function success(response) {
|
||||
response.data.loadbalancerId = $route.current.params.loadbalancerId;
|
||||
response.data.listenerId = $route.current.params.listenerId;
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
]
|
||||
},
|
||||
controller: 'L7PolicyDetailController',
|
||||
controllerAs: 'ctrl'
|
||||
})
|
||||
.when(listenerL7Rule, {
|
||||
templateUrl: basePath + 'l7rules/details/detail.html',
|
||||
resolve: {
|
||||
loadbalancer: [
|
||||
'$route',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
function($route, api) {
|
||||
return api.getLoadBalancer($route.current.params.loadbalancerId, true).then(
|
||||
function success(response) {
|
||||
response.data.floating_ip_address = response.data.floating_ip.ip;
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
listener: [
|
||||
'$route',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
function($route, api) {
|
||||
return api.getListener($route.current.params.listenerId).then(
|
||||
function success(response) {
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
l7policy: [
|
||||
'$route',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
function($route, api) {
|
||||
return api.getL7Policy($route.current.params.l7policyId).then(
|
||||
function success(response) {
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
l7rule: [
|
||||
'$route',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2',
|
||||
function($route, api) {
|
||||
return api.getL7Rule($route.current.params.l7policyId,
|
||||
$route.current.params.l7ruleId).then(
|
||||
function success(response) {
|
||||
response.data.loadbalancerId = $route.current.params.loadbalancerId;
|
||||
response.data.listenerId = $route.current.params.listenerId;
|
||||
response.data.l7policyId = $route.current.params.l7policyId;
|
||||
return response.data;
|
||||
}
|
||||
);
|
||||
}
|
||||
]
|
||||
},
|
||||
controller: 'L7RuleDetailController',
|
||||
controllerAs: 'ctrl'
|
||||
})
|
||||
.when(listenerPool, {
|
||||
templateUrl: basePath + 'pools/details/detail.html',
|
||||
resolve: {
|
||||
|
@ -233,6 +233,121 @@
|
||||
});
|
||||
}));
|
||||
|
||||
it('should route resolved listener l7 policy detail', inject(function($injector) {
|
||||
function loadbalancerAPI() {
|
||||
var loadbalancer = { provisioning_status: 'ACTIVE' };
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback(loadbalancer);
|
||||
},
|
||||
then: function(callback) {
|
||||
callback({ data: { id: 1, floating_ip: {}}});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function listenerAPI() {
|
||||
var listener = { provisioning_status: 'ACTIVE' };
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback(listener);
|
||||
},
|
||||
then: function(callback) {
|
||||
callback({ data: { id: 1}});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function l7policyAPI() {
|
||||
var l7policy = { provisioning_status: 'ACTIVE' };
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback(l7policy);
|
||||
},
|
||||
then: function(callback) {
|
||||
callback({ data: { id: 1}});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
|
||||
spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
|
||||
spyOn(lbaasv2API, 'getListener').and.callFake(listenerAPI);
|
||||
spyOn(lbaasv2API, 'getL7Policy').and.callFake(l7policyAPI);
|
||||
inject(function($route, $location, $rootScope, $httpBackend) {
|
||||
$httpBackend.expectGET(
|
||||
'/static/dashboard/project/lbaasv2/l7policies/details/detail.html'
|
||||
).respond({});
|
||||
$location.path('/project/load_balancer/1/listeners/2/l7policies/3');
|
||||
$rootScope.$digest();
|
||||
expect($route.current).toBeDefined();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should route resolved listener l7 rule detail', inject(function($injector) {
|
||||
function loadbalancerAPI() {
|
||||
var loadbalancer = { provisioning_status: 'ACTIVE' };
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback(loadbalancer);
|
||||
},
|
||||
then: function(callback) {
|
||||
callback({ data: { id: 1, floating_ip: {}}});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function listenerAPI() {
|
||||
var listener = { provisioning_status: 'ACTIVE' };
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback(listener);
|
||||
},
|
||||
then: function(callback) {
|
||||
callback({ data: { id: 1}});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function l7policyAPI() {
|
||||
var l7policy = { provisioning_status: 'ACTIVE' };
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback(l7policy);
|
||||
},
|
||||
then: function(callback) {
|
||||
callback({ data: { id: 1}});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function l7ruleAPI() {
|
||||
var l7rule = { provisioning_status: 'ACTIVE' };
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback(l7rule);
|
||||
},
|
||||
then: function(callback) {
|
||||
callback({ data: { id: 1}});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
|
||||
spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI);
|
||||
spyOn(lbaasv2API, 'getListener').and.callFake(listenerAPI);
|
||||
spyOn(lbaasv2API, 'getL7Policy').and.callFake(l7policyAPI);
|
||||
spyOn(lbaasv2API, 'getL7Rule').and.callFake(l7ruleAPI);
|
||||
inject(function($route, $location, $rootScope, $httpBackend) {
|
||||
$httpBackend.expectGET(
|
||||
'/static/dashboard/project/lbaasv2/l7rules/details/detail.html'
|
||||
).respond({});
|
||||
$location.path('/project/load_balancer/1/listeners/2/l7policies/3/l7rules/4');
|
||||
$rootScope.$digest();
|
||||
expect($route.current).toBeDefined();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should route resolved listener pool member detail', inject(function($injector) {
|
||||
function loadbalancerAPI() {
|
||||
var loadbalancer = { provisioning_status: 'ACTIVE' };
|
||||
|
@ -61,4 +61,10 @@
|
||||
list-function-extra-params="ctrl.listFunctionExtraParams">
|
||||
</hz-resource-table>
|
||||
</uib-tab>
|
||||
<uib-tab heading="{$ 'L7 Policies' | translate $}">
|
||||
<hz-resource-table resource-type-name="OS::Octavia::L7Policy"
|
||||
track-by="trackBy"
|
||||
list-function-extra-params="ctrl.listFunctionExtraParams">
|
||||
</hz-resource-table>
|
||||
</uib-tab>
|
||||
</uib-tabset>
|
||||
|
@ -33,7 +33,11 @@
|
||||
// the wizard continues to work. Using local var to appease eslint angular/ng_controller_as.
|
||||
scope.model = model;
|
||||
scope.submit = scope.model.submit;
|
||||
scope.workflow = workflowService(gettext('Create Load Balancer'), 'fa fa-cloud-download');
|
||||
scope.workflow = workflowService(
|
||||
gettext('Create Load Balancer'),
|
||||
'fa fa-cloud-download',
|
||||
['loadbalancer', 'listener', 'certificates', 'pool', 'members', 'monitor']
|
||||
);
|
||||
scope.model.initialize('loadbalancer');
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,28 @@
|
||||
SOURCE_IP: gettext('Source IP')
|
||||
};
|
||||
|
||||
var l7policyAction = {
|
||||
REJECT: gettext('Reject'),
|
||||
REDIRECT_TO_URL: gettext('Redirect to URL'),
|
||||
REDIRECT_TO_POOL: gettext('Redirect to Pool')
|
||||
};
|
||||
|
||||
var l7ruleType = {
|
||||
HOST_NAME: gettext('Host Name'),
|
||||
PATH: gettext('Path'),
|
||||
FILE_TYPE: gettext('File Type'),
|
||||
HEADER: gettext('Header'),
|
||||
COOKIE: gettext('Cookie')
|
||||
};
|
||||
|
||||
var l7ruleCompareType = {
|
||||
REGEX: gettext('Regex'),
|
||||
STARTS_WITH: gettext('Starts With'),
|
||||
ENDS_WITH: gettext('Ends With'),
|
||||
CONTAINS: gettext('Contains'),
|
||||
EQUAL_TO: gettext('Equal To')
|
||||
};
|
||||
|
||||
var none = {
|
||||
null: gettext('None')
|
||||
};
|
||||
@ -72,6 +94,9 @@
|
||||
operatingStatus: operatingStatus,
|
||||
provisioningStatus: provisioningStatus,
|
||||
loadBalancerAlgorithm: loadBalancerAlgorithm,
|
||||
l7policyAction: l7policyAction,
|
||||
l7ruleType: l7ruleType,
|
||||
l7ruleCompareType: l7ruleCompareType,
|
||||
none: none,
|
||||
nullFilter: nullFilter,
|
||||
getLoadBalancersPromise: getLoadBalancersPromise,
|
||||
@ -80,6 +105,12 @@
|
||||
getListenersPromise: getListenersPromise,
|
||||
getListenerPromise: getListenerPromise,
|
||||
getListenerDetailsPath: getListenerDetailsPath,
|
||||
getL7PoliciesPromise: getL7PoliciesPromise,
|
||||
getL7PolicyPromise: getL7PolicyPromise,
|
||||
getL7PolicyDetailsPath: getL7PolicyDetailsPath,
|
||||
getL7RulesPromise: getL7RulesPromise,
|
||||
getL7RulePromise: getL7RulePromise,
|
||||
getL7RuleDetailsPath: getL7RuleDetailsPath,
|
||||
getPoolsPromise: getPoolsPromise,
|
||||
getPoolPromise: getPoolPromise,
|
||||
getPoolDetailsPath: getPoolDetailsPath,
|
||||
@ -200,6 +231,58 @@
|
||||
}
|
||||
}
|
||||
|
||||
function getL7RulesPromise(params) {
|
||||
return api.getL7Rules(params.l7policyId).then(modifyResponse);
|
||||
|
||||
function modifyResponse(response) {
|
||||
return {data: {items: response.data.items.map(modifyItem)}};
|
||||
|
||||
function modifyItem(item) {
|
||||
item.trackBy = item.id + item.updated_at;
|
||||
item.loadbalancerId = params.loadbalancerId;
|
||||
item.listenerId = params.listenerId;
|
||||
item.l7policyId = params.l7policyId;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getL7RulePromise(l7policyId, l7ruleId) {
|
||||
return api.getL7Rule(l7policyId, l7ruleId);
|
||||
}
|
||||
|
||||
function getL7RuleDetailsPath(item) {
|
||||
return 'project/load_balancer/' +
|
||||
item.loadbalancerId + '/listeners/' +
|
||||
item.listenerId + '/l7policies/' +
|
||||
item.l7policyId + '/l7rules/' + item.id;
|
||||
}
|
||||
|
||||
function getL7PoliciesPromise(params) {
|
||||
return api.getL7Policies(params.listenerId).then(modifyResponse);
|
||||
|
||||
function modifyResponse(response) {
|
||||
return {data: {items: response.data.items.map(modifyItem)}};
|
||||
|
||||
function modifyItem(item) {
|
||||
item.trackBy = item.id + item.updated_at;
|
||||
item.loadbalancerId = params.loadbalancerId;
|
||||
item.listenerId = params.listenerId;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getL7PolicyPromise(identifier) {
|
||||
return api.getL7Policy(identifier);
|
||||
}
|
||||
|
||||
function getL7PolicyDetailsPath(item) {
|
||||
return 'project/load_balancer/' +
|
||||
item.loadbalancerId + '/listeners/' +
|
||||
item.listenerId + '/l7policies/' + item.id;
|
||||
}
|
||||
|
||||
function getListenersPromise(params) {
|
||||
return api.getListeners(params.loadbalancerId).then(modifyResponse);
|
||||
|
||||
|
@ -91,6 +91,61 @@
|
||||
expect(result.$$state.value.data.updated_at).toBe('feb8');
|
||||
}));
|
||||
|
||||
it('getL7PolicyDetailsPath creates urls using the item\'s ID', function() {
|
||||
var myItem = {loadbalancerId: '123', id: '789', listenerId: '456'};
|
||||
expect(service.getL7PolicyDetailsPath(myItem))
|
||||
.toBe('project/load_balancer/123/listeners/456/l7policies/789');
|
||||
});
|
||||
|
||||
it("getL7PoliciesPromise provides a promise", inject(function($timeout) {
|
||||
var deferred = $q.defer();
|
||||
spyOn(api, 'getL7Policies').and.returnValue(deferred.promise);
|
||||
var result = service.getL7PoliciesPromise({listenerId: 3});
|
||||
deferred.resolve({data: {items: [{id: 1, updated_at: 'feb8'}]}});
|
||||
$timeout.flush();
|
||||
expect(result.$$state.value.data.items[0].id).toBe(1);
|
||||
expect(result.$$state.value.data.items[0].updated_at).toBe('feb8');
|
||||
expect(result.$$state.value.data.items[0].trackBy).toBe('1feb8');
|
||||
expect(result.$$state.value.data.items[0].listenerId).toBe(3);
|
||||
}));
|
||||
|
||||
it("getL7PolicyPromise provides a promise", inject(function() {
|
||||
var deferred = $q.defer();
|
||||
spyOn(api, 'getL7Policy').and.returnValue(deferred.promise);
|
||||
var result = service.getL7PolicyPromise(1);
|
||||
deferred.resolve({data: {id: 1, updated_at: 'feb8'}});
|
||||
expect(result.$$state.value.data.id).toBe(1);
|
||||
expect(result.$$state.value.data.updated_at).toBe('feb8');
|
||||
}));
|
||||
|
||||
it('getL7RuleDetailsPath creates urls using the item\'s ID', function() {
|
||||
var myItem = {loadbalancerId: '1', id: '5', listenerId: '2', l7policyId: '3'};
|
||||
expect(service.getL7RuleDetailsPath(myItem))
|
||||
.toBe('project/load_balancer/1/listeners/2/l7policies/3/l7rules/5');
|
||||
});
|
||||
|
||||
it("getL7RulesPromise provides a promise", inject(function($timeout) {
|
||||
var deferred = $q.defer();
|
||||
spyOn(api, 'getL7Rules').and.returnValue(deferred.promise);
|
||||
var result = service.getL7RulesPromise({listenerId: 3, l7policyId: 5});
|
||||
deferred.resolve({data: {items: [{id: 1, updated_at: 'feb8'}]}});
|
||||
$timeout.flush();
|
||||
expect(result.$$state.value.data.items[0].id).toBe(1);
|
||||
expect(result.$$state.value.data.items[0].updated_at).toBe('feb8');
|
||||
expect(result.$$state.value.data.items[0].trackBy).toBe('1feb8');
|
||||
expect(result.$$state.value.data.items[0].listenerId).toBe(3);
|
||||
expect(result.$$state.value.data.items[0].l7policyId).toBe(5);
|
||||
}));
|
||||
|
||||
it("getL7RulePromise provides a promise", inject(function() {
|
||||
var deferred = $q.defer();
|
||||
spyOn(api, 'getL7Rule').and.returnValue(deferred.promise);
|
||||
var result = service.getL7RulePromise(2, 1);
|
||||
deferred.resolve({data: {id: 1, updated_at: 'feb8'}});
|
||||
expect(result.$$state.value.data.id).toBe(1);
|
||||
expect(result.$$state.value.data.updated_at).toBe('feb8');
|
||||
}));
|
||||
|
||||
it('getPoolDetailsPath creates urls using the item\'s ID', function() {
|
||||
var myItem = {loadbalancerId: '123', id: '789', listeners: [{id: '456'}]};
|
||||
expect(service.getPoolDetailsPath(myItem))
|
||||
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.controller('L7PolicyDetailsController', L7PolicyDetailsController);
|
||||
|
||||
L7PolicyDetailsController.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.patterns',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name L7PolicyDetailsController
|
||||
* @description
|
||||
* The `L7PolicyDetailsController` controller provides functions for
|
||||
* configuring the l7policy step of the LBaaS wizard.
|
||||
* @param patterns The LBaaS v2 patterns constant.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function L7PolicyDetailsController(patterns, gettext) {
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.adminStateUpOptions = [
|
||||
{ label: gettext('Yes'), value: true },
|
||||
{ label: gettext('No'), value: false }
|
||||
];
|
||||
|
||||
ctrl.redirectUrlError = gettext('The redirect url must be a valid http or https url.');
|
||||
ctrl.positionError = gettext('The position must be a number between 1 and 2147483647.');
|
||||
|
||||
}
|
||||
})();
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('L7Policy Details Step', function() {
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
describe('L7PolicyDetailsController', function() {
|
||||
var ctrl;
|
||||
|
||||
beforeEach(inject(function($controller) {
|
||||
ctrl = $controller('L7PolicyDetailsController');
|
||||
}));
|
||||
|
||||
it('should define adminStateUpOptions', function() {
|
||||
expect(ctrl.adminStateUpOptions).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
})();
|
@ -0,0 +1,38 @@
|
||||
<p translate>
|
||||
An L7 Policy is a collection of L7 rules associated with a Listener, and which may also have an association to a back-end pool
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Action:</strong>
|
||||
<translate>
|
||||
The L7 policy action. One of REJECT, REDIRECT_TO_URL, or REDIRECT_TO_POOL.
|
||||
</translate>
|
||||
<ul>
|
||||
<li translate>
|
||||
REJECT: The request is denied with an appropriate response code, and not forwarded on to any back-end pool.
|
||||
</li>
|
||||
<li translate>
|
||||
REDIRECT_TO_URL: The request is sent an HTTP redirect to the URL defined in the redirect_url parameter.
|
||||
</li>
|
||||
<li translate>
|
||||
REDIRECT_TO_POOL: The request is forwarded to the back-end pool associated with the L7 policy.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Position:</strong>
|
||||
<translate>
|
||||
The position of this policy on the listener. Positions start at 1.
|
||||
</translate>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Redirect Pool ID:</strong>
|
||||
<translate>
|
||||
Requests matching this policy will be redirected to the pool with this ID. Only valid if action is REDIRECT_TO_POOL.
|
||||
</translate>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Redirect URL:</strong>
|
||||
<translate>
|
||||
Requests matching this policy will be redirected to this URL. Only valid if action is REDIRECT_TO_URL.
|
||||
</translate>
|
||||
</p>
|
@ -0,0 +1,104 @@
|
||||
<div ng-controller="L7PolicyDetailsController as ctrl">
|
||||
<p translate>Provide the details for the l7 policy.</p>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group">
|
||||
<label translate class="control-label" for="name">Name</label>
|
||||
<input name="name" id="name" type="text" class="form-control"
|
||||
ng-model="model.spec.l7policy.name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group">
|
||||
<label translate class="control-label" for="description">Description</label>
|
||||
<input name="description" id="description" type="text" class="form-control"
|
||||
ng-model="model.spec.l7policy.description">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group required">
|
||||
<label class="control-label" for="action">
|
||||
<translate>Action</translate>
|
||||
<span class="hz-icon-required fa fa-asterisk"></span>
|
||||
</label>
|
||||
<select class="form-control" name="action" id="action"
|
||||
ng-options="action for action in model.l7policyActions"
|
||||
ng-model="model.spec.l7policy.action"
|
||||
ng-required="true">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6" ng-if="model.spec.l7policy.action === 'REDIRECT_TO_URL'">
|
||||
<div class="form-group required">
|
||||
<label class="control-label" for="redirect_url">
|
||||
<translate>Redirect URL</translate>
|
||||
<span class="hz-icon-required fa fa-asterisk"></span>
|
||||
</label>
|
||||
<input name="redirect_url" id="redirect_url" placeholder="https://www.example.com" type="url" class="form-control"
|
||||
ng-model="model.spec.l7policy.redirect_url" ng-patter="/^http[s]?:\/\//" ng-required="true">
|
||||
<span class="help-block" ng-show="!l7policyDetailsForm.redirect_url.$valid && l7policyDetailsForm.redirect_url.$dirty">
|
||||
{$ ::ctrl.redirectUrlError $}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6" ng-if="model.spec.l7policy.action === 'REDIRECT_TO_POOL'">
|
||||
<div class="form-group required">
|
||||
<label translate class="control-label" for="redirect_pool_id">
|
||||
<translate>Redirect Pool ID</translate>
|
||||
<span class="hz-icon-required fa fa-asterisk"></span>
|
||||
</label>
|
||||
<select class="form-control" name="redirect_pool_id" id="redirect_pool_id"
|
||||
ng-model="model.spec.l7policy.redirect_pool_id" ng-required="true">
|
||||
<option ng-repeat="pool_id in model.spec.availablePools" value="{$ pool_id $}">
|
||||
{$ pool_id $}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group">
|
||||
<label translate class="control-label" for="position">Position</label>
|
||||
<input name="position" id="position" type="number" class="form-control"
|
||||
ng-model="model.spec.l7policy.position" ng-pattern="/^\d+$/" min="1" max="2147483647">
|
||||
<span class="help-block" ng-show="!l7policyDetailsForm.position.$valid && l7policyDetailsForm.position.$dirty">
|
||||
{$ ::ctrl.positionError $}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label required" translate>Admin State Up</label>
|
||||
<div class="form-field">
|
||||
<div class="btn-group">
|
||||
<label class="btn btn-default"
|
||||
ng-repeat="option in ctrl.adminStateUpOptions"
|
||||
ng-model="model.spec.l7policy.admin_state_up"
|
||||
uib-btn-radio="option.value">{$ ::option.label $}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.controller('L7RuleDetailsController', L7RuleDetailsController);
|
||||
|
||||
L7RuleDetailsController.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.patterns',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name L7RuleDetailsController
|
||||
* @description
|
||||
* The `L7RuleDetailsController` controller provides functions for
|
||||
* configuring the l7rule step of the LBaaS wizard.
|
||||
* @param patterns The LBaaS v2 patterns constant.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function L7RuleDetailsController(patterns, gettext) {
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.adminStateUpOptions = [
|
||||
{ label: gettext('Yes'), value: true },
|
||||
{ label: gettext('No'), value: false }
|
||||
];
|
||||
|
||||
}
|
||||
})();
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2018 Walmart.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('L7Rule Details Step', function() {
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
describe('L7RuleDetailsController', function() {
|
||||
var ctrl;
|
||||
|
||||
beforeEach(inject(function($controller) {
|
||||
ctrl = $controller('L7RuleDetailsController');
|
||||
}));
|
||||
|
||||
it('should define adminStateUpOptions', function() {
|
||||
expect(ctrl.adminStateUpOptions).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
})();
|
@ -0,0 +1,76 @@
|
||||
<p translate>
|
||||
An L7 Rule is a single, simple logical test which returns either true or
|
||||
false.
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Type:</strong>
|
||||
<translate>
|
||||
The L7 rule type. One of COOKIE, FILE_TYPE, HEADER, HOST_NAME, or PATH.
|
||||
</translate>
|
||||
<ul>
|
||||
<li translate>
|
||||
COOKIE: The rule looks for a cookie named by the key parameter and
|
||||
compares it against the value parameter in the rule.
|
||||
</li>
|
||||
<li translate>
|
||||
HEADER: The rule looks for a header defined in the key parameter
|
||||
and compares it against the value parameter in the rule.
|
||||
</li>
|
||||
<li translate>
|
||||
FILE_TYPE: The rule compares the last portion of the URI against
|
||||
the value parameter in the rule. (eg. “txt”, “jpg”, etc.)
|
||||
</li>
|
||||
<li translate>
|
||||
PATH: The rule compares the path portion of the HTTP URI against
|
||||
the value parameter in the rule.
|
||||
</li>
|
||||
<li translate>
|
||||
HOST_NAME: The rule does a comparison between the HTTP/1.1
|
||||
hostname in the request against the value parameter in the rule.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Compare Type:</strong>
|
||||
<translate>
|
||||
The comparison type for the L7 rule. One of CONTAINS, ENDS_WITH,
|
||||
EQUAL_TO, REGEX, or STARTS_WITH.
|
||||
</translate>
|
||||
<ul>
|
||||
<li translate>
|
||||
REGEX: Perl type regular expression matching.
|
||||
</li>
|
||||
<li translate>
|
||||
STARTS_WITH: String starts with.
|
||||
</li>
|
||||
<li translate>
|
||||
ENDS_WITH: String ends with.
|
||||
</li>
|
||||
<li translate>
|
||||
CONTAINS: String contains.
|
||||
</li>
|
||||
<li translate>
|
||||
EQUAL_TO: String is equal to.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Key:</strong>
|
||||
<translate>
|
||||
The key to use for the comparison. For example, the name of the cookie
|
||||
to evaluate.
|
||||
</translate>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Value:</strong>
|
||||
<translate>
|
||||
The value to use for the comparison. For example, the file type to compare.
|
||||
</translate>
|
||||
</p>
|
||||
<p>
|
||||
<strong translate>Invert:</strong>
|
||||
<translate>
|
||||
When true the logic of the rule is inverted. For example, with invert
|
||||
true, equal to would become not equal to.
|
||||
</translate>
|
||||
</p>
|
@ -0,0 +1,92 @@
|
||||
<div ng-controller="L7RuleDetailsController as ctrl">
|
||||
<p translate>Provide the details for the l7 rule.</p>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label required" translate>Invert</label>
|
||||
<div class="form-field">
|
||||
<div class="btn-group">
|
||||
<label class="btn btn-default"
|
||||
ng-repeat="option in ctrl.adminStateUpOptions"
|
||||
ng-model="model.spec.l7rule.invert"
|
||||
uib-btn-radio="option.value">{$ ::option.label $}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group required">
|
||||
<label class="control-label" for="type">
|
||||
<translate>Type</translate>
|
||||
<span class="hz-icon-required fa fa-asterisk"></span>
|
||||
</label>
|
||||
<select class="form-control" name="type" id="type"
|
||||
ng-options="type for type in model.l7ruleTypes"
|
||||
ng-model="model.spec.l7rule.type"
|
||||
ng-required="true">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6" ng-if="(model.spec.l7rule.type === 'COOKIE') || (model.spec.l7rule.type === 'HEADER')">
|
||||
<div class="form-group required">
|
||||
<label translate class="control-label" for="key">Key</label>
|
||||
<input name="key" id="key" type="text" class="form-control"
|
||||
ng-model="model.spec.l7rule.key" ng-required="true">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group required">
|
||||
<label class="control-label" for="compare_type">
|
||||
<translate>Compare Type</translate>
|
||||
<span class="hz-icon-required fa fa-asterisk"></span>
|
||||
</label>
|
||||
<select class="form-control" name="compare_type" id="compare_type"
|
||||
ng-options="compare_type for compare_type in model.l7ruleCompareTypes"
|
||||
ng-model="model.spec.l7rule.compare_type"
|
||||
ng-required="true">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group required">
|
||||
<label translate class="control-label" for="rule_value">Value</label>
|
||||
<input name="rule_value" id="rule_value" type="text" class="form-control"
|
||||
ng-model="model.spec.l7rule.rule_value" ng-required="true">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label required" translate>Admin State Up</label>
|
||||
<div class="form-field">
|
||||
<div class="btn-group">
|
||||
<label class="btn btn-default"
|
||||
ng-repeat="option in ctrl.adminStateUpOptions"
|
||||
ng-model="model.spec.l7rule.admin_state_up"
|
||||
uib-btn-radio="option.value">{$ ::option.label $}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
@ -86,6 +86,9 @@
|
||||
subnets: [],
|
||||
members: [],
|
||||
listenerProtocols: ['HTTP', 'TCP', 'TERMINATED_HTTPS', 'HTTPS'],
|
||||
l7policyActions: ['REJECT', 'REDIRECT_TO_URL', 'REDIRECT_TO_POOL'],
|
||||
l7ruleTypes: ['HOST_NAME', 'PATH', 'FILE_TYPE', 'HEADER', 'COOKIE'],
|
||||
l7ruleCompareTypes: ['REGEX', 'STARTS_WITH', 'ENDS_WITH', 'CONTAINS', 'EQUAL_TO'],
|
||||
poolProtocols: ['HTTP', 'HTTPS', 'PROXY', 'TCP'],
|
||||
methods: ['LEAST_CONNECTIONS', 'ROUND_ROBIN', 'SOURCE_IP'],
|
||||
types: ['SOURCE_IP', 'HTTP_COOKIE', 'APP_COOKIE'],
|
||||
@ -153,6 +156,25 @@
|
||||
admin_state_up: true,
|
||||
default_pool_id: null
|
||||
},
|
||||
l7policy: {
|
||||
id: null,
|
||||
name: gettext('L7 Policy 1'),
|
||||
description: null,
|
||||
action: null,
|
||||
position: null,
|
||||
redirect_pool_id: null,
|
||||
redirect_url: null,
|
||||
admin_state_up: true
|
||||
},
|
||||
l7rule: {
|
||||
id: null,
|
||||
type: null,
|
||||
compare_type: null,
|
||||
key: null,
|
||||
rule_value: null,
|
||||
invert: false,
|
||||
admin_state_up: true
|
||||
},
|
||||
pool: {
|
||||
id: null,
|
||||
name: gettext('Pool 1'),
|
||||
@ -198,11 +220,15 @@
|
||||
var promise = {
|
||||
createloadbalancer: initCreateLoadBalancer,
|
||||
createlistener: initCreateListener,
|
||||
createl7policy: initCreateL7Policy,
|
||||
createl7rule: initCreateL7Rule,
|
||||
createpool: initCreatePool,
|
||||
createmonitor: initCreateMonitor,
|
||||
createmembers: initUpdateMemberList,
|
||||
editloadbalancer: initEditLoadBalancer,
|
||||
editlistener: initEditListener,
|
||||
editl7policy: initEditL7Policy,
|
||||
editl7rule: initEditL7Rule,
|
||||
editpool: initEditPool,
|
||||
editmonitor: initEditMonitor
|
||||
}[type](keymanagerPromise);
|
||||
@ -242,6 +268,17 @@
|
||||
]).then(initMemberAddresses);
|
||||
}
|
||||
|
||||
function initCreateL7Policy() {
|
||||
model.context.submit = createL7Policy;
|
||||
return lbaasv2API.getListener(model.spec.parentResourceId)
|
||||
.then(onGetListener).then(getPools).then(onGetPools);
|
||||
}
|
||||
|
||||
function initCreateL7Rule() {
|
||||
model.context.submit = createL7Rule;
|
||||
return $q.when();
|
||||
}
|
||||
|
||||
function initCreatePool() {
|
||||
model.context.submit = createPool;
|
||||
// We get the listener details here because we need to know the listener protocol
|
||||
@ -295,6 +332,19 @@
|
||||
]).then(initMemberAddresses);
|
||||
}
|
||||
|
||||
function initEditL7Policy() {
|
||||
model.context.submit = editL7Policy;
|
||||
return lbaasv2API
|
||||
.getListener(model.spec.parentResourceId).then(onGetListener)
|
||||
.then(getPools).then(onGetPools)
|
||||
.then(getL7Policy).then(onGetL7Policy);
|
||||
}
|
||||
|
||||
function initEditL7Rule() {
|
||||
model.context.submit = editL7Rule;
|
||||
return getL7Rule().then(onGetL7Rule);
|
||||
}
|
||||
|
||||
function initEditPool() {
|
||||
model.context.submit = editPool;
|
||||
return $q.all([
|
||||
@ -339,6 +389,14 @@
|
||||
return lbaasv2API.createListener(spec);
|
||||
}
|
||||
|
||||
function createL7Policy(spec) {
|
||||
return lbaasv2API.createL7Policy(spec);
|
||||
}
|
||||
|
||||
function createL7Rule(spec) {
|
||||
return lbaasv2API.createL7Rule(model.spec.parentResourceId, spec);
|
||||
}
|
||||
|
||||
function createPool(spec) {
|
||||
return lbaasv2API.createPool(spec);
|
||||
}
|
||||
@ -355,6 +413,14 @@
|
||||
return lbaasv2API.editListener(model.context.id, spec);
|
||||
}
|
||||
|
||||
function editL7Policy(spec) {
|
||||
return lbaasv2API.editL7Policy(model.context.id, spec);
|
||||
}
|
||||
|
||||
function editL7Rule(spec) {
|
||||
return lbaasv2API.editL7Rule(model.spec.parentResourceId, model.context.id, spec);
|
||||
}
|
||||
|
||||
function editPool(spec) {
|
||||
return lbaasv2API.editPool(model.context.id, spec);
|
||||
}
|
||||
@ -576,6 +642,15 @@
|
||||
return lbaasv2API.getListener(model.context.id, true);
|
||||
}
|
||||
|
||||
function getL7Policy() {
|
||||
return lbaasv2API.getL7Policy(model.context.id, true);
|
||||
}
|
||||
|
||||
function getL7Rule() {
|
||||
return lbaasv2API.getL7Rule(model.spec.parentResourceId,
|
||||
model.context.id);
|
||||
}
|
||||
|
||||
function getPool() {
|
||||
return lbaasv2API.getPool(model.context.id, true);
|
||||
}
|
||||
@ -633,6 +708,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
function onGetL7Policy(response) {
|
||||
var result = response.data;
|
||||
|
||||
setL7PolicySpec(result.l7policy || result);
|
||||
}
|
||||
|
||||
function onGetL7Rule(response) {
|
||||
var result = response.data;
|
||||
|
||||
setL7RuleSpec(result.l7rule || result);
|
||||
}
|
||||
|
||||
function onGetPool(response) {
|
||||
var result = response.data;
|
||||
|
||||
@ -674,6 +761,29 @@
|
||||
spec.default_pool_id = listener.default_pool_id;
|
||||
}
|
||||
|
||||
function setL7PolicySpec(l7policy) {
|
||||
var spec = model.spec.l7policy;
|
||||
spec.id = l7policy.id;
|
||||
spec.name = l7policy.name;
|
||||
spec.description = l7policy.description;
|
||||
spec.action = l7policy.action;
|
||||
spec.position = l7policy.position;
|
||||
spec.redirect_pool_id = l7policy.redirect_pool_id;
|
||||
spec.redirect_url = l7policy.redirect_url;
|
||||
spec.admin_state_up = l7policy.admin_state_up;
|
||||
}
|
||||
|
||||
function setL7RuleSpec(l7rule) {
|
||||
var spec = model.spec.l7rule;
|
||||
spec.id = l7rule.id;
|
||||
spec.type = l7rule.type;
|
||||
spec.compare_type = l7rule.compare_type;
|
||||
spec.key = l7rule.key;
|
||||
spec.rule_value = l7rule.rule_value;
|
||||
spec.invert = l7rule.invert;
|
||||
spec.admin_state_up = l7rule.admin_state_up;
|
||||
}
|
||||
|
||||
function setPoolSpec(pool) {
|
||||
var spec = model.spec.pool;
|
||||
spec.id = pool.id;
|
||||
|
@ -141,6 +141,37 @@
|
||||
deferred.resolve({ data: listenerData });
|
||||
return deferred.promise;
|
||||
},
|
||||
getL7Policy: function() {
|
||||
var l7policy = {
|
||||
admin_state_up: true,
|
||||
id: '1234',
|
||||
name: 'L7 Policy 1',
|
||||
description: 'l7 policy description',
|
||||
action: 'REDIRECT_TO_URL',
|
||||
position: 1,
|
||||
redirect_url: 'http://example.com'
|
||||
};
|
||||
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve({ data: l7policy });
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
getL7Rule: function() {
|
||||
var l7rule = {
|
||||
admin_state_up: true,
|
||||
id: '1234',
|
||||
type: 'HOST_NAME',
|
||||
compare_type: 'EQUAL_TO',
|
||||
value: 'api.example.com',
|
||||
invert: false
|
||||
};
|
||||
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve({ data: l7rule });
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
getPool: function() {
|
||||
var poolResources = angular.copy(listenerResources);
|
||||
delete poolResources.listener;
|
||||
@ -202,6 +233,18 @@
|
||||
editListener: function(id, spec) {
|
||||
return spec;
|
||||
},
|
||||
createL7Policy: function(spec) {
|
||||
return spec;
|
||||
},
|
||||
editL7Policy: function(id, spec) {
|
||||
return spec;
|
||||
},
|
||||
createL7Rule: function(l7policyId, spec) {
|
||||
return spec;
|
||||
},
|
||||
editL7Rule: function(l7policyId, l7ruleId, spec) {
|
||||
return spec;
|
||||
},
|
||||
createPool: function(spec) {
|
||||
return spec;
|
||||
},
|
||||
@ -463,6 +506,82 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post initialize model (create l7 policy)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
includeChildResources = false;
|
||||
model.initialize('l7policy', false, '1234', '5678');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should initialize model properties', function() {
|
||||
expect(model.initializing).toBe(false);
|
||||
expect(model.initialized).toBe(true);
|
||||
expect(model.subnets.length).toBe(0);
|
||||
expect(model.members.length).toBe(0);
|
||||
expect(model.certificates.length).toBe(0);
|
||||
expect(model.listenerPorts.length).toBe(0);
|
||||
expect(model.spec).toBeDefined();
|
||||
expect(model.spec.loadbalancer_id).toBe('1234');
|
||||
expect(model.spec.parentResourceId).toBe('5678');
|
||||
expect(model.spec.loadbalancer).toBeDefined();
|
||||
expect(model.spec.listener).toBeDefined();
|
||||
expect(model.spec.pool).toBeDefined();
|
||||
expect(model.spec.members.length).toBe(0);
|
||||
expect(model.spec.certificates).toEqual([]);
|
||||
expect(model.spec.monitor).toBeDefined();
|
||||
expect(model.certificatesError).toBe(false);
|
||||
});
|
||||
|
||||
it('should initialize names', function() {
|
||||
expect(model.spec.l7policy.name).toBe('L7 Policy 1');
|
||||
});
|
||||
|
||||
it('should initialize context properties', function() {
|
||||
expect(model.context.resource).toBe('l7policy');
|
||||
expect(model.context.id).toBeFalsy();
|
||||
expect(model.context.submit).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post initialize model (create l7 rule)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
includeChildResources = false;
|
||||
model.initialize('l7rule', false, '1234', '5678');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should initialize model properties', function() {
|
||||
expect(model.initializing).toBe(false);
|
||||
expect(model.initialized).toBe(true);
|
||||
expect(model.subnets.length).toBe(0);
|
||||
expect(model.members.length).toBe(0);
|
||||
expect(model.certificates.length).toBe(0);
|
||||
expect(model.listenerPorts.length).toBe(0);
|
||||
expect(model.spec).toBeDefined();
|
||||
expect(model.spec.loadbalancer_id).toBe('1234');
|
||||
expect(model.spec.parentResourceId).toBe('5678');
|
||||
expect(model.spec.loadbalancer).toBeDefined();
|
||||
expect(model.spec.listener).toBeDefined();
|
||||
expect(model.spec.pool).toBeDefined();
|
||||
expect(model.spec.members.length).toBe(0);
|
||||
expect(model.spec.certificates).toEqual([]);
|
||||
expect(model.spec.monitor).toBeDefined();
|
||||
expect(model.certificatesError).toBe(false);
|
||||
});
|
||||
|
||||
it('should initialize invert', function() {
|
||||
expect(model.spec.l7rule.invert).toBe(false);
|
||||
});
|
||||
|
||||
it('should initialize context properties', function() {
|
||||
expect(model.context.resource).toBe('l7rule');
|
||||
expect(model.context.id).toBeFalsy();
|
||||
expect(model.context.submit).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post initialize model (create pool with listener)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
@ -794,6 +913,53 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post initialize model (edit l7 policy)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('l7policy', '1234', 'loadbalancerId', 'listenerId');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should initialize model properties', function() {
|
||||
expect(model.initializing).toBe(false);
|
||||
expect(model.initialized).toBe(true);
|
||||
expect(model.spec).toBeDefined();
|
||||
expect(model.spec.loadbalancer_id).toBeDefined();
|
||||
expect(model.spec.l7policy.id).toBe('1234');
|
||||
expect(model.spec.l7policy.name).toBe('L7 Policy 1');
|
||||
expect(model.spec.l7policy.description).toBe('l7 policy description');
|
||||
});
|
||||
|
||||
it('should initialize context', function() {
|
||||
expect(model.context.resource).toBe('l7policy');
|
||||
expect(model.context.id).toBeDefined();
|
||||
expect(model.context.submit).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post initialize model (edit l7 rule)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('l7rule', '1234', 'loadbalancerId', 'l7policyId');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should initialize model properties', function() {
|
||||
expect(model.initializing).toBe(false);
|
||||
expect(model.initialized).toBe(true);
|
||||
expect(model.spec).toBeDefined();
|
||||
expect(model.spec.loadbalancer_id).toBeDefined();
|
||||
expect(model.spec.l7rule.id).toBe('1234');
|
||||
expect(model.spec.l7rule.type).toBe('HOST_NAME');
|
||||
});
|
||||
|
||||
it('should initialize context', function() {
|
||||
expect(model.context.resource).toBe('l7rule');
|
||||
expect(model.context.id).toBeDefined();
|
||||
expect(model.context.submit).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post initialize model (edit pool)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
@ -1005,9 +1171,11 @@
|
||||
// This is here to ensure that as people add/change spec properties, they don't forget
|
||||
// to implement tests for them.
|
||||
it('has the right number of properties', function() {
|
||||
expect(Object.keys(model.spec).length).toBe(9);
|
||||
expect(Object.keys(model.spec).length).toBe(11);
|
||||
expect(Object.keys(model.spec.loadbalancer).length).toBe(5);
|
||||
expect(Object.keys(model.spec.listener).length).toBe(8);
|
||||
expect(Object.keys(model.spec.l7policy).length).toBe(8);
|
||||
expect(Object.keys(model.spec.l7rule).length).toBe(7);
|
||||
expect(Object.keys(model.spec.pool).length).toBe(8);
|
||||
expect(Object.keys(model.spec.monitor).length).toBe(10);
|
||||
expect(model.spec.members).toEqual([]);
|
||||
@ -1716,6 +1884,47 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('Model submit function (create l7 policy)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('l7policy', null, '1234', 'listener1');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should set final spec properties', function() {
|
||||
model.spec.l7policy.action = 'REJECT';
|
||||
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer_id).toBe('1234');
|
||||
expect(finalSpec.parentResourceId).toBe('listener1');
|
||||
expect(finalSpec.loadbalancer).toBeUndefined();
|
||||
expect(finalSpec.listener).toBeDefined();
|
||||
|
||||
expect(finalSpec.l7policy.action).toBe('REJECT');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Model submit function (create l7 rule)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('l7rule', null, '1234', 'l7policy1');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should set final spec properties', function() {
|
||||
model.spec.l7rule.type = 'PATH';
|
||||
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer_id).toBe('1234');
|
||||
expect(finalSpec.parentResourceId).toBe('l7policy1');
|
||||
expect(finalSpec.loadbalancer).toBeUndefined();
|
||||
|
||||
expect(finalSpec.l7rule.type).toBe('PATH');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Model submit function (create pool)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
@ -1977,6 +2186,45 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('Model submit function (edit l7 policy)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('l7policy', 'l7policy1', '1234', '1234');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should set final spec properties', function() {
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer_id).toBe('1234');
|
||||
expect(finalSpec.parentResourceId).toBe('1234');
|
||||
expect(finalSpec.loadbalancer).toBeUndefined();
|
||||
expect(finalSpec.listener).toBeDefined();
|
||||
|
||||
expect(finalSpec.l7policy.action).toBe('REDIRECT_TO_URL');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Model submit function (edit l7 rule)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize('l7rule', '1234', '1234', '1234');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
it('should set final spec properties', function() {
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer_id).toBe('1234');
|
||||
expect(finalSpec.parentResourceId).toBe('1234');
|
||||
expect(finalSpec.loadbalancer).toBeUndefined();
|
||||
|
||||
expect(finalSpec.l7rule.type).toBe('HOST_NAME');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Model submit function (edit pool)', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
|
@ -42,6 +42,20 @@
|
||||
helpUrl: basePath + 'workflow/listener/listener.help.html',
|
||||
formName: 'listenerDetailsForm'
|
||||
},
|
||||
{
|
||||
id: 'l7policy',
|
||||
title: gettext('L7 Policy Details'),
|
||||
templateUrl: basePath + 'workflow/l7policy/l7policy.html',
|
||||
helpUrl: basePath + 'workflow/l7policy/l7policy.help.html',
|
||||
formName: 'l7policyDetailsForm'
|
||||
},
|
||||
{
|
||||
id: 'l7rule',
|
||||
title: gettext('L7 Rule Details'),
|
||||
templateUrl: basePath + 'workflow/l7rule/l7rule.html',
|
||||
helpUrl: basePath + 'workflow/l7rule/l7rule.help.html',
|
||||
formName: 'l7ruleDetailsForm'
|
||||
},
|
||||
{
|
||||
id: 'pool',
|
||||
title: gettext('Pool Details'),
|
||||
|
@ -44,11 +44,13 @@
|
||||
it('should have default steps defined', function () {
|
||||
var workflow = workflowService('My Workflow');
|
||||
expect(workflow.steps).toBeDefined();
|
||||
expect(workflow.steps.length).toBe(6);
|
||||
expect(workflow.steps.length).toBe(8);
|
||||
|
||||
var forms = [
|
||||
'loadBalancerDetailsForm',
|
||||
'listenerDetailsForm',
|
||||
'l7policyDetailsForm',
|
||||
'l7ruleDetailsForm',
|
||||
'poolDetailsForm',
|
||||
'memberDetailsForm',
|
||||
'monitorDetailsForm',
|
||||
|
4
releasenotes/notes/add-l7-support-05a790bc2965c38f.yaml
Normal file
4
releasenotes/notes/add-l7-support-05a790bc2965c38f.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds L7 policy support to the dashboard.
|
Loading…
Reference in New Issue
Block a user