UNPKG

9.04 kBJavaScriptView Raw
1/**
2 * Copyright 2016-2018 F5 Networks, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17'use strict';
18
19/* eslint-disable no-console */
20
21const q = require('q');
22const options = require('commander');
23const fs = require('fs');
24const util = require('../lib/util');
25const path = require('path');
26const BigIp = require('../lib/bigIp');
27
28const LOG_ID = 'setMasterKey.js';
29const Logger = require('../lib/logger');
30const cloudProviderFactory = require('../lib/cloudProviderFactory');
31const BACKUP = require('../lib/sharedConstants').BACKUP;
32
33
34(function run() {
35 let logger;
36 let bigIp;
37 const runner = {
38 run(argv) {
39 const providerOptions = {};
40 const loggerOptions = {};
41 const tempUcsDir = `${BACKUP.UCS_LOCAL_TMP_DIRECTORY}/`;
42 const DEFAULT_LOG_FILE = '/var/log/cloudlibs/setMasterKey.log';
43 const PRIMARY_KEY_DIR = BACKUP.PRIMARY_KEY_DIR;
44 const UNIT_KEY_DIR = BACKUP.UNIT_KEY_DIR;
45 let cloudProvider;
46 options
47 .version('4.10.3')
48 .option(
49 '--hostname <username>',
50 'Hostname for BIGIP device',
51 'localhost'
52 )
53 .option(
54 '--username <username>',
55 'Username to access BIGIP device',
56 'admin'
57 )
58 .option(
59 '--password <password>',
60 'Password to access BIGIP device',
61 'admin'
62 )
63 .option(
64 '--mgmtPort <port>',
65 'Managment port on BIGIP device',
66 '8443'
67 )
68 .option(
69 '--cloud <cloud_provider>',
70 'Cloud provider (aws | azure | etc.)'
71 )
72 .option(
73 '--provider-options <cloud_options>',
74 'Options specific to cloud_provider. Ex: param1:value1,param2:value2',
75 util.map,
76 providerOptions
77 )
78 .option(
79 '--log-level <level>',
80 'Log level (none, error, warn, info, verbose, debug, silly). Default is info.', 'info'
81 )
82 .option(
83 '-o, --output <file>',
84 `Log to file. Default is ${DEFAULT_LOG_FILE}`, DEFAULT_LOG_FILE
85 )
86 .parse(argv);
87
88 /* eslint-enable max-len */
89 loggerOptions.console = true;
90 loggerOptions.logLevel = options.logLevel;
91 loggerOptions.fileName = options.output;
92 loggerOptions.module = module;
93 if (loggerOptions.fileName) {
94 const dirName = path.dirname(loggerOptions.fileName);
95 if (!fs.existsSync(dirName)) {
96 fs.mkdirSync(dirName);
97 }
98 }
99 logger = Logger.getLogger(loggerOptions);
100 bigIp = new BigIp({ loggerOptions });
101 util.setLoggerOptions(loggerOptions);
102 logger.silly(LOG_ID, `Options: ${JSON.stringify(options)}`);
103 logger.silly(LOG_ID, `Provider Options: ${JSON.stringify(providerOptions)}`);
104 logger.info(LOG_ID, 'Starting setting master key....');
105 return bigIp.init(
106 options.hostname,
107 options.username,
108 options.password,
109 {
110 port: options.mgmtPort
111 }
112 )
113 .then(() => {
114 logger.info(LOG_ID, `Cloud Provider ${options.cloud}`);
115 cloudProvider = cloudProviderFactory.getCloudProvider(
116 options.cloud,
117 {
118 loggerOptions,
119 clOptions: options
120 }
121 );
122 logger.info(LOG_ID, 'Initializing cloud provider');
123 return util.tryUntil(
124 cloudProvider,
125 util.MEDIUM_RETRY,
126 cloudProvider.init,
127 [providerOptions]
128 );
129 })
130 .then(() => {
131 logger.silly(LOG_ID, `provider is configured for ${options.cloud} cloud`);
132 logger.silly(LOG_ID, 'Grabbing ucs from cloud storage');
133 return cloudProvider.getStoredUcs();
134 })
135 .then((ucsData) => {
136 if (ucsData) {
137 return util.writeUcsFile(`${tempUcsDir}temp.ucs`, ucsData);
138 }
139 return q.resolve(false);
140 })
141 .then((response) => {
142 if (!response) {
143 util.logAndExit('no ucs file available - skipping step for setting master key');
144 return Promise.reject(new Error('no ucs file available'));
145 }
146 logger.silly('stopping bigip to set master key');
147 return util.runShellCommand('bigstart stop');
148 })
149 .then(() => {
150 logger.silly(LOG_ID, 'bigstart stopped. untarring ucs');
151 fs.mkdirSync(`${tempUcsDir}ucsContent/`);
152 return util.runShellCommand(
153 `tar --warning=no-timestamp -xf ${tempUcsDir}temp.ucs -C ${tempUcsDir}ucsContent/`
154 );
155 })
156 .then(() => {
157 logger.silly(LOG_ID, 'untar success, reading key');
158 return util.readDataFromFile(`${tempUcsDir}ucsContent${PRIMARY_KEY_DIR}`);
159 })
160 .then((oldMasterKey) => {
161 logger.silly(LOG_ID, 'read success, writing key');
162 return util.writeDataToFile(oldMasterKey, PRIMARY_KEY_DIR);
163 })
164 .then(() => {
165 logger.silly(LOG_ID, 'wrote master key, reading unit key');
166 return util.readDataFromFile(`${tempUcsDir}ucsContent${UNIT_KEY_DIR}`);
167 })
168 .then((oldUnitKey) => {
169 logger.silly(LOG_ID, 'read unitkey success, writing unit key');
170 return util.writeDataToFile(oldUnitKey, UNIT_KEY_DIR);
171 })
172 .then(() => {
173 logger.silly(LOG_ID, 'wrote master key; calling bigstart restart');
174 return util.runShellCommand('bigstart start');
175 })
176 .then(() => {
177 return bigIp.ready();
178 })
179 .then(() => {
180 logger.info(LOG_ID, 'Master Key is configured; ' +
181 'Restarting dhclient to set mgmt ip address');
182 return util.runShellCommand('bigstart restart dhclient');
183 })
184 .then(() => {
185 return util.tryUntil(this, util.MEDIUM_RETRY, () => {
186 return util.runShellCommand('tmsh list sys management-ip')
187 .then((response) => {
188 logger.silly(`Response for Managemetn Ip: ${response}`);
189 if (response) {
190 return Promise.resolve();
191 }
192 return Promise.reject(new Error('management ip is not configured on device'));
193 });
194 }, {});
195 })
196 .catch((err) => {
197 if (err.message === 'no ucs file available') {
198 process.exit(0);
199 }
200 logger.error(err.message);
201 })
202 .finally(() => {
203 if (fs.existsSync(tempUcsDir)) {
204 logger.silly(LOG_ID, 'cleaning up working directory');
205 return util.runShellCommand(`rm -rf ${tempUcsDir}`);
206 }
207 return Promise.resolve();
208 });
209 }
210 };
211
212 module.exports = runner;
213
214 // If we're called from the command line, run
215 // This allows for test code to call us as a module
216 if (!module.parent) {
217 runner.run(process.argv);
218 }
219}());