Browse Source

Added support for multi-region catalog

OpenStack wrapper will read the 'region_name' from config, and use
the correct endpoint matching this region

Change-Id: I01049f3bed227eb1e11f9a1f7d338177e95aef34
Corentin Ardeois 2 years ago
parent
commit
0a4fb9f8b9

+ 4
- 1
src/openstack.js View File

@@ -83,10 +83,13 @@ export default class OpenStack {
83 83
    * @private
84 84
    */
85 85
   _getComponentConfigFor(name) {
86
+    const config = this.getConfig();
86 87
     return this._token
87 88
       .then((token) => this._keystone.then((keystone) => keystone.catalogList(token)))
88 89
       .then((catalog) => catalog.find((entry) => entry.name === name))
89
-      .then((entry) => entry.endpoints.find((endpoint) => endpoint.interface === 'public'));
90
+      .then((entry) => entry.endpoints.find((endpoint) => {
91
+        return endpoint.region === config.region_name && endpoint.interface === 'public';
92
+      }));
90 93
   }
91 94
 
92 95
 }

+ 21
- 0
test/unit/helpers/data/keystone.js View File

@@ -253,6 +253,27 @@ const catalogListData = [
253 253
         region: "RegionOne",
254 254
         interface: "admin",
255 255
         id: "bd8db1bafe41489bbbc45641e525ee7d"
256
+      },
257
+      {
258
+        region_id: "RegionTwo",
259
+        url: "http://192.168.99.100:9696/",
260
+        region: "RegionTwo",
261
+        interface: "public",
262
+        id: "7033fa4ebed74e3fa51753162150a1f2"
263
+      },
264
+      {
265
+        region_id: "RegionTwo",
266
+        url: "http://192.168.99.100:9696/",
267
+        region: "RegionOne",
268
+        interface: "RegionTwo",
269
+        id: "7aa942d402a34d4c90454b9d84285855"
270
+      },
271
+      {
272
+        region_id: "RegionTwo",
273
+        url: "http://192.168.99.100:9696/",
274
+        region: "RegionTwo",
275
+        interface: "admin",
276
+        id: "bd8db1bafe41489bbbc45641e525ee7d"
256 277
       }
257 278
     ],
258 279
     type: "network",

+ 14
- 9
test/unit/helpers/data/openstack.js View File

@@ -22,16 +22,21 @@
22 22
 /**
23 23
  * Mock cloud configuration that matches our test data below. This is not a full clouds.yaml
24 24
  * format, rather just the subsection pointing to a particular cloud.
25
+ * @param {String} regionName A region name to use
26
+ * @returns {{}} a cloud config object.
25 27
  */
26
-const cloudConfig = {
27
-  region_name: 'Region1',
28
-  auth: {
29
-    username: 'user',
30
-    password: 'pass',
31
-    project_name: 'js-openstack-lib',
32
-    auth_url: 'http://192.168.99.99/'
33
-  }
34
-};
28
+function cloudConfig(regionName = 'RegionOne') {
29
+  return {
30
+    region_name: regionName,
31
+    auth: {
32
+      username: 'user',
33
+      password: 'pass',
34
+      project_name: 'js-openstack-lib',
35
+      auth_url: 'http://192.168.99.99/'
36
+    }
37
+  };
38
+}
39
+
35 40
 export {
36 41
   cloudConfig as config,
37 42
 };

+ 25
- 7
test/unit/openstackTest.js View File

@@ -11,7 +11,7 @@ describe("Simple test", () => {
11 11
   afterEach(fetchMock.restore);
12 12
 
13 13
   it("should export a class", () => {
14
-    let t = new OpenStack(openStackMockData.config);
14
+    let t = new OpenStack(openStackMockData.config());
15 15
     expect(t).toBeDefined();
16 16
   });
17 17
 
@@ -25,14 +25,14 @@ describe("Simple test", () => {
25 25
   });
26 26
 
27 27
   it("getConfig should returns the config", () => {
28
-    let openstack = new OpenStack(openStackMockData.config);
28
+    let openstack = new OpenStack(openStackMockData.config());
29 29
     let config = openstack.getConfig();
30
-    expect(config.region_name).toEqual('Region1');
30
+    expect(config.region_name).toEqual('RegionOne');
31 31
   });
32 32
 
33 33
   describe('networkList', () => {
34 34
     it('should fetch networkList from neutron', (done) => {
35
-      const openstack = new OpenStack(openStackMockData.config);
35
+      const openstack = new OpenStack(openStackMockData.config());
36 36
       const neutron = mockNeutron(openstack);
37 37
       const networksData = neutronMockData.networkList('token').response.networks;
38 38
 
@@ -50,7 +50,7 @@ describe("Simple test", () => {
50 50
   describe('_neutron', () => {
51 51
     it('creates Neutron instance with the correct endpoint', (done) => {
52 52
       const token = 'test_token';
53
-      const openstack = new OpenStack(openStackMockData.config);
53
+      const openstack = new OpenStack(openStackMockData.config());
54 54
       const keystone = mockKeystone(openstack);
55 55
       const catalogData = keystoneMockData.catalogList(token).response.catalog;
56 56
 
@@ -67,8 +67,26 @@ describe("Simple test", () => {
67 67
         .catch((error) => done.fail(error));
68 68
     });
69 69
 
70
+    it('creates Neutron instance for the correct endpoint', (done) => {
71
+      const token = 'test_token';
72
+      const openstack = new OpenStack(openStackMockData.config('RegionTwo'));
73
+      const keystone = mockKeystone(openstack);
74
+      const catalogData = keystoneMockData.catalogList(token).response.catalog;
75
+
76
+      spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve(token));
77
+      spyOn(keystone, 'catalogList').and.returnValue(Promise.resolve(catalogData));
78
+
79
+      openstack._neutron
80
+        .then((neutron) => {
81
+          expect(neutron).toEqual(jasmine.any(Neutron));
82
+          expect(neutron.endpointUrl).toEqual('http://192.168.99.100:9696/');
83
+          done();
84
+        })
85
+        .catch((error) => done.fail(error));
86
+    });
87
+
70 88
     it('should cache Neutron instance and Keystone token', (done) => {
71
-      const openstack = new OpenStack(openStackMockData.config);
89
+      const openstack = new OpenStack(openStackMockData.config());
72 90
       const tokenIssueMock = keystoneMockData.tokenIssue();
73 91
       const catalogListMock = keystoneMockData.catalogList('test_token');
74 92
 
@@ -95,7 +113,7 @@ describe("Simple test", () => {
95 113
 
96 114
   describe('_token', () => {
97 115
     it('should fetch the token and cache it', (done) => {
98
-      const openstack = new OpenStack(openStackMockData.config);
116
+      const openstack = new OpenStack(openStackMockData.config());
99 117
       const keystone = mockKeystone(openstack);
100 118
 
101 119
       spyOn(keystone, 'tokenIssue').and.returnValue(Promise.resolve('test_token'));

Loading…
Cancel
Save