UNPKG

8.79 kBJavaScriptView Raw
1'use strict';
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 return new (P || (P = Promise))(function (resolve, reject) {
4 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7 step((generator = generator.apply(thisArg, _arguments || [])).next());
8 });
9};
10const _ = require('lodash');
11const debug = require('debug')('fun:nas');
12const { red } = require('colors');
13const { getProfile } = require('./profile');
14const { getFcClient, getNasPopClient } = require('./client');
15const { promptForConfirmContinue } = require('./init/prompt');
16var requestOption = {
17 method: 'POST'
18};
19function createDefaultVSwitch(vpcClient, region, vpcId, vswitchName) {
20 return __awaiter(this, void 0, void 0, function* () {
21 const vswitchZoneId = yield selectAllowedVSwitchZone(vpcClient, region);
22 var vswitchId;
23 try {
24 // 创建 vswitch
25 vswitchId = yield createVSwitch(vpcClient, {
26 region,
27 vpcId,
28 zoneId: vswitchZoneId,
29 vswitchName: vswitchName
30 });
31 }
32 catch (ex) {
33 throw ex;
34 }
35 return vswitchId;
36 });
37}
38function describeVSwitchAttributes(vpcClient, region, vswitchId) {
39 return __awaiter(this, void 0, void 0, function* () {
40 const params = {
41 'RegionId': region,
42 'VSwitchId': vswitchId
43 };
44 return yield vpcClient.request('DescribeVSwitchAttributes', params, requestOption);
45 });
46}
47function getVSwitchZoneId(vpcClient, region, vswitchId) {
48 return __awaiter(this, void 0, void 0, function* () {
49 const describeRs = yield describeVSwitchAttributes(vpcClient, region, vswitchId);
50 return (describeRs || {}).ZoneId;
51 });
52}
53function getVSwitchName(vpcClient, region, vswitchId) {
54 return __awaiter(this, void 0, void 0, function* () {
55 const describeRs = yield describeVSwitchAttributes(vpcClient, region, vswitchId);
56 return (describeRs || {}).VSwitchName;
57 });
58}
59function findVswitchExistByName(vpcClient, region, vswitchIds, searchVSwtichName) {
60 return __awaiter(this, void 0, void 0, function* () {
61 if (!_.isEmpty(vswitchIds)) {
62 for (let vswitchId of vswitchIds) {
63 const vswitchName = yield getVSwitchName(vpcClient, region, vswitchId);
64 if (_.isEqual(searchVSwtichName, vswitchName)) {
65 debug('found default vswitchId: ' + vswitchId);
66 return vswitchId;
67 }
68 }
69 }
70 debug('could not find %s from %j for region %s', searchVSwtichName, vswitchIds, region);
71 return null;
72 });
73}
74function createVSwitch(vpcClient, { region, vpcId, zoneId, vswitchName }) {
75 return __awaiter(this, void 0, void 0, function* () {
76 var params = {
77 'RegionId': region,
78 'VpcId': vpcId,
79 'ZoneId': zoneId,
80 'CidrBlock': '10.20.0.0/16',
81 'VSwitchName': vswitchName,
82 'Description': 'default vswitch created by fc fun'
83 };
84 debug('createVSwitch params is %j', params);
85 const createRs = yield vpcClient.request('CreateVSwitch', params, requestOption);
86 return createRs.VSwitchId;
87 });
88}
89function selectVSwitchZoneId(fcAllowedZones, vpcZones, nasZones) {
90 return __awaiter(this, void 0, void 0, function* () {
91 const allowedZones = _.filter(vpcZones, z => {
92 return _.includes(fcAllowedZones, z.ZoneId) && _.includes(nasZones.map(zone => { return zone.ZoneId; }), z.ZoneId);
93 });
94 const sortedZones = _.sortBy(allowedZones, ['ZoneId']);
95 return (_.head(sortedZones) || {}).ZoneId;
96 });
97}
98function getFcAllowedZones() {
99 return __awaiter(this, void 0, void 0, function* () {
100 const fc = yield getFcClient();
101 const fcRs = yield fc.getAccountSettings();
102 const fcAllowedZones = fcRs.data.availableAZs;
103 debug('fc allowed zones: %j', fcAllowedZones);
104 if (_.isEqual(fcAllowedZones, [''])) {
105 const profile = yield getProfile();
106 throw new Error(red(`No fc vswitch zones allowed, you may need login to fc console to apply for VPC feature: https://fc.console.aliyun.com/overview/${profile.defaultRegion}`));
107 }
108 return fcAllowedZones;
109 });
110}
111function selectAllowedVSwitchZone(vpcClient, region) {
112 return __awaiter(this, void 0, void 0, function* () {
113 const nasClient = yield getNasPopClient();
114 const fcAllowedZones = yield getFcAllowedZones();
115 const vpcZones = yield describeVpcZones(vpcClient, region);
116 const nasZones = yield require('./nas').describeNasZones(nasClient, region);
117 const usedZoneId = yield selectVSwitchZoneId(fcAllowedZones, vpcZones, nasZones);
118 if (!usedZoneId) {
119 throw new Error('no availiable zone for vswitch');
120 }
121 debug('select allowed switch zone: ', usedZoneId);
122 return usedZoneId;
123 });
124}
125function describeVpcZones(vpcClient, region) {
126 return __awaiter(this, void 0, void 0, function* () {
127 const params = {
128 'RegionId': region
129 };
130 const zones = yield vpcClient.request('DescribeZones', params, requestOption);
131 return zones.Zones.Zone;
132 });
133}
134function convertToFcAllowedZoneMap(vpcClient, region, vswitchIds) {
135 return __awaiter(this, void 0, void 0, function* () {
136 const fcAllowedZones = yield getFcAllowedZones();
137 const zoneMap = new Map();
138 for (const vswitchId of vswitchIds) {
139 const zoneId = yield getVSwitchZoneId(vpcClient, region, vswitchId);
140 if (_.includes(fcAllowedZones, zoneId)) {
141 zoneMap.set(zoneId, vswitchId);
142 }
143 }
144 if (_.isEmpty(zoneMap)) {
145 throw new Error(`
146Only zoneId ${fcAllowedZones} of vswitch is allowed by VpcConfig.
147Check your vswitch zoneId please.`);
148 }
149 return zoneMap;
150 });
151}
152function convertZones(zones, zoneMap, storageType = 'Performance') {
153 const zoneId = zones.ZoneId;
154 return {
155 zoneId,
156 vswitchId: zoneMap.get(zoneId),
157 storageType
158 };
159}
160function processDifferentZones(nasZones, FcAllowVswitchId) {
161 const performance = _.find(nasZones, nasZone => !_.isEmpty(nasZone.Performance.Protocol));
162 if (!_.isEmpty(performance)) {
163 return {
164 zoneId: performance.ZoneId,
165 vswitchId: FcAllowVswitchId,
166 storageType: 'Performance'
167 };
168 }
169 const capacity = _.find(nasZones, nasZone => !_.isEmpty(nasZone.Capacity.Protocol));
170 if (!_.isEmpty(capacity)) {
171 return {
172 zoneId: capacity.ZoneId,
173 vswitchId: FcAllowVswitchId,
174 storageType: 'Capacity'
175 };
176 }
177 return null;
178}
179function getAvailableVSwitchId(vpcClient, region, vswitchIds, nasZones) {
180 return __awaiter(this, void 0, void 0, function* () {
181 const zoneMap = yield convertToFcAllowedZoneMap(vpcClient, region, vswitchIds);
182 for (const zoneId of zoneMap.keys()) {
183 if (!_.includes(nasZones.map(m => { return m.ZoneId; }), zoneId)) {
184 zoneMap.delete(zoneId);
185 }
186 }
187 const performances = [];
188 const capacities = [];
189 _.forEach(nasZones, nasZone => {
190 if (_.includes([...zoneMap.keys()], nasZone.ZoneId)) {
191 if (!_.isEmpty(nasZone.Performance.Protocol)) {
192 performances.push(nasZone);
193 }
194 if (!_.isEmpty(nasZone.Capacity.Protocol)) {
195 capacities.push(nasZone);
196 }
197 }
198 });
199 if (!_.isEmpty(performances)) {
200 return convertZones(_.head(performances), zoneMap);
201 }
202 if (!_.isEmpty(capacities)) {
203 const msg = `Region ${region} only supports capacity NAS. Do you want to create it automatically?`;
204 const yes = yield promptForConfirmContinue(msg);
205 if (yes) {
206 return convertZones(_.head(capacities), zoneMap, 'Capacity');
207 }
208 throw new Error(`No NAS service available under region ${region}.`);
209 }
210 return processDifferentZones(nasZones, _.head([...zoneMap.values()]));
211 });
212}
213module.exports = {
214 findVswitchExistByName,
215 selectVSwitchZoneId,
216 createVSwitch,
217 createDefaultVSwitch,
218 getAvailableVSwitchId
219};