From b01bf0f9a16b6aa48f73bf046e9ef51287cb40cc Mon Sep 17 00:00:00 2001 From: Brad Pokorny Date: Thu, 22 Sep 2016 14:27:35 -0700 Subject: [PATCH] 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 --- .../images/filters/image-visibility.filter.js | 12 ++++++---- .../filters/image-visibility.filter.spec.js | 6 ++--- .../static/app/core/images/images.service.js | 23 ++++++++++++++++++- .../app/core/images/images.service.spec.js | 14 ++++++++--- .../notes/glance-v2-ba86ba34611f95ce.yaml | 3 +++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/openstack_dashboard/static/app/core/images/filters/image-visibility.filter.js b/openstack_dashboard/static/app/core/images/filters/image-visibility.filter.js index 3d5d300206..96bfa57b30 100644 --- a/openstack_dashboard/static/app/core/images/filters/image-visibility.filter.js +++ b/openstack_dashboard/static/app/core/images/filters/image-visibility.filter.js @@ -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; } diff --git a/openstack_dashboard/static/app/core/images/filters/image-visibility.filter.spec.js b/openstack_dashboard/static/app/core/images/filters/image-visibility.filter.spec.js index 9e4d8d3548..9a802df078 100644 --- a/openstack_dashboard/static/app/core/images/filters/image-visibility.filter.spec.js +++ b/openstack_dashboard/static/app/core/images/filters/image-visibility.filter.spec.js @@ -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 () { diff --git a/openstack_dashboard/static/app/core/images/images.service.js b/openstack_dashboard/static/app/core/images/images.service.js index 978f1689ae..0fd30abc7b 100644 --- a/openstack_dashboard/static/app/core/images/images.service.js +++ b/openstack_dashboard/static/app/core/images/images.service.js @@ -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; } } diff --git a/openstack_dashboard/static/app/core/images/images.service.spec.js b/openstack_dashboard/static/app/core/images/images.service.spec.js index d298b022b3..e7b9e70cc5 100644 --- a/openstack_dashboard/static/app/core/images/images.service.spec.js +++ b/openstack_dashboard/static/app/core/images/images.service.spec.js @@ -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'); })); }); }); diff --git a/releasenotes/notes/glance-v2-ba86ba34611f95ce.yaml b/releasenotes/notes/glance-v2-ba86ba34611f95ce.yaml index 0db20bb054..4951524d46 100644 --- a/releasenotes/notes/glance-v2-ba86ba34611f95ce.yaml +++ b/releasenotes/notes/glance-v2-ba86ba34611f95ce.yaml @@ -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.