UNPKG

8.62 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 Ram = require('@alicloud/ram');
11const getProfile = require('./profile').getProfile;
12const promiseRetry = require('./retry');
13const { red } = require('colors');
14const debug = require('debug')('fun:ram');
15const _ = require('lodash');
16const { throwProcessedPopPermissionError } = require('./error-message');
17const FNF_ASSUME_ROLE_POLICY = {
18 'Statement': [
19 {
20 'Action': 'sts:AssumeRole',
21 'Effect': 'Allow',
22 'Principal': {
23 'Service': [
24 'fnf.aliyuncs.com'
25 ]
26 }
27 }
28 ],
29 'Version': '1'
30};
31const getRamClient = () => __awaiter(this, void 0, void 0, function* () {
32 const profile = yield getProfile();
33 const ram = new Ram({
34 accessKeyId: profile.accessKeyId,
35 accessKeySecret: profile.accessKeySecret,
36 endpoint: 'https://ram.aliyuncs.com',
37 opts: {
38 timeout: profile.timeout * 1000
39 }
40 });
41 const realRequest = ram.request.bind(ram);
42 ram.request = (action, params, options) => __awaiter(this, void 0, void 0, function* () {
43 try {
44 return yield realRequest(action, params, options);
45 }
46 catch (ex) {
47 yield throwProcessedPopPermissionError(ex, action);
48 throw ex;
49 }
50 });
51 return ram;
52});
53function normalizeRoleOrPoliceName(roleName) {
54 return roleName.replace(/_/g, '-');
55}
56function deletePolicyNotDefaultVersion(ram, policyName) {
57 return __awaiter(this, void 0, void 0, function* () {
58 const listResponse = yield ram.listPolicyVersions({
59 PolicyType: 'Custom',
60 PolicyName: policyName
61 });
62 const versions = (listResponse.PolicyVersions || {}).PolicyVersion;
63 if (versions) {
64 for (let version of versions) {
65 if (version.IsDefaultVersion === false) {
66 yield ram.deletePolicyVersion({
67 PolicyName: policyName,
68 VersionId: version.VersionId
69 });
70 }
71 }
72 }
73 });
74}
75function makePolicy(policyName, policyDocument) {
76 return __awaiter(this, void 0, void 0, function* () {
77 const ram = yield getRamClient();
78 let exists = true;
79 yield promiseRetry((retry, times) => __awaiter(this, void 0, void 0, function* () {
80 try {
81 try {
82 yield ram.getPolicy({
83 PolicyType: 'Custom',
84 PolicyName: policyName
85 });
86 }
87 catch (ex) {
88 if (ex.code !== 'EntityNotExist.Policy') {
89 throw ex;
90 }
91 else {
92 exists = false;
93 }
94 }
95 if (!exists) {
96 yield ram.createPolicy({
97 PolicyName: policyName,
98 Description: 'generated by fc fun',
99 PolicyDocument: JSON.stringify(policyDocument)
100 });
101 }
102 else {
103 // avoid limitExceeded.Policy.Version
104 yield deletePolicyNotDefaultVersion(ram, policyName);
105 yield ram.createPolicyVersion({
106 PolicyName: policyName,
107 PolicyDocument: JSON.stringify(policyDocument),
108 SetAsDefault: true
109 });
110 }
111 }
112 catch (ex) {
113 if (ex.code && ex.code === 'NoPermission') {
114 throw ex;
115 }
116 console.log(red(`retry ${times} times`));
117 retry(ex);
118 }
119 }));
120 });
121}
122function attachPolicyToRole(policyName, roleName, policyType = 'System') {
123 return __awaiter(this, void 0, void 0, function* () {
124 const ram = yield getRamClient();
125 yield promiseRetry((retry, times) => __awaiter(this, void 0, void 0, function* () {
126 try {
127 const policies = yield ram.listPoliciesForRole({
128 RoleName: roleName
129 });
130 var policy = policies.Policies.Policy.find((item) => {
131 return _.toLower(item.PolicyName) === _.toLower(policyName);
132 });
133 if (!policy) {
134 yield ram.attachPolicyToRole({
135 PolicyType: policyType,
136 PolicyName: policyName,
137 RoleName: roleName
138 });
139 }
140 }
141 catch (ex) {
142 if (ex.code && ex.code === 'NoPermission') {
143 throw ex;
144 }
145 debug('error when attachPolicyToRole: %s, policyName %s, error is: \n%O', roleName, policyName, ex);
146 console.log(red(`retry ${times} times`));
147 retry(ex);
148 }
149 }));
150 });
151}
152function getRamRole(ramClient, roleName) {
153 return __awaiter(this, void 0, void 0, function* () {
154 try {
155 return yield ramClient.getRole({
156 RoleName: roleName
157 });
158 }
159 catch (ex) {
160 debug('error when getRole: %s, error is: \n%O', roleName, ex);
161 if (ex.name !== 'EntityNotExist.RoleError') {
162 throw ex;
163 }
164 }
165 });
166}
167function makeRole(roleName, createRoleIfNotExist, description = 'FunctionCompute Default Role', assumeRolePolicy) {
168 return __awaiter(this, void 0, void 0, function* () {
169 const ram = yield getRamClient();
170 var role;
171 yield promiseRetry((retry, times) => __awaiter(this, void 0, void 0, function* () {
172 try {
173 role = yield getRamRole(ram, roleName);
174 if (!assumeRolePolicy) {
175 assumeRolePolicy = {
176 'Statement': [
177 {
178 'Action': 'sts:AssumeRole',
179 'Effect': 'Allow',
180 'Principal': {
181 'Service': [
182 'fc.aliyuncs.com'
183 ]
184 }
185 }
186 ],
187 'Version': '1'
188 };
189 }
190 if (!role && createRoleIfNotExist) {
191 role = yield ram.createRole({
192 RoleName: roleName,
193 Description: description,
194 AssumeRolePolicyDocument: JSON.stringify(assumeRolePolicy)
195 });
196 }
197 else if (!role) {
198 throw new Error(`role ${roleName} not exist`);
199 }
200 }
201 catch (ex) {
202 debug('error when makeRole: %s, error is: \n%O', roleName, ex);
203 if (ex.code && ex.code.startsWith('InvalidParameter')) {
204 throw ex;
205 }
206 else if (ex.code && ex.code === 'NoPermission') {
207 throw ex;
208 }
209 else {
210 console.log(red(`retry ${times} times`));
211 retry(ex);
212 }
213 }
214 }));
215 return role;
216 });
217}
218function makeAndAttachPolicy(policyName, policyDocument, roleName) {
219 return __awaiter(this, void 0, void 0, function* () {
220 debug('begin makePolicy');
221 yield makePolicy(policyName, policyDocument);
222 debug('begin attachPolicyToRole');
223 yield attachPolicyToRole(policyName, roleName, 'Custom');
224 });
225}
226module.exports = {
227 makeRole, makePolicy,
228 attachPolicyToRole, makeAndAttachPolicy,
229 normalizeRoleOrPoliceName,
230 FNF_ASSUME_ROLE_POLICY
231};