/
googleProvider.js
139 lines (114 loc) · 4.07 KB
/
googleProvider.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
'use strict';
const path = require('path');
const os = require('os');
const _ = require('lodash');
const google = require('googleapis').google;
const pluginPackageJson = require('../package.json'); // eslint-disable-line import/newline-after-import
const googleApisPackageJson = require(require.resolve('googleapis/package.json')); // eslint-disable-line import/no-dynamic-require
const constants = {
providerName: 'google',
};
class GoogleProvider {
static getProviderName() {
return constants.providerName;
}
constructor(serverless) {
this.serverless = serverless;
this.provider = this; // only load plugin in a Google service context
this.serverless.setProvider(constants.providerName, this);
const serverlessVersion = this.serverless.version;
const pluginVersion = pluginPackageJson.version;
const googleApisVersion = googleApisPackageJson.version;
google.options({
headers: {
'User-Agent': `Serverless/${serverlessVersion} Serverless-Google-Provider/${pluginVersion} Googleapis/${googleApisVersion}`,
},
});
this.sdk = {
google,
deploymentmanager: google.deploymentmanager('v2'),
storage: google.storage('v1'),
logging: google.logging('v2'),
cloudfunctions: google.cloudfunctions('v1'),
};
this.variableResolvers = {
gs: this.getGsValue,
};
}
getGsValue(variableString) {
const groups = variableString.split(':')[1].split('/');
const bucket = groups.shift();
const object = groups.join('/');
return this.serverless
.getProvider('google')
.request('storage', 'objects', 'get', {
bucket,
object,
alt: 'media',
})
.catch((err) => {
throw new Error(`Error getting value for ${variableString}. ${err.message}`);
});
}
request() {
// grab necessary stuff from arguments array
const lastArg = arguments[Object.keys(arguments).pop()]; //eslint-disable-line
const hasParams = typeof lastArg === 'object';
const filArgs = _.filter(arguments, (v) => typeof v === 'string'); //eslint-disable-line
const params = hasParams ? lastArg : {};
const service = filArgs[0];
const serviceInstance = this.sdk[service];
this.isServiceSupported(service);
const authClient = this.getAuthClient();
return authClient.getClient().then(() => {
const requestParams = { auth: authClient };
// merge the params from the request call into the base functionParams
_.merge(requestParams, params);
return filArgs
.reduce((p, c) => p[c], this.sdk)
.bind(serviceInstance)(requestParams)
.then((result) => result.data)
.catch((error) => {
if (
error &&
error.errors &&
error.errors[0].message &&
_.includes(error.errors[0].message, 'project 1043443644444')
) {
throw new Error(
"Incorrect configuration. Please change the 'project' key in the 'provider' block in your Serverless config file."
);
} else if (error) {
throw error;
}
});
});
}
getAuthClient() {
let credentials = this.serverless.service.provider.credentials;
if (credentials) {
const credParts = this.serverless.service.provider.credentials.split(path.sep);
if (credParts[0] === '~') {
credParts[0] = os.homedir();
credentials = credParts.reduce((memo, part) => path.join(memo, part), '');
}
return new google.auth.GoogleAuth({
keyFile: credentials.toString(),
scopes: 'https://www.googleapis.com/auth/cloud-platform',
});
}
return new google.auth.GoogleAuth({
scopes: 'https://www.googleapis.com/auth/cloud-platform',
});
}
isServiceSupported(service) {
if (!_.includes(Object.keys(this.sdk), service)) {
const errorMessage = [
`Unsupported service API "${service}".`,
` Supported service APIs are: ${Object.keys(this.sdk).join(', ')}`,
].join('');
throw new Error(errorMessage);
}
}
}
module.exports = GoogleProvider;