Make shared image text less confusing for Glance v2

When using Glance v2 and logged in as an admin, the images
panel now shows all the images in the cloud. This is the
way the Glance v2 list api works, but it changed the behavior
from v1. In Horizon, we can't tell whether non-public images
that aren't owned by current project are shared or just from
some other project without making multiple api calls. This
patch makes the text of the images less confusing when using
Glance v2, so that it no longer claims the images are "Shared
with Project".

Change-Id: I2859e104de78a6a633b0e1a2ff30dde674b4bdee
Closes-Bug: #1624743
This commit is contained in:
Brad Pokorny 2016-09-22 14:27:35 -07:00 committed by Beth Elwell
parent f05fd1e4f7
commit b01bf0f9a1
5 changed files with 47 additions and 11 deletions

View File

@ -36,7 +36,8 @@
* {string} currentProjectId (optional) Pass this in if the filter should derive the
* sharing status based on the current project id. If the image is non-public and the image
* is not "owned" by the current project, then this will return a visibility of
* "Shared with Project".
* "Shared with Project" if using Glance v1 and "Image from Other Project - Non-Public" if
* using Glance v2.
*
* @example
*
@ -61,13 +62,16 @@
var imageVisibility = {
'public': gettext('Public'),
'private': gettext('Private'),
'shared_with_project': gettext('Shared with Project'),
'other': null,
'unknown': gettext('Unknown')
};
return function getVisibility(image, currentProjectId) {
imageVisibility.other = gettext('Image from Other Project - Non-Public');
if (null !== image && angular.isDefined(image)) {
if (image.apiVersion < 2) {
imageVisibility.other = gettext('Shared with Project');
}
return evaluateImageProperties(image, currentProjectId);
} else {
return imageVisibility.unknown;
@ -115,7 +119,7 @@
return translatedVisibility;
} else if (angular.isDefined(currentProjectId) &&
!angular.equals(image.owner, currentProjectId)) {
return imageVisibility.shared_with_project;
return imageVisibility.other;
} else {
return translatedVisibility;
}

View File

@ -29,7 +29,7 @@
var expected = {
public: 'Public',
private: 'Private',
shared_with_project: "Shared with Project",
other: "Image from Other Project - Non-Public",
unknown: 'Unknown'
};
@ -48,7 +48,7 @@
it('returns Shared for visibility.private and owner is not current project', function () {
expect(imageVisibilityFilter({visibility: 'private', owner: 'me'}, 'not me'))
.toBe(expected.shared_with_project);
.toBe(expected.other);
});
it('returns Private for visibility.private and owner undefined', function () {
@ -93,7 +93,7 @@
it('returns Shared for is_public = false and owner is not current project', function () {
expect(imageVisibilityFilter({is_public: false, owner: 'me'}, 'not me'))
.toBe(expected.shared_with_project);
.toBe(expected.other);
});
it('returns Private for is_public = false and owner undefined', function () {

View File

@ -37,6 +37,8 @@
* is documented below.
*/
function imageService($filter, glance, userSession, transitionalStatuses) {
var version;
return {
getDetailsPath: getDetailsPath,
getImagePromise: getImagePromise,
@ -106,6 +108,7 @@
return userSession.get().then(getImages);
function getImages(userSession) {
glance.getVersion().then(setVersion);
projectId = userSession.project_id;
return glance.getImages(params).then(modifyResponse);
}
@ -115,6 +118,7 @@
function modifyImage(image) {
image.trackBy = image.id + image.updated_at;
image.apiVersion = version;
image.visibility = $filter('imageVisibility')(image, projectId);
image.name = image.name || image.id;
return image;
@ -129,7 +133,24 @@
* Given an id, returns a promise for the image data.
*/
function getImagePromise(identifier) {
return glance.getImage(identifier);
glance.getVersion().then(setVersion);
return glance.getImage(identifier).then(modifyResponse);
function modifyResponse(response) {
response.data.apiVersion = version;
return {data: response.data};
}
}
/*
* @ngdoc function
* @name setVersion
* @description
* Set the image api version so it can be used in decisions about how to
* display information later.
*/
function setVersion(response) {
version = response.data.version;
}
}

View File

@ -88,11 +88,14 @@
var glance = $injector.get('horizon.app.core.openstack-service-api.glance');
var session = $injector.get('horizon.app.core.openstack-service-api.userSession');
var deferred = $q.defer();
var deferredVersion = $q.defer();
var deferredSession = $q.defer();
spyOn(glance, 'getImages').and.returnValue(deferred.promise);
spyOn(glance, 'getVersion').and.returnValue(deferredVersion.promise);
spyOn(session, 'get').and.returnValue(deferredSession.promise);
var result = service.getImagesPromise({});
deferred.resolve({data: {items: [{id: 1, updated_at: 'jul1'}]}});
deferredVersion.resolve({data: {version: '2'}});
deferredSession.resolve({project_id: '12'});
$timeout.flush();
expect(result.$$state.value.data.items[0].trackBy).toBe('1jul1');
@ -100,14 +103,19 @@
});
describe('getImagePromise', function() {
it("provides a promise", inject(function($q, $injector) {
it("provides a promise", inject(function($q, $injector, $timeout) {
var glance = $injector.get('horizon.app.core.openstack-service-api.glance');
var deferred = $q.defer();
var deferredVersion = $q.defer();
spyOn(glance, 'getImage').and.returnValue(deferred.promise);
spyOn(glance, 'getVersion').and.returnValue(deferredVersion.promise);
var result = service.getImagePromise({});
deferred.resolve({id: 1, updated_at: 'jul1'});
deferred.resolve({data: {id: 1, updated_at: 'jul1'}});
deferredVersion.resolve({data: {version: '2'}});
expect(glance.getImage).toHaveBeenCalled();
expect(result.$$state.value.updated_at).toBe('jul1');
expect(glance.getVersion).toHaveBeenCalled();
$timeout.flush();
expect(result.$$state.value.data.updated_at).toBe('jul1');
}));
});
});

View File

@ -17,3 +17,6 @@ issues:
other:
- Glance v2 doesn't support the copy-from feature, so this feature is
disabled in Horizon when using Glance v2.
- The output from the Glance image list API has changed between v1 and v2
such that admins logged into Horizon will now see all images in the cloud
on the Project->Compute->Images panel.