UNPKG

9.16 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 takeIntersection(vpcZones, fcAllowedZones, nasZones) {
90 const threeIntersection = _.filter(vpcZones, z => {
91 return _.includes(fcAllowedZones, z.ZoneId) && _.includes(nasZones.map(zone => { return zone.ZoneId; }), z.ZoneId);
92 });
93 if (!_.isEmpty(threeIntersection)) {
94 return threeIntersection;
95 }
96 return _.filter(vpcZones, z => {
97 return _.includes(fcAllowedZones, z.ZoneId);
98 });
99}
100function selectVSwitchZoneId(fcAllowedZones, vpcZones, nasZones) {
101 return __awaiter(this, void 0, void 0, function* () {
102 const allowedZones = takeIntersection(vpcZones, fcAllowedZones, nasZones);
103 const sortedZones = _.sortBy(allowedZones, ['ZoneId']);
104 return (_.head(sortedZones) || {}).ZoneId;
105 });
106}
107function getFcAllowedZones() {
108 return __awaiter(this, void 0, void 0, function* () {
109 const fc = yield getFcClient();
110 const fcRs = yield fc.getAccountSettings();
111 const fcAllowedZones = fcRs.data.availableAZs;
112 debug('fc allowed zones: %j', fcAllowedZones);
113 if (_.isEqual(fcAllowedZones, [''])) {
114 const profile = yield getProfile();
115 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}`));
116 }
117 return fcAllowedZones;
118 });
119}
120function selectAllowedVSwitchZone(vpcClient, region) {
121 return __awaiter(this, void 0, void 0, function* () {
122 const nasClient = yield getNasPopClient();
123 const fcAllowedZones = yield getFcAllowedZones();
124 const vpcZones = yield describeVpcZones(vpcClient, region);
125 const nasZones = yield require('./nas').describeNasZones(nasClient, region);
126 const usedZoneId = yield selectVSwitchZoneId(fcAllowedZones, vpcZones, nasZones);
127 if (!usedZoneId) {
128 throw new Error('no availiable zone for vswitch');
129 }
130 debug('select allowed switch zone: ', usedZoneId);
131 return usedZoneId;
132 });
133}
134function describeVpcZones(vpcClient, region) {
135 return __awaiter(this, void 0, void 0, function* () {
136 const params = {
137 'RegionId': region
138 };
139 const zones = yield vpcClient.request('DescribeZones', params, requestOption);
140 return zones.Zones.Zone;
141 });
142}
143function convertToFcAllowedZones(vpcClient, region, vswitchIds) {
144 return __awaiter(this, void 0, void 0, function* () {
145 const fcAllowedZones = yield getFcAllowedZones();
146 const fcZones = [];
147 for (const vswitchId of vswitchIds) {
148 const zoneId = yield getVSwitchZoneId(vpcClient, region, vswitchId);
149 if (_.includes(fcAllowedZones, zoneId)) {
150 fcZones.push({ zoneId, vswitchId });
151 }
152 }
153 if (_.isEmpty(fcZones)) {
154 throw new Error(`
155Only zoneId ${fcAllowedZones} of vswitch is allowed by VpcConfig.
156Check your vswitch zoneId please.`);
157 }
158 return fcZones;
159 });
160}
161function convertZones(nasZones, zones, storageType = 'Performance') {
162 const zoneId = nasZones.ZoneId;
163 const vswitchId = zones.filter(f => { return f.zoneId === zoneId; });
164 return {
165 zoneId,
166 vswitchId: _.head(vswitchId).vswitchId,
167 storageType
168 };
169}
170function processDifferentZones(nasZones, FcAllowVswitchId) {
171 const performance = _.find(nasZones, nasZone => !_.isEmpty(nasZone.Performance.Protocol));
172 if (!_.isEmpty(performance)) {
173 return {
174 zoneId: performance.ZoneId,
175 vswitchId: FcAllowVswitchId,
176 storageType: 'Performance'
177 };
178 }
179 const capacity = _.find(nasZones, nasZone => !_.isEmpty(nasZone.Capacity.Protocol));
180 if (!_.isEmpty(capacity)) {
181 return {
182 zoneId: capacity.ZoneId,
183 vswitchId: FcAllowVswitchId,
184 storageType: 'Capacity'
185 };
186 }
187 return null;
188}
189function getAvailableVSwitchId(vpcClient, region, vswitchIds, nasZones) {
190 return __awaiter(this, void 0, void 0, function* () {
191 const fcZones = yield convertToFcAllowedZones(vpcClient, region, vswitchIds);
192 const availableZones = fcZones.filter(fcZone => { return _.includes(nasZones.map(m => { return m.ZoneId; }), fcZone.zoneId); });
193 const performances = [];
194 const capacities = [];
195 _.forEach(nasZones, nasZone => {
196 if (_.includes(availableZones.map(z => z.zoneId), nasZone.ZoneId)) {
197 if (!_.isEmpty(nasZone.Performance.Protocol)) {
198 performances.push(nasZone);
199 }
200 if (!_.isEmpty(nasZone.Capacity.Protocol)) {
201 capacities.push(nasZone);
202 }
203 }
204 });
205 if (!_.isEmpty(performances)) {
206 return convertZones(_.head(performances), availableZones);
207 }
208 if (!_.isEmpty(capacities)) {
209 const msg = `Region ${region} only supports capacity NAS. Do you want to create it automatically?`;
210 const yes = yield promptForConfirmContinue(msg);
211 if (yes) {
212 return convertZones(_.head(capacities), availableZones, 'Capacity');
213 }
214 throw new Error(`No NAS service available under region ${region}.`);
215 }
216 return processDifferentZones(nasZones, _.head(fcZones).vswitchId);
217 });
218}
219module.exports = {
220 findVswitchExistByName,
221 selectVSwitchZoneId,
222 createVSwitch,
223 createDefaultVSwitch,
224 getAvailableVSwitchId
225};