-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathserverless.js
134 lines (110 loc) · 3.62 KB
/
serverless.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
'use strict';
// eslint-disable-next-line import/no-unresolved
const { Component } = require('@serverless/core');
const {
generateId,
getClients,
packageExpress,
createOrUpdateFunctionRole,
createOrUpdateMetaRole,
createOrUpdateLambda,
createOrUpdateAlias,
createOrUpdateApi,
createOrUpdateDomain,
removeApi,
removeAllRoles,
removeLambda,
removeDomain,
getMetrics,
retryIfRateExceeded,
} = require('./utils');
class Express extends Component {
/**
* Deploy
* @param {object} inputs
*/
async deploy(inputs) {
const outputs = {};
console.log('Deploying Express App...');
inputs.domain = inputs.domain
? inputs.domain.replace('https://', '').replace('http://', '')
: null;
// for backward compatability
this.state.domain = this.state.domain
? this.state.domain.replace('https://', '').replace('http://', '')
: null;
// Throw error on domain change
if (inputs.domain && this.state.domain && this.state.domain !== inputs.domain) {
throw new Error(
`Changing the domain from ${this.state.domain} to ${inputs.domain} will remove your infrastructure. Please remove it manually, change the domain, then re-deploy.`
);
}
// Validate
if (inputs.timeout && inputs.timeout > 30) {
throw new Error('"timeout" can not be greater than 30 seconds.');
}
// Set app name & region or use previously set name
this.state.name = this.state.name || `${this.name}-${generateId()}`;
this.state.region = inputs.region || 'us-east-1';
const clients = getClients(this.credentials.aws, inputs.region);
await packageExpress(this, inputs, outputs);
await Promise.all([
retryIfRateExceeded(() => createOrUpdateFunctionRole(this, inputs, clients)),
retryIfRateExceeded(() => createOrUpdateMetaRole(this, inputs, clients, this.accountId)),
]);
await retryIfRateExceeded(() => createOrUpdateLambda(this, inputs, clients));
await retryIfRateExceeded(() => createOrUpdateAlias(this, inputs, clients));
await retryIfRateExceeded(() => createOrUpdateApi(this, inputs, clients));
if (inputs.domain) {
await retryIfRateExceeded(() => createOrUpdateDomain(this, inputs, clients));
} else if (this.state.domain) {
delete this.state.domain;
}
// Set outputs
outputs.apiGatewayUrl = this.state.apiGatewayUrl;
if (inputs.domain) {
// Ensure http info isn't replicated
if (!inputs.domain.includes('http://') && !inputs.domain.includes('https://')) {
outputs.url = `https://${inputs.domain}`;
} else {
outputs.url = inputs.domain;
}
// if domain is not in aws account, show the regional url
// as it would be required by the external registrars
if (this.state.apigatewayDomainName && !this.state.domainHostedZoneId) {
outputs.regionalUrl = `https://${this.state.apigatewayDomainName}`;
}
} else {
outputs.url = this.state.apiGatewayUrl;
}
return outputs;
}
/**
* Remove
*/
async remove() {
const clients = getClients(this.credentials.aws, this.state.region);
await removeAllRoles(this, clients);
await removeLambda(this, clients);
await removeDomain(this, clients);
await removeApi(this, clients);
this.state = {};
return {};
}
/**
* Metrics
*/
async metrics(inputs = {}) {
console.log('Fetching metrics...');
const result = await getMetrics(
this.state.region,
this.state.metaRoleArn,
this.state.apiId,
this.state.lambdaName,
inputs.rangeStart,
inputs.rangeEnd
);
return result;
}
}
module.exports = Express;