Fix 403 issue when creating load balancers
The Octavia dashboard code was attempting to access flavor profile information when creating a load balancer. Flavor profiles are administrator only objects that cannot be accessed by users with the default RBAC. This patch removes the code attempting to access the flavor profile as it is not necessary. Change-Id: Ic11d8b84f61c1fd8c97a81f2e47745a339396336 Story: 2005759 Task: 33467
This commit is contained in:
parent
360e41d7c8
commit
a27ed69f1e
@ -97,27 +97,15 @@
|
|||||||
}, {
|
}, {
|
||||||
label: gettext('Flavor Description'),
|
label: gettext('Flavor Description'),
|
||||||
value: 'description'
|
value: 'description'
|
||||||
}, {
|
|
||||||
label: gettext('Provider'),
|
|
||||||
value: function(flavor) {
|
|
||||||
var flavorProfile = $scope.model.flavorProfiles[flavor.flavor_profile_id];
|
|
||||||
return flavorProfile ? flavorProfile.provider_name : '';
|
|
||||||
}
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
ctrl.flavorOptions = [];
|
ctrl.flavorOptions = [];
|
||||||
|
|
||||||
ctrl.flavorShorthand = function(flavor) {
|
ctrl.flavorShorthand = function(flavor) {
|
||||||
var flavorProfile = $scope.model.flavorProfiles[flavor.flavor_profile_id];
|
|
||||||
|
|
||||||
var providerText =
|
|
||||||
flavorProfile
|
|
||||||
? flavorProfile.provider_name
|
|
||||||
: '';
|
|
||||||
var flavorText = flavor.name || flavor.id.substring(0, 10) + '...';
|
var flavorText = flavor.name || flavor.id.substring(0, 10) + '...';
|
||||||
var flavorDescription = flavor.description || '';
|
var flavorDescription = flavor.description || '';
|
||||||
|
|
||||||
return flavorText + ' (' + providerText + '): ' + flavorDescription;
|
return flavorText + ': ' + flavorDescription;
|
||||||
};
|
};
|
||||||
|
|
||||||
ctrl.setFlavor = function(option) {
|
ctrl.setFlavor = function(option) {
|
||||||
@ -157,9 +145,6 @@
|
|||||||
$scope.$watchCollection('model.flavors', function() {
|
$scope.$watchCollection('model.flavors', function() {
|
||||||
ctrl._checkLoaded();
|
ctrl._checkLoaded();
|
||||||
});
|
});
|
||||||
$scope.$watchCollection('model.flavorProfiles', function() {
|
|
||||||
ctrl._checkLoaded();
|
|
||||||
});
|
|
||||||
$scope.$watch('model.initialized', function() {
|
$scope.$watch('model.initialized', function() {
|
||||||
ctrl._checkLoaded();
|
ctrl._checkLoaded();
|
||||||
});
|
});
|
||||||
|
@ -75,13 +75,6 @@
|
|||||||
is_enabled: true
|
is_enabled: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
flavorProfiles: {
|
|
||||||
'79e16118-daba-4255-9d1d-9cc7812e18a1': {
|
|
||||||
id: '79e16118-daba-4255-9d1d-9cc7812e18a1',
|
|
||||||
name: 'flavor_profile_1',
|
|
||||||
provider_name: 'amphora'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
subnets: [{}, {}],
|
subnets: [{}, {}],
|
||||||
spec: {
|
spec: {
|
||||||
loadbalancer: {
|
loadbalancer: {
|
||||||
@ -123,13 +116,13 @@
|
|||||||
|
|
||||||
it('should create flavor shorthand text', function() {
|
it('should create flavor shorthand text', function() {
|
||||||
expect(ctrl.flavorShorthand(mockFlavors[0])).toBe(
|
expect(ctrl.flavorShorthand(mockFlavors[0])).toBe(
|
||||||
'flavor_1 (amphora): Flavor 1 description'
|
'flavor_1: Flavor 1 description'
|
||||||
);
|
);
|
||||||
expect(ctrl.flavorShorthand(mockFlavors[1])).toBe(
|
expect(ctrl.flavorShorthand(mockFlavors[1])).toBe(
|
||||||
'flavor_2 (): '
|
'flavor_2: '
|
||||||
);
|
);
|
||||||
expect(ctrl.flavorShorthand(mockFlavors[2])).toBe(
|
expect(ctrl.flavorShorthand(mockFlavors[2])).toBe(
|
||||||
'94306089-5... (): '
|
'94306089-5...: '
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -162,10 +155,6 @@
|
|||||||
scope.$apply();
|
scope.$apply();
|
||||||
expect(ctrl._checkLoaded).toHaveBeenCalled();
|
expect(ctrl._checkLoaded).toHaveBeenCalled();
|
||||||
|
|
||||||
scope.model.flavorProfiles = {};
|
|
||||||
scope.$apply();
|
|
||||||
expect(ctrl._checkLoaded).toHaveBeenCalled();
|
|
||||||
|
|
||||||
scope.model.initialized = true;
|
scope.model.initialized = true;
|
||||||
|
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
@ -239,12 +228,6 @@
|
|||||||
|
|
||||||
expect(ctrl.flavorColumns[2].label).toBe('Flavor Description');
|
expect(ctrl.flavorColumns[2].label).toBe('Flavor Description');
|
||||||
expect(ctrl.flavorColumns[2].value).toBe('description');
|
expect(ctrl.flavorColumns[2].value).toBe('description');
|
||||||
|
|
||||||
expect(ctrl.flavorColumns[3].label).toBe('Provider');
|
|
||||||
var flavorLabel3 = ctrl.flavorColumns[3].value(mockFlavors[0]);
|
|
||||||
expect(flavorLabel3).toBe('amphora');
|
|
||||||
flavorLabel3 = ctrl.flavorColumns[3].value(mockFlavors[1]);
|
|
||||||
expect(flavorLabel3).toBe('');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -86,7 +86,6 @@
|
|||||||
members: [],
|
members: [],
|
||||||
networks: {},
|
networks: {},
|
||||||
flavors: {},
|
flavors: {},
|
||||||
flavorProfiles: {},
|
|
||||||
listenerProtocols: ['HTTP', 'TCP', 'TERMINATED_HTTPS', 'HTTPS'],
|
listenerProtocols: ['HTTP', 'TCP', 'TERMINATED_HTTPS', 'HTTPS'],
|
||||||
l7policyActions: ['REJECT', 'REDIRECT_TO_URL', 'REDIRECT_TO_POOL'],
|
l7policyActions: ['REJECT', 'REDIRECT_TO_URL', 'REDIRECT_TO_POOL'],
|
||||||
l7ruleTypes: ['HOST_NAME', 'PATH', 'FILE_TYPE', 'HEADER', 'COOKIE'],
|
l7ruleTypes: ['HOST_NAME', 'PATH', 'FILE_TYPE', 'HEADER', 'COOKIE'],
|
||||||
@ -267,7 +266,6 @@
|
|||||||
model.context.submit = createLoadBalancer;
|
model.context.submit = createLoadBalancer;
|
||||||
return $q.all([
|
return $q.all([
|
||||||
lbaasv2API.getFlavors().then(onGetFlavors),
|
lbaasv2API.getFlavors().then(onGetFlavors),
|
||||||
lbaasv2API.getFlavorProfiles().then(onGetFlavorProfiles),
|
|
||||||
neutronAPI.getSubnets().then(onGetSubnets),
|
neutronAPI.getSubnets().then(onGetSubnets),
|
||||||
neutronAPI.getPorts().then(onGetPorts),
|
neutronAPI.getPorts().then(onGetPorts),
|
||||||
neutronAPI.getNetworks().then(onGetNetworks),
|
neutronAPI.getNetworks().then(onGetNetworks),
|
||||||
@ -288,12 +286,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGetFlavorProfiles(response) {
|
|
||||||
angular.forEach(response.data.items, function(value) {
|
|
||||||
model.flavorProfiles[value.id] = value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initCreateListener(keymanagerPromise) {
|
function initCreateListener(keymanagerPromise) {
|
||||||
model.context.submit = createListener;
|
model.context.submit = createListener;
|
||||||
return $q.all([
|
return $q.all([
|
||||||
@ -355,7 +347,6 @@
|
|||||||
model.context.submit = editLoadBalancer;
|
model.context.submit = editLoadBalancer;
|
||||||
return $q.all([
|
return $q.all([
|
||||||
lbaasv2API.getFlavors().then(onGetFlavors),
|
lbaasv2API.getFlavors().then(onGetFlavors),
|
||||||
lbaasv2API.getFlavorProfiles().then(onGetFlavorProfiles),
|
|
||||||
lbaasv2API.getLoadBalancer(model.context.id).then(onGetLoadBalancer),
|
lbaasv2API.getLoadBalancer(model.context.id).then(onGetLoadBalancer),
|
||||||
neutronAPI.getSubnets().then(onGetSubnets),
|
neutronAPI.getSubnets().then(onGetSubnets),
|
||||||
neutronAPI.getNetworks().then(onGetNetworks)
|
neutronAPI.getNetworks().then(onGetNetworks)
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
describe('LBaaS v2 Workflow Model Service', function() {
|
describe('LBaaS v2 Workflow Model Service', function() {
|
||||||
var model, $q, scope, listenerResources, barbicanEnabled,
|
var model, $q, scope, listenerResources, barbicanEnabled,
|
||||||
certificatesError, mockNetworks, mockFlavors, mockFlavorProfiles;
|
certificatesError, mockNetworks, mockFlavors;
|
||||||
var includeChildResources = true;
|
var includeChildResources = true;
|
||||||
|
|
||||||
beforeEach(module('horizon.framework.util.i18n'));
|
beforeEach(module('horizon.framework.util.i18n'));
|
||||||
@ -105,16 +105,6 @@
|
|||||||
id: 'f2'
|
id: 'f2'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mockFlavorProfiles = {
|
|
||||||
p1: {
|
|
||||||
name: 'flavor_profile_1',
|
|
||||||
id: 'p1'
|
|
||||||
},
|
|
||||||
p2: {
|
|
||||||
name: 'flavor_profile_2',
|
|
||||||
id: 'p2'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(module(function($provide) {
|
beforeEach(module(function($provide) {
|
||||||
@ -276,19 +266,6 @@
|
|||||||
deferred.resolve({data: {items: flavors}});
|
deferred.resolve({data: {items: flavors}});
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
},
|
},
|
||||||
getFlavorProfiles: function() {
|
|
||||||
var flavorProfiles = [{
|
|
||||||
name: 'flavor_profile_1',
|
|
||||||
id: 'p1'
|
|
||||||
}, {
|
|
||||||
name: 'flavor_profile_2',
|
|
||||||
id: 'p2'
|
|
||||||
}];
|
|
||||||
|
|
||||||
var deferred = $q.defer();
|
|
||||||
deferred.resolve({data: {items: flavorProfiles}});
|
|
||||||
return deferred.promise;
|
|
||||||
},
|
|
||||||
createLoadBalancer: function(spec) {
|
createLoadBalancer: function(spec) {
|
||||||
return spec;
|
return spec;
|
||||||
},
|
},
|
||||||
@ -534,7 +511,6 @@
|
|||||||
expect(model.subnets.length).toBe(2);
|
expect(model.subnets.length).toBe(2);
|
||||||
expect(model.networks).toEqual(mockNetworks);
|
expect(model.networks).toEqual(mockNetworks);
|
||||||
expect(model.flavors).toEqual(mockFlavors);
|
expect(model.flavors).toEqual(mockFlavors);
|
||||||
expect(model.flavorProfiles).toEqual(mockFlavorProfiles);
|
|
||||||
expect(model.members.length).toBe(2);
|
expect(model.members.length).toBe(2);
|
||||||
expect(model.certificates.length).toBe(2);
|
expect(model.certificates.length).toBe(2);
|
||||||
expect(model.listenerPorts.length).toBe(0);
|
expect(model.listenerPorts.length).toBe(0);
|
||||||
@ -792,7 +768,6 @@
|
|||||||
expect(model.subnets.length).toBe(2);
|
expect(model.subnets.length).toBe(2);
|
||||||
expect(model.networks).toEqual(mockNetworks);
|
expect(model.networks).toEqual(mockNetworks);
|
||||||
expect(model.flavors).toEqual(mockFlavors);
|
expect(model.flavors).toEqual(mockFlavors);
|
||||||
expect(model.flavorProfiles).toEqual(mockFlavorProfiles);
|
|
||||||
expect(model.members.length).toBe(0);
|
expect(model.members.length).toBe(0);
|
||||||
expect(model.certificates.length).toBe(0);
|
expect(model.certificates.length).toBe(0);
|
||||||
expect(model.listenerPorts.length).toBe(0);
|
expect(model.listenerPorts.length).toBe(0);
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Fixes an issue in the Octavia dashboard where users receive a 403
|
||||||
|
error when attempting to create a load balancer. This was due to
|
||||||
|
the dashboard attempting to access the flavor profile information
|
||||||
|
which is an administrator only object by default.
|
Loading…
Reference in New Issue
Block a user