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:
parent
f05fd1e4f7
commit
b01bf0f9a1
@ -36,7 +36,8 @@
|
|||||||
* {string} currentProjectId (optional) Pass this in if the filter should derive the
|
* {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
|
* 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
|
* 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
|
* @example
|
||||||
*
|
*
|
||||||
@ -61,13 +62,16 @@
|
|||||||
var imageVisibility = {
|
var imageVisibility = {
|
||||||
'public': gettext('Public'),
|
'public': gettext('Public'),
|
||||||
'private': gettext('Private'),
|
'private': gettext('Private'),
|
||||||
|
'other': null,
|
||||||
'shared_with_project': gettext('Shared with Project'),
|
|
||||||
'unknown': gettext('Unknown')
|
'unknown': gettext('Unknown')
|
||||||
};
|
};
|
||||||
|
|
||||||
return function getVisibility(image, currentProjectId) {
|
return function getVisibility(image, currentProjectId) {
|
||||||
|
imageVisibility.other = gettext('Image from Other Project - Non-Public');
|
||||||
if (null !== image && angular.isDefined(image)) {
|
if (null !== image && angular.isDefined(image)) {
|
||||||
|
if (image.apiVersion < 2) {
|
||||||
|
imageVisibility.other = gettext('Shared with Project');
|
||||||
|
}
|
||||||
return evaluateImageProperties(image, currentProjectId);
|
return evaluateImageProperties(image, currentProjectId);
|
||||||
} else {
|
} else {
|
||||||
return imageVisibility.unknown;
|
return imageVisibility.unknown;
|
||||||
@ -115,7 +119,7 @@
|
|||||||
return translatedVisibility;
|
return translatedVisibility;
|
||||||
} else if (angular.isDefined(currentProjectId) &&
|
} else if (angular.isDefined(currentProjectId) &&
|
||||||
!angular.equals(image.owner, currentProjectId)) {
|
!angular.equals(image.owner, currentProjectId)) {
|
||||||
return imageVisibility.shared_with_project;
|
return imageVisibility.other;
|
||||||
} else {
|
} else {
|
||||||
return translatedVisibility;
|
return translatedVisibility;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
var expected = {
|
var expected = {
|
||||||
public: 'Public',
|
public: 'Public',
|
||||||
private: 'Private',
|
private: 'Private',
|
||||||
shared_with_project: "Shared with Project",
|
other: "Image from Other Project - Non-Public",
|
||||||
unknown: 'Unknown'
|
unknown: 'Unknown'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
it('returns Shared for visibility.private and owner is not current project', function () {
|
it('returns Shared for visibility.private and owner is not current project', function () {
|
||||||
expect(imageVisibilityFilter({visibility: 'private', owner: 'me'}, 'not me'))
|
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 () {
|
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 () {
|
it('returns Shared for is_public = false and owner is not current project', function () {
|
||||||
expect(imageVisibilityFilter({is_public: false, owner: 'me'}, 'not me'))
|
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 () {
|
it('returns Private for is_public = false and owner undefined', function () {
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
* is documented below.
|
* is documented below.
|
||||||
*/
|
*/
|
||||||
function imageService($filter, glance, userSession, transitionalStatuses) {
|
function imageService($filter, glance, userSession, transitionalStatuses) {
|
||||||
|
var version;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getDetailsPath: getDetailsPath,
|
getDetailsPath: getDetailsPath,
|
||||||
getImagePromise: getImagePromise,
|
getImagePromise: getImagePromise,
|
||||||
@ -106,6 +108,7 @@
|
|||||||
return userSession.get().then(getImages);
|
return userSession.get().then(getImages);
|
||||||
|
|
||||||
function getImages(userSession) {
|
function getImages(userSession) {
|
||||||
|
glance.getVersion().then(setVersion);
|
||||||
projectId = userSession.project_id;
|
projectId = userSession.project_id;
|
||||||
return glance.getImages(params).then(modifyResponse);
|
return glance.getImages(params).then(modifyResponse);
|
||||||
}
|
}
|
||||||
@ -115,6 +118,7 @@
|
|||||||
|
|
||||||
function modifyImage(image) {
|
function modifyImage(image) {
|
||||||
image.trackBy = image.id + image.updated_at;
|
image.trackBy = image.id + image.updated_at;
|
||||||
|
image.apiVersion = version;
|
||||||
image.visibility = $filter('imageVisibility')(image, projectId);
|
image.visibility = $filter('imageVisibility')(image, projectId);
|
||||||
image.name = image.name || image.id;
|
image.name = image.name || image.id;
|
||||||
return image;
|
return image;
|
||||||
@ -129,7 +133,24 @@
|
|||||||
* Given an id, returns a promise for the image data.
|
* Given an id, returns a promise for the image data.
|
||||||
*/
|
*/
|
||||||
function getImagePromise(identifier) {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,11 +88,14 @@
|
|||||||
var glance = $injector.get('horizon.app.core.openstack-service-api.glance');
|
var glance = $injector.get('horizon.app.core.openstack-service-api.glance');
|
||||||
var session = $injector.get('horizon.app.core.openstack-service-api.userSession');
|
var session = $injector.get('horizon.app.core.openstack-service-api.userSession');
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
|
var deferredVersion = $q.defer();
|
||||||
var deferredSession = $q.defer();
|
var deferredSession = $q.defer();
|
||||||
spyOn(glance, 'getImages').and.returnValue(deferred.promise);
|
spyOn(glance, 'getImages').and.returnValue(deferred.promise);
|
||||||
|
spyOn(glance, 'getVersion').and.returnValue(deferredVersion.promise);
|
||||||
spyOn(session, 'get').and.returnValue(deferredSession.promise);
|
spyOn(session, 'get').and.returnValue(deferredSession.promise);
|
||||||
var result = service.getImagesPromise({});
|
var result = service.getImagesPromise({});
|
||||||
deferred.resolve({data: {items: [{id: 1, updated_at: 'jul1'}]}});
|
deferred.resolve({data: {items: [{id: 1, updated_at: 'jul1'}]}});
|
||||||
|
deferredVersion.resolve({data: {version: '2'}});
|
||||||
deferredSession.resolve({project_id: '12'});
|
deferredSession.resolve({project_id: '12'});
|
||||||
$timeout.flush();
|
$timeout.flush();
|
||||||
expect(result.$$state.value.data.items[0].trackBy).toBe('1jul1');
|
expect(result.$$state.value.data.items[0].trackBy).toBe('1jul1');
|
||||||
@ -100,14 +103,19 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getImagePromise', function() {
|
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 glance = $injector.get('horizon.app.core.openstack-service-api.glance');
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
|
var deferredVersion = $q.defer();
|
||||||
spyOn(glance, 'getImage').and.returnValue(deferred.promise);
|
spyOn(glance, 'getImage').and.returnValue(deferred.promise);
|
||||||
|
spyOn(glance, 'getVersion').and.returnValue(deferredVersion.promise);
|
||||||
var result = service.getImagePromise({});
|
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(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');
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -17,3 +17,6 @@ issues:
|
|||||||
other:
|
other:
|
||||||
- Glance v2 doesn't support the copy-from feature, so this feature is
|
- Glance v2 doesn't support the copy-from feature, so this feature is
|
||||||
disabled in Horizon when using Glance v2.
|
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.
|
||||||
|
Loading…
Reference in New Issue
Block a user