Skip to content

Commit 12b3eb1

Browse files
committed
Fix accesscontrol
1 parent bc4aa42 commit 12b3eb1

File tree

1 file changed

+108
-66
lines changed

1 file changed

+108
-66
lines changed

package/lib/compileFunctions.js

Lines changed: 108 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,98 @@
1-
'use strict';
1+
"use strict";
22

33
/* eslint no-use-before-define: 0 */
44

5-
const path = require('path');
5+
const path = require("path");
66

7-
const _ = require('lodash');
8-
const BbPromise = require('bluebird');
7+
const _ = require("lodash");
8+
const BbPromise = require("bluebird");
99

1010
module.exports = {
1111
compileFunctions() {
1212
const artifactFilePath = this.serverless.service.package.artifact;
1313
const fileName = artifactFilePath.split(path.sep).pop();
1414

15-
this.serverless.service.package
16-
.artifactFilePath = `${this.serverless.service.package.artifactDirectoryName}/${fileName}`;
15+
this.serverless.service.package.artifactFilePath = `${this.serverless.service.package.artifactDirectoryName}/${fileName}`;
1716

1817
this.serverless.service.getAllFunctions().forEach((functionName) => {
1918
const funcObject = this.serverless.service.getFunction(functionName);
2019

21-
this.serverless.cli
22-
.log(`Compiling function "${functionName}"...`);
20+
this.serverless.cli.log(`Compiling function "${functionName}"...`);
2321

24-
funcObject.prependStage = _.get(funcObject, 'prependStage', this.options.prependStage);
25-
funcObject.prependService = _.get(funcObject, 'prependService', this.options.prependService);
26-
funcObject.prefix = _.get(funcObject, 'prefix', this.options.prefix);
22+
funcObject.prependStage = _.get(
23+
funcObject,
24+
"prependStage",
25+
this.options.prependStage
26+
);
27+
funcObject.prependService = _.get(
28+
funcObject,
29+
"prependService",
30+
this.options.prependService
31+
);
32+
funcObject.prefix = _.get(funcObject, "prefix", this.options.prefix);
2733

2834
validateHandlerProperty(funcObject, functionName);
2935
validateEventsProperty(funcObject, functionName);
3036
const funcTemplate = getFunctionTemplate(
3137
funcObject,
32-
_.get(this, 'serverless.service.provider.region', this.options.region),
38+
_.get(this, "serverless.service.provider.region", this.options.region),
3339
this.options.stage,
3440
this.serverless.service.service,
3541
this.serverless.service.provider.project,
36-
`gs://${
37-
this.serverless.service.provider.deploymentBucketName
38-
}/${this.serverless.service.package.artifactFilePath}`,
42+
`gs://${this.serverless.service.provider.deploymentBucketName}/${this.serverless.service.package.artifactFilePath}`
3943
);
4044

45+
const accessControlTemplate = getAccessControlTemplate();
46+
4147
const eventType = Object.keys(funcObject.events[0])[0];
4248

43-
funcTemplate.properties.availableMemoryMb = _.get(funcObject, 'memorySize')
44-
|| _.get(this, 'serverless.service.provider.memorySize')
45-
|| 256;
46-
funcTemplate.properties.runtime = _.get(funcObject, 'runtime')
47-
|| _.get(this, 'serverless.service.provider.runtime')
48-
|| 'nodejs8';
49-
funcTemplate.properties.timeout = _.get(funcObject, 'timeout')
50-
|| _.get(this, 'serverless.service.provider.timeout')
51-
|| '60s';
52-
funcTemplate.properties.serviceAccountEmail = _.get(funcObject, 'serviceAccount')
53-
|| _.get(this, 'serverless.service.provider.serviceAccount')
54-
|| '';
55-
funcTemplate.properties.vpcConnector = _.get(funcObject, 'vpcConnector')
56-
|| '';
57-
58-
if (funcTemplate.properties.vpcConnector && funcTemplate.properties.vpcConnector.length > 0) {
59-
funcTemplate.properties.vpcConnectorEgressSettings = _.get(funcObject, 'vpcConnectorEgressSettings')
60-
|| "ALL_TRAFFIC";
49+
funcTemplate.properties.availableMemoryMb =
50+
_.get(funcObject, "memorySize") ||
51+
_.get(this, "serverless.service.provider.memorySize") ||
52+
256;
53+
funcTemplate.properties.runtime =
54+
_.get(funcObject, "runtime") ||
55+
_.get(this, "serverless.service.provider.runtime") ||
56+
"nodejs8";
57+
funcTemplate.properties.timeout =
58+
_.get(funcObject, "timeout") ||
59+
_.get(this, "serverless.service.provider.timeout") ||
60+
"60s";
61+
funcTemplate.properties.serviceAccountEmail =
62+
_.get(funcObject, "serviceAccount") ||
63+
_.get(this, "serverless.service.provider.serviceAccount") ||
64+
"";
65+
funcTemplate.properties.vpcConnector =
66+
_.get(funcObject, "vpcConnector") || "";
67+
68+
if (
69+
funcTemplate.properties.vpcConnector &&
70+
funcTemplate.properties.vpcConnector.length > 0
71+
) {
72+
funcTemplate.properties.vpcConnectorEgressSettings =
73+
_.get(funcObject, "vpcConnectorEgressSettings") || "ALL_TRAFFIC";
6174
}
6275

63-
if (eventType == 'http') {
64-
funcTemplate.properties.unauthenticatedAccess = _.get(funcObject, 'unauthenticatedAccess')
65-
|| false;
66-
}
76+
if (
77+
eventType == "http" &&
78+
funcTemplate.properties.unauthenticatedAccess == true
79+
) {
80+
accessControlTemplate.gcpIamPolicy.bindings.push({
81+
role: "roles/cloudfunctions.invoker",
82+
members: ["allUsers"],
83+
});
84+
}
6785

68-
funcTemplate.properties.labels = _.assign({},
69-
_.get(this, 'serverless.service.provider.labels') || {},
70-
_.get(funcObject, 'labels') || {},
86+
funcTemplate.properties.labels = _.assign(
87+
{},
88+
_.get(this, "serverless.service.provider.labels") || {},
89+
_.get(funcObject, "labels") || {}
7190
);
7291
funcTemplate.properties.environmentVariables = _.merge(
73-
_.get(this, 'serverless.service.provider.environment'),
74-
funcObject.environment,
92+
_.get(this, "serverless.service.provider.environment"),
93+
funcObject.environment
7594
);
76-
95+
7796
if (!funcTemplate.properties.serviceAccountEmail) {
7897
delete funcTemplate.properties.serviceAccountEmail;
7998
}
@@ -86,21 +105,17 @@ module.exports = {
86105
delete funcTemplate.properties.vpcConnectorEgressSettings;
87106
}
88107

89-
if (!funcTemplate.properties.unauthenticatedAccess) {
90-
delete funcTemplate.properties.unauthenticatedAccess;
91-
}
92-
93108
if (!_.size(funcTemplate.properties.environmentVariables)) {
94109
delete funcTemplate.properties.environmentVariables;
95110
}
96111

97-
if (eventType === 'http') {
112+
if (eventType === "http") {
98113
const url = funcObject.events[0].http;
99114

100115
funcTemplate.properties.httpsTrigger = {};
101116
funcTemplate.properties.httpsTrigger.url = url;
102117
}
103-
if (eventType === 'event') {
118+
if (eventType === "event") {
104119
const type = funcObject.events[0].event.eventType;
105120
const path = funcObject.events[0].event.path; //eslint-disable-line
106121
const resource = funcObject.events[0].event.resource;
@@ -109,11 +124,20 @@ module.exports = {
109124
funcTemplate.properties.eventTrigger = {};
110125
funcTemplate.properties.eventTrigger.eventType = type;
111126
if (path) funcTemplate.properties.eventTrigger.path = path;
112-
if (retry) funcTemplate.properties.eventTrigger.failurePolicy = { retry: {} };
127+
if (retry)
128+
funcTemplate.properties.eventTrigger.failurePolicy = { retry: {} };
113129
funcTemplate.properties.eventTrigger.resource = resource;
114130
}
115131

116-
this.serverless.service.provider.compiledConfigurationTemplate.resources.push(funcTemplate);
132+
if (
133+
accessControlTemplate.accessControl.gcpIamPolicy.bindings.length > 0
134+
) {
135+
funcTemplate = _.assign({}, funcTemplate, accessControlTemplate);
136+
}
137+
138+
this.serverless.service.provider.compiledConfigurationTemplate.resources.push(
139+
funcTemplate
140+
);
117141
});
118142

119143
return BbPromise.resolve();
@@ -125,8 +149,8 @@ const validateHandlerProperty = (funcObject, functionName) => {
125149
const errorMessage = [
126150
`Missing "handler" property for function "${functionName}".`,
127151
' Your function needs a "handler".',
128-
' Please check the docs for more info.',
129-
].join('');
152+
" Please check the docs for more info.",
153+
].join("");
130154
throw new Error(errorMessage);
131155
}
132156
};
@@ -136,32 +160,40 @@ const validateEventsProperty = (funcObject, functionName) => {
136160
const errorMessage = [
137161
`Missing "events" property for function "${functionName}".`,
138162
' Your function needs at least one "event".',
139-
' Please check the docs for more info.',
140-
].join('');
163+
" Please check the docs for more info.",
164+
].join("");
141165
throw new Error(errorMessage);
142166
}
143167

144168
if (funcObject.events.length > 1) {
145169
const errorMessage = [
146170
`The function "${functionName}" has more than one event.`,
147-
' Only one event per function is supported.',
148-
' Please check the docs for more info.',
149-
].join('');
171+
" Only one event per function is supported.",
172+
" Please check the docs for more info.",
173+
].join("");
150174
throw new Error(errorMessage);
151175
}
152176

153-
const supportedEvents = ['http', 'event'];
177+
const supportedEvents = ["http", "event"];
154178
const eventType = Object.keys(funcObject.events[0])[0];
155179
if (supportedEvents.indexOf(eventType) === -1) {
156180
const errorMessage = [
157181
`Event type "${eventType}" of function "${functionName}" not supported.`,
158-
` supported event types are: ${supportedEvents.join(', ')}`,
159-
].join('');
182+
` supported event types are: ${supportedEvents.join(", ")}`,
183+
].join("");
160184
throw new Error(errorMessage);
161185
}
162186
};
163187

164-
const getFunctionTemplate = (funcObject, region, stage, service, project, sourceArchiveUrl) => { //eslint-disable-line
188+
const getFunctionTemplate = (
189+
funcObject,
190+
region,
191+
stage,
192+
service,
193+
project,
194+
sourceArchiveUrl
195+
) => {
196+
//eslint-disable-line
165197
let funcName = funcObject.handler;
166198

167199
if (funcObject.prependStage) {
@@ -172,21 +204,31 @@ const getFunctionTemplate = (funcObject, region, stage, service, project, source
172204
funcName = `${service}-${funcName}`;
173205
}
174206

175-
if (funcObject.prefix && funcObject.prefix !=='') {
207+
if (funcObject.prefix && funcObject.prefix !== "") {
176208
funcName = `${funcObject.prefix}-${funcName}`;
177209
}
178210

179211
return {
180-
type: 'gcp-types/cloudfunctions-v1:projects.locations.functions',
212+
type: "gcp-types/cloudfunctions-v1:projects.locations.functions",
181213
name: funcObject.name,
182214
properties: {
183215
parent: `projects/${project}/locations/${region}`,
184216
availableMemoryMb: 256,
185-
runtime: 'nodejs8',
186-
timeout: '60s',
217+
runtime: "nodejs8",
218+
timeout: "60s",
187219
entryPoint: funcObject.handler,
188220
function: funcName,
189221
sourceArchiveUrl,
190222
},
191223
};
192224
};
225+
226+
const getAccessControlTemplate = () => {
227+
return {
228+
accessControl: {
229+
gcpIamPolicy: {
230+
bindings: [],
231+
},
232+
},
233+
};
234+
};

0 commit comments

Comments
 (0)