forked from danielcondemarin/aws-dynamodb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserverless.js
132 lines (100 loc) · 3.53 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
const { mergeDeepRight, pick, equals } = require('ramda')
const AWS = require('aws-sdk')
const { Component } = require('@serverless/core')
const { createTable, deleteTable, describeTable, updateTable, configChanged } = require('./utils')
const outputsList = ['name', 'arn', 'region']
const defaults = {
attributeDefinitions: [
{
AttributeName: 'id',
AttributeType: 'S'
}
],
keySchema: [
{
AttributeName: 'id',
KeyType: 'HASH'
}
],
name: false,
region: 'us-east-1'
}
const setTableName = (component, inputs, config) => {
const generatedName = inputs.name
? `${inputs.name}-${component.context.resourceId()}`
: component.context.resourceId()
const hasDeployedBefore = 'nameInput' in component.state
const givenNameHasNotChanged =
component.state.nameInput && component.state.nameInput === inputs.name
const bothLastAndCurrentDeployHaveNoNameDefined = !component.state.nameInput && !inputs.name
config.name =
hasDeployedBefore && (givenNameHasNotChanged || bothLastAndCurrentDeployHaveNoNameDefined)
? component.state.name
: generatedName
component.state.nameInput = inputs.name || false
}
class AwsDynamoDb extends Component {
async default(inputs = {}) {
this.context.status('Deploying')
const config = mergeDeepRight(defaults, inputs)
this.context.debug(
`Starting deployment of table ${config.name} in the ${config.region} region.`
)
const dynamodb = new AWS.DynamoDB({
region: config.region,
credentials: this.context.credentials.aws
})
this.context.debug(
`Checking if table ${config.name} already exists in the ${config.region} region.`
)
setTableName(this, inputs, config)
const prevTable = await describeTable({ dynamodb, name: this.state.name })
if (!prevTable) {
this.context.status('Creating')
this.context.debug(`Table ${config.name} does not exist. Creating...`)
config.arn = await createTable({ dynamodb, ...config })
} else {
this.context.debug(`Table ${config.name} already exists. Comparing config changes...`)
config.arn = prevTable.arn
if (configChanged(prevTable, config)) {
this.context.status('Updating')
this.context.debug(`Config changed for table ${config.name}. Updating...`)
if (!equals(prevTable.name, config.name)) {
await deleteTable({ dynamodb, name: prevTable.name })
config.arn = await createTable({ dynamodb, ...config })
} else {
await updateTable({ dynamodb, ...config })
}
}
}
this.context.debug(
`Table ${config.name} was successfully deployed to the ${config.region} region.`
)
this.state.arn = config.arn
this.state.name = config.name
this.state.region = config.region
await this.save()
const outputs = pick(outputsList, config)
return outputs
}
async remove() {
this.context.status('Removing')
const { name, region } = this.state
if (!name) {
this.context.debug(`Aborting removal. Table name not found in state.`)
return
}
const dynamodb = new AWS.DynamoDB({
region,
credentials: this.context.credentials.aws
})
this.context.debug(`Removing table ${name} from the ${region} region.`)
await deleteTable({ dynamodb, name })
const outputs = pick(outputsList, this.state)
this.context.debug(`Table ${name} was successfully removed from the ${region} region.`)
this.state = {}
await this.save()
return outputs
}
}
module.exports = AwsDynamoDb