1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | 'use strict';
|
18 |
|
19 | const q = require('q');
|
20 | const util = require('./util');
|
21 | const Logger = require('./logger');
|
22 |
|
23 | const LICENSE_PATH = '/cm/shared/licensing/pools/';
|
24 | const LICENSE_TIMEOUT = { maxRetries: 40, retryIntervalMs: 5000 };
|
25 |
|
26 | let logger;
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | function BigIq50LicenseProvider(bigIp, options) {
|
42 | const injectedLogger = options ? options.logger : undefined;
|
43 | let loggerOptions = options ? options.loggerOptions : undefined;
|
44 |
|
45 | if (injectedLogger) {
|
46 | this.logger = injectedLogger;
|
47 | util.setLogger(injectedLogger);
|
48 | } else {
|
49 | loggerOptions = loggerOptions || { logLevel: 'none' };
|
50 | loggerOptions.module = module;
|
51 | this.logger = Logger.getLogger(loggerOptions);
|
52 | util.setLoggerOptions(loggerOptions);
|
53 | }
|
54 |
|
55 | logger = this.logger;
|
56 | this.bigIp = bigIp;
|
57 | }
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 | BigIq50LicenseProvider.prototype.getUnmanagedDeviceLicense = function getUnmanagedDeviceLicense(
|
71 | bigIqControl,
|
72 | poolName,
|
73 | bigIpMgmtAddress,
|
74 | bigIpMgmtPort
|
75 | ) {
|
76 | let poolUuid;
|
77 |
|
78 | this.logger.debug('Getting BIG-IP license pool UUID.');
|
79 | return getPoolUuid(bigIqControl, poolName)
|
80 | .then((response) => {
|
81 | poolUuid = response;
|
82 | logger.silly('Got pool UUID:', poolUuid);
|
83 |
|
84 | this.logger.debug('Requesting license from BIG-IQ license pool.');
|
85 | return bigIqControl.create(
|
86 | `${LICENSE_PATH}${poolUuid}/members`,
|
87 | {
|
88 | deviceAddress: `${bigIpMgmtAddress}:${bigIpMgmtPort}`,
|
89 | username: this.bigIp.user,
|
90 | password: this.bigIp.password
|
91 | }
|
92 | );
|
93 | })
|
94 | .then((response) => {
|
95 | this.logger.debug(response);
|
96 |
|
97 | let licenseUuid;
|
98 |
|
99 | const isLicensed = function () {
|
100 | const deferred = q.defer();
|
101 |
|
102 | bigIqControl.list(`${LICENSE_PATH}${poolUuid}/members/${licenseUuid}`)
|
103 | .then((licenseUuidRespnse) => {
|
104 | const state = licenseUuidRespnse.state;
|
105 | this.logger.verbose('Current licensing state:', state);
|
106 | if (state === 'LICENSED') {
|
107 | deferred.resolve();
|
108 | } else {
|
109 | deferred.reject();
|
110 | }
|
111 | });
|
112 |
|
113 | return deferred.promise;
|
114 | };
|
115 |
|
116 | if (response) {
|
117 | const state = response.state;
|
118 | licenseUuid = response.uuid;
|
119 | this.logger.verbose('Current licensing state:', state);
|
120 | this.logger.debug('License UUID:', licenseUuid);
|
121 |
|
122 | if (state === 'LICENSED') {
|
123 | return q();
|
124 | }
|
125 | this.logger.verbose('Waiting to be LICENSED.');
|
126 | return util.tryUntil(this, this.getLicenseTimeout(), isLicensed)
|
127 | .then(() => {
|
128 | return q();
|
129 | })
|
130 | .catch(() => {
|
131 | return q.reject(new Error('Giving up on licensing via BIG-IQ.'));
|
132 | });
|
133 | }
|
134 |
|
135 | return q();
|
136 | });
|
137 | };
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 | BigIq50LicenseProvider.prototype.revoke = function revoke(bigIqControl, poolName, instance) {
|
149 | let poolUuid;
|
150 |
|
151 | this.logger.debug('Getting BIG-IP license pool UUID.');
|
152 | return getPoolUuid(bigIqControl, poolName)
|
153 | .then((response) => {
|
154 | poolUuid = response;
|
155 | this.logger.debug('Getting licenses in pool');
|
156 | return bigIqControl.list(`${LICENSE_PATH}${poolUuid}/members/`);
|
157 | })
|
158 | .then((response) => {
|
159 | const licenses = response || [];
|
160 | let license;
|
161 |
|
162 | for (let i = 0; i < licenses.length; i++) {
|
163 | if (licenses[i].deviceName && licenses[i].deviceName === instance.hostname) {
|
164 | license = licenses[i];
|
165 | break;
|
166 | }
|
167 | }
|
168 |
|
169 | if (license) {
|
170 | return bigIqControl.delete(
|
171 | `${LICENSE_PATH}${poolUuid}/members/${license.uuid}`,
|
172 | {
|
173 | username: this.bigIp.user || 'dummyUser',
|
174 | password: this.bigIp.password || 'dummyPassword',
|
175 | uuid: license.uuid
|
176 | }
|
177 | );
|
178 | }
|
179 |
|
180 | return q.reject(new Error('no license found for host:', instance.hostname));
|
181 | });
|
182 | };
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 | BigIq50LicenseProvider.prototype.getLicenseTimeout = function getLicenseTimeout() {
|
192 | return LICENSE_TIMEOUT;
|
193 | };
|
194 |
|
195 | function getPoolUuid(bigIqControl, poolName) {
|
196 | return bigIqControl.list(`${LICENSE_PATH}?$select=uuid,name`)
|
197 | .then((response) => {
|
198 | logger.debug(response);
|
199 |
|
200 | let poolUuid;
|
201 |
|
202 | if (Array.isArray(response)) {
|
203 | for (let i = 0; i < response.length; i++) {
|
204 | if (response[i].name === poolName) {
|
205 | poolUuid = response[i].uuid;
|
206 | break;
|
207 | }
|
208 | }
|
209 |
|
210 | if (poolUuid) {
|
211 | return poolUuid;
|
212 | }
|
213 | return q.reject(new Error(`No license pool found with name: ${poolName}`));
|
214 | }
|
215 |
|
216 | return q.reject(new Error(`Error getting license pools: ${response}`));
|
217 | });
|
218 | }
|
219 |
|
220 | module.exports = BigIq50LicenseProvider;
|