Added networkList() method to OpenStack wrapper
This patch adds the networkList() method to the OpenStack wrapper class. This method will initialize `Neutron` instance if needed and cache it. As neutron needs the URL, `Keystone` instance is also initialize and cache if needed. Change-Id: If12af29a86b9856a145c1f91de25eb3473938de5
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
import Keystone from "./keystone";
|
||||||
|
import Neutron from "./neutron";
|
||||||
|
|
||||||
export default class OpenStack {
|
export default class OpenStack {
|
||||||
/**
|
/**
|
||||||
* Create wrapper class that takes clouds.yaml instance
|
* Create wrapper class that takes clouds.yaml instance
|
||||||
@@ -15,8 +18,75 @@ export default class OpenStack {
|
|||||||
|
|
||||||
this.cloudConfig = cloudConfig;
|
this.cloudConfig = cloudConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
getConfig() {
|
getConfig() {
|
||||||
// Returns the config instance
|
// Returns the config instance
|
||||||
return this.cloudConfig;
|
return this.cloudConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List the networks available.
|
||||||
|
*
|
||||||
|
* @returns {Promise.<T>} A promise which will resolve with the list of networks.
|
||||||
|
*/
|
||||||
|
networkList() {
|
||||||
|
return this._neutron
|
||||||
|
.then((neutron) => neutron.networkList(this._token));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keystone component.
|
||||||
|
*
|
||||||
|
* @returns {Promise.<Keystone>} A promise which will resolve with Keystone instance.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
get _keystone() {
|
||||||
|
if (!this._keystonePromise) {
|
||||||
|
this._keystonePromise = Promise.resolve(new Keystone(this.getConfig()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._keystonePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Neutron component.
|
||||||
|
*
|
||||||
|
* @returns {Promise.<Neutron>} A promise which will resolve with Neutron instance.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
get _neutron() {
|
||||||
|
if (!this._neutronPromise) {
|
||||||
|
this._neutronPromise = this._getComponentConfigFor('neutron')
|
||||||
|
.then((componentConfig) => new Neutron(componentConfig));
|
||||||
|
}
|
||||||
|
return this._neutronPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token issued from Keystone.
|
||||||
|
*
|
||||||
|
* @returns {Promise.<T>} A promise which will resolve with the token.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
get _token() {
|
||||||
|
if (!this._tokenPromise) {
|
||||||
|
this._tokenPromise = this._keystone.then((k) => k.tokenIssue());
|
||||||
|
}
|
||||||
|
return this._tokenPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an component config from keystone catalog.
|
||||||
|
*
|
||||||
|
* @param {String} name A component name to find.
|
||||||
|
* @returns {Promise.<{}>} A promise which will resolve with the component config.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_getComponentConfigFor(name) {
|
||||||
|
return this._token
|
||||||
|
.then((token) => this._keystone.then((keystone) => keystone.catalogList(token)))
|
||||||
|
.then((catalog) => catalog.find((entry) => entry.name === name))
|
||||||
|
.then((entry) => entry.endpoints.find((endpoint) => endpoint.interface === 'public'));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -52,6 +52,15 @@ export default class AbstractService {
|
|||||||
return this._supportedVersions || [];
|
return this._supportedVersions || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our endpoint URL for this service.
|
||||||
|
*
|
||||||
|
* @returns {string} The URL of our service.
|
||||||
|
*/
|
||||||
|
get endpointUrl() {
|
||||||
|
return this._endpointUrl;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all the API versions available.
|
* Retrieve all the API versions available.
|
||||||
*
|
*
|
||||||
|
23
test/functional/openstackTest.js
Normal file
23
test/functional/openstackTest.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import config from "./helpers/cloudsConfig";
|
||||||
|
import OpenStack from "../../src/openstack";
|
||||||
|
import log from 'loglevel';
|
||||||
|
|
||||||
|
log.setLevel("DEBUG");
|
||||||
|
|
||||||
|
describe("OpenStack", () => {
|
||||||
|
let devstackConfig = config.clouds.devstack;
|
||||||
|
|
||||||
|
describe("networkList()", () => {
|
||||||
|
it("should return the networks as an array.", (done) => {
|
||||||
|
const openstack = new OpenStack(devstackConfig);
|
||||||
|
|
||||||
|
openstack.networkList()
|
||||||
|
.then((networks) => {
|
||||||
|
expect(networks.length > 0).toBeTruthy();
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch((error) => done.fail(error));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -1,16 +1,17 @@
|
|||||||
import OpenStack from "../../src/openstack";
|
import OpenStack from "../../src/openstack";
|
||||||
import * as mockData from './helpers/data/openstack';
|
import * as openStackMockData from './helpers/data/openstack';
|
||||||
|
import * as neutronMockData from './helpers/data/neutron';
|
||||||
const FetchMock = require('fetch-mock');
|
import * as keystoneMockData from './helpers/data/keystone';
|
||||||
|
import fetchMock from 'fetch-mock';
|
||||||
|
import Neutron from "../../src/neutron";
|
||||||
|
import Keystone from "../../src/keystone";
|
||||||
|
|
||||||
describe("Simple test", () => {
|
describe("Simple test", () => {
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(fetchMock.restore);
|
||||||
FetchMock.reset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should export a class", () => {
|
it("should export a class", () => {
|
||||||
let t = new OpenStack(mockData.config);
|
let t = new OpenStack(openStackMockData.config);
|
||||||
expect(t).toBeDefined();
|
expect(t).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -24,9 +25,106 @@ describe("Simple test", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("getConfig should returns the config", () => {
|
it("getConfig should returns the config", () => {
|
||||||
let openstack = new OpenStack(mockData.config);
|
let openstack = new OpenStack(openStackMockData.config);
|
||||||
let config = openstack.getConfig();
|
let config = openstack.getConfig();
|
||||||
expect(config.region_name).toEqual('Region1');
|
expect(config.region_name).toEqual('Region1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('networkList', () => {
|
||||||
|
it('should fetch networkList from neutron', (done) => {
|
||||||
|
const openstack = new OpenStack(openStackMockData.config);
|
||||||
|
const neutron = mockNeutron(openstack);
|
||||||
|
const networksData = neutronMockData.networkList('token').response.networks;
|
||||||
|
|
||||||
|
spyOn(neutron, 'networkList').and.returnValue(Promise.resolve(networksData));
|
||||||
|
|
||||||
|
openstack.networkList()
|
||||||
|
.then((networks) => {
|
||||||
|
expect(networks.length).toBe(2);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch((error) => done.fail(error));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('_neutron', () => {
|
||||||
|
it('creates Neutron instance with the correct endpoint', (done) => {
|
||||||
|
const token = 'test_token';
|
||||||
|
const openstack = new OpenStack(openStackMockData.config);
|
||||||
|
const keystone = mockKeystone(openstack);
|
||||||
|
const catalogData = keystoneMockData.catalogList(token).response.catalog;
|
||||||
|
|
||||||
|
spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token));
|
||||||
|
spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData));
|
||||||
|
|
||||||
|
openstack._neutron
|
||||||
|
.then((neutron) => {
|
||||||
|
expect(keystone.catalogList).toHaveBeenCalledWith(token);
|
||||||
|
expect(neutron).toEqual(jasmine.any(Neutron));
|
||||||
|
expect(neutron.endpointUrl).toEqual('http://192.168.99.99:9696/');
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch((error) => done.fail(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should cache Neutron instance and Keystone token', (done) => {
|
||||||
|
const openstack = new OpenStack(openStackMockData.config);
|
||||||
|
const tokenIssueMock = keystoneMockData.tokenIssue();
|
||||||
|
const catalogListMock = keystoneMockData.catalogList('test_token');
|
||||||
|
|
||||||
|
fetchMock.mock(keystoneMockData.root());
|
||||||
|
fetchMock.mock(tokenIssueMock);
|
||||||
|
fetchMock.mock(catalogListMock);
|
||||||
|
|
||||||
|
openstack._neutron
|
||||||
|
.then((neutron) => {
|
||||||
|
expect(neutron).toEqual(jasmine.any(Neutron));
|
||||||
|
expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1);
|
||||||
|
expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1);
|
||||||
|
return openstack._neutron;
|
||||||
|
})
|
||||||
|
.then((neutron) => {
|
||||||
|
expect(neutron).toEqual(jasmine.any(Neutron));
|
||||||
|
expect(fetchMock.calls(tokenIssueMock.matcher).length).toEqual(1);
|
||||||
|
expect(fetchMock.calls(catalogListMock.matcher).length).toEqual(1);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch((error) => done.fail(error));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('_token', () => {
|
||||||
|
it('should fetch the token and cache it', (done) => {
|
||||||
|
const openstack = new OpenStack(openStackMockData.config);
|
||||||
|
const keystone = mockKeystone(openstack);
|
||||||
|
|
||||||
|
spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve('test_token'));
|
||||||
|
|
||||||
|
openstack._token
|
||||||
|
.then((token) => {
|
||||||
|
expect(token).toEqual('test_token');
|
||||||
|
expect(keystone.tokenIssue.calls.count()).toEqual(1);
|
||||||
|
return openstack._token;
|
||||||
|
})
|
||||||
|
.then((token) => {
|
||||||
|
expect(token).toEqual('test_token');
|
||||||
|
expect(keystone.tokenIssue.calls.count()).toEqual(1);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch((error) => done.fail(error));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function mockKeystone(openstack) {
|
||||||
|
const keystone = new Keystone(keystoneMockData.config);
|
||||||
|
openstack._keystonePromise = Promise.resolve(keystone);
|
||||||
|
return keystone;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mockNeutron(openstack) {
|
||||||
|
const neutron = new Neutron(neutronMockData.config);
|
||||||
|
openstack._neutronPromise = Promise.resolve(neutron);
|
||||||
|
return neutron;
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user