diff --git a/src/glance.js b/src/glance.js index 2175c07..1d42002 100644 --- a/src/glance.js +++ b/src/glance.js @@ -53,6 +53,28 @@ export default class Glance { this.http = new Http(); } + /** + * This method resolves any passed token into an appropriate header, as well as the base URL + * for the glance API. these variables may then be used to feed other requests. + * + * @param {Promise|String} token A promise, or string, representing a token. + * @returns {Promise} A promise which resolves with [url, token]. + * @private + */ + _requestComponents (token = null) { + // Make sure the token is a promise. + let headerPromise = new Promise((resolve) => resolve(token)) + .then((token) => { + if (token) { + return { + 'X-Auth-Token': token + }; + } + return {}; + }); + return Promise.all([this.serviceEndpoint(), headerPromise]); + } + /** * Retrieve all the API versions available. * @@ -106,4 +128,18 @@ export default class Glance { } return this._endpointPromise; } + + /** + * List the images available on glance. + * + * @param {String} token An authorization token, or a promise which will resolve into one. + * @returns {Promise.} A promise which will resolve with the list of images. + */ + imageList (token = null) { + return this + ._requestComponents(token) + .then(([url, headers]) => this.http.httpRequest('GET', `${url}images`, headers)) + .then((response) => response.json()) + .then((body) => body.images); + } } diff --git a/test/functional/glanceTest.js b/test/functional/glanceTest.js index 386eeb6..e64be7f 100644 --- a/test/functional/glanceTest.js +++ b/test/functional/glanceTest.js @@ -79,4 +79,22 @@ describe("Glance", () => { .catch((error) => done.fail(error)); }); }); + + describe("imageList()", () => { + + /** + * Assert that we can get a list of images. + */ + it("should return a supported version.", (done) => { + configPromise + .then((config) => new Glance(config)) + .then((glance) => glance.imageList(tokenPromise)) + .then((images) => { + expect(images.length > 0).toBeTruthy(); + done(); + }) + .catch((error) => done.fail(error)); + }); + }); + }); diff --git a/test/unit/glanceTest.js b/test/unit/glanceTest.js index 1a4d1a4..2d61d8a 100644 --- a/test/unit/glanceTest.js +++ b/test/unit/glanceTest.js @@ -187,4 +187,45 @@ describe('Glance', () => { .catch((error) => done.fail(error)); }); }); + + describe("imageList()", () => { + let glance = null; + + beforeEach(() => { + fetchMock.mock(mockData.root()); + glance = new Glance(mockData.config); + }); + + it("should return the images as an array.", (done) => { + const token = 'test_token'; + + fetchMock.mock(mockData.imageList(token)); + glance + .imageList(token) + .then((images) => { + expect(images.length).not.toBe(0); + done(); + }) + .catch((error) => done.fail(error)); + }); + + it("Should not cache its results", (done) => { + const token = 'test_token'; + + let mockOptions = mockData.imageList(token); + fetchMock.mock(mockOptions); + + glance + .imageList(token) + .then(() => { + expect(fetchMock.calls(mockOptions.name).length).toEqual(1); + return glance.imageList(token); + }) + .then(() => { + expect(fetchMock.calls(mockOptions.name).length).toEqual(2); + done(); + }) + .catch((error) => done.fail(error)); + }); + }); }); diff --git a/test/unit/helpers/data/glance.js b/test/unit/helpers/data/glance.js index ebb4ad4..64e1558 100644 --- a/test/unit/helpers/data/glance.js +++ b/test/unit/helpers/data/glance.js @@ -108,7 +108,87 @@ function rootResponse () { }; } +function imageList (token) { + return { + method: 'GET', + matcher: 'http://192.168.99.99:9292/v2/images', + headers: { + 'X-Auth-Token': token + }, + response: { + images: [ + { + status: 'active', + name: 'cirros-0.3.4-x86_64-uec', + tags: [], + kernel_id: '7c26de84-1ad7-4851-aea5-5c173d0605c8', + container_format: 'ami', + created_at: '2016-08-26T17:16:10Z', + ramdisk_id: '3ac21034-3764-407a-baab-966db753e3e5', + disk_format: 'ami', + updated_at: '2016-08-26T17:16:10Z', + visibility: 'public', + self: '/v2/images/8f3c7c9a-d812-46b1-9223-aa2d8f12c10a', + min_disk: 0, + protected: false, + id: '8f3c7c9a-d812-46b1-9223-aa2d8f12c10a', + size: 25165824, + file: '/v2/images/8f3c7c9a-d812-46b1-9223-aa2d8f12c10a/file', + checksum: 'eb9139e4942121f22bbc2afc0400b2a4', + owner: 'fcfe212681764e0595df8df83fd019f6', + virtual_size: null, + min_ram: 0, + schema: '/v2/schemas/image' + }, + { + status: 'active', + name: 'cirros-0.3.4-x86_64-uec-ramdisk', + tags: [], + container_format: 'ari', + created_at: '2016-08-26T17:16:09Z', + size: 3740163, + disk_format: 'ari', + updated_at: '2016-08-26T17:16:09Z', + visibility: 'public', + self: '/v2/images/3ac21034-3764-407a-baab-966db753e3e5', + min_disk: 0, + protected: false, + id: '3ac21034-3764-407a-baab-966db753e3e5', + file: '/v2/images/3ac21034-3764-407a-baab-966db753e3e5/file', + checksum: 'be575a2b939972276ef675752936977f', + owner: 'fcfe212681764e0595df8df83fd019f6', + virtual_size: null, + min_ram: 0, + schema: '/v2/schemas/image' + }, + { + status: 'active', + name: 'cirros-0.3.4-x86_64-uec-kernel', + tags: [], + container_format: 'aki', + created_at: '2016-08-26T17:16:08Z', + size: 4979632, + disk_format: 'aki', + updated_at: '2016-08-26T17:16:08Z', + visibility: 'public', + self: '/v2/images/7c26de84-1ad7-4851-aea5-5c173d0605c8', + min_disk: 0, + protected: false, + id: '7c26de84-1ad7-4851-aea5-5c173d0605c8', + file: '/v2/images/7c26de84-1ad7-4851-aea5-5c173d0605c8/file', + checksum: '8a40c862b5735975d82605c1dd395796', + owner: 'fcfe212681764e0595df8df83fd019f6', + virtual_size: null, + min_ram: 0, + schema: '/v2/schemas/image' + }], + schema: '/v2/schemas/images', + first: '/v2/images' + } + }; +} export { glanceConfig as config, - rootResponse as root + rootResponse as root, + imageList };