1
1
'use strict'
2
2
3
- /* eslint-disable require-jsdoc */
4
-
5
3
const axios = require ( 'axios' )
6
4
const merge = require ( 'lodash.merge' )
7
5
const pWhilst = require ( 'p-whilst' )
8
6
9
7
/**
10
8
* @typedef {import('./types').Validate } Validate
11
9
* @typedef {import('./types').ErrorCode } ErrorCode
10
+ * @typedef {import('./types').Service } Service
11
+ * @typedef {import('./types').Stack } Stack
12
+ * @typedef {import('./types').ServiceUpgrade } ServiceUpgrade
13
+ * @typedef {import('./types').Upgrade } Upgrade
14
+ * @typedef {import('./types').Options } Options
12
15
* @typedef {import('axios').AxiosInstance } AxiosInstance
13
16
*/
14
17
@@ -36,36 +39,77 @@ const validate = async client => {
36
39
}
37
40
}
38
41
42
+ /**
43
+ * @param {AxiosInstance } client -
44
+ * @returns {Promise<Array<Stack>> } -
45
+ * @example
46
+ * const stacks = getStacks(client)
47
+ */
39
48
const getStacks = async client => {
40
49
return ( await client . get ( 'environments/' ) ) . data . data
41
50
}
42
51
52
+ /**
53
+ * @param {AxiosInstance } client -
54
+ * @returns {Promise<Array<Service>> } -
55
+ * @example
56
+ * const services = getServices(client)
57
+ */
43
58
const getServices = async client => {
44
59
return ( await client . get ( 'services/' ) ) . data . data
45
60
}
46
61
62
+ /**
63
+ * @param {Array<Stack> } stacks -
64
+ * @param {string } name -
65
+ * @returns {Stack } -
66
+ * @example
67
+ * const stack = fetchStackByName(stacks, 'MyStack')
68
+ */
47
69
const fetchStackByName = ( stacks , name ) => {
48
70
return stacks . filter ( stack => stack . name === name ) . pop ( )
49
71
}
50
72
73
+ /**
74
+ * @param {Array<Service> } services -
75
+ * @param {string } name -
76
+ * @param {string } [stackId=null] -
77
+ * @returns {Service } -
78
+ * @example
79
+ * const service = fetchServiceByName(services, 'MyService')
80
+ */
51
81
const fetchServiceByName = ( services , name , stackId = null ) => {
52
82
return services
53
83
. filter ( s => s . name === name )
54
84
. filter ( s => ! stackId || s . environmentId === stackId )
55
85
. pop ( )
56
86
}
57
87
88
+ /**
89
+ * @param {AxiosInstance } client -
90
+ * @param {string } name -
91
+ * @returns {Promise<Stack> } -
92
+ * @example
93
+ * const stack = findStackByName(client, 'MyStack')
94
+ */
58
95
const findStackByName = async ( client , name ) => {
59
96
const stacks = await getStacks ( client )
60
97
const stack = await fetchStackByName ( stacks , name )
61
98
62
99
if ( ! stack ) {
63
- throw new Error ( `Unable to locate stack '${ stack } '` )
100
+ throw new Error ( `Unable to locate stack '${ name } '` )
64
101
}
65
102
66
103
return stack
67
104
}
68
105
106
+ /**
107
+ * @param {AxiosInstance } client -
108
+ * @param {string } name -
109
+ * @returns {Promise<Service> } -
110
+ * @example
111
+ * const service = findServiceByName(client, 'MyStack/MyService')
112
+ */
69
113
const findServiceByName = async ( client , name ) => {
70
114
const [ service , stack ] = name
71
115
. toLowerCase ( )
@@ -83,7 +127,15 @@ const findServiceByName = async (client, name) => {
83
127
return locatedService
84
128
}
85
129
86
- const buildUpgradeInstructions = ( service , newVersion ) => {
130
+ /**
131
+ * @param {Service } service -
132
+ * @param {string } newVersion -
133
+ * @param {boolean } [startFirst=true] -
134
+ * @returns {ServiceUpgrade } -
135
+ * @example
136
+ * const upgrade = await buildUpgradeInstructions(service, '1.0.0')
137
+ */
138
+ const buildUpgradeInstructions = ( service , newVersion , startFirst = true ) => {
87
139
const {
88
140
launchConfig,
89
141
launchConfig : { imageUuid }
@@ -97,26 +149,50 @@ const buildUpgradeInstructions = (service, newVersion) => {
97
149
{
98
150
inServiceStrategy : {
99
151
launchConfig : { imageUuid : image } ,
100
- startFirst : true
152
+ startFirst
101
153
}
102
154
}
103
155
)
104
156
}
105
157
158
+ /**
159
+ * @param {ServiceUpgrade } instruction -
160
+ * @param {string } variable -
161
+ * @param {string } value -
162
+ * @returns {ServiceUpgrade } -
163
+ * @example
164
+ * upgrade = withAdditionalEnvVar(upgrade, 'MY_VAR', 'myValue')
165
+ */
106
166
const withAdditionalEnvVar = ( instruction , variable , value ) => {
107
167
const launchConfig = { environment : { [ variable ] : value } }
108
168
109
169
return merge ( instruction , { inServiceStrategy : { launchConfig } } )
110
170
}
111
171
172
+ /**
173
+ * @param {AxiosInstance } client -
174
+ * @param {string } id -
175
+ * @param {ServiceUpgrade } upgrade -
176
+ * @returns {Promise<*> } -
177
+ * @example
178
+ * const response = upgradeService(client, 'stackId', upgrade)
179
+ */
112
180
const upgradeService = async ( client , id , upgrade ) => {
113
181
return ( await client . post ( `services/${ id } /?action=upgrade` , upgrade ) ) . data
114
182
}
115
183
184
+ /**
185
+ * @param {AxiosInstance } client -
186
+ * @param {string } id -
187
+ * @returns {Promise<*> } -
188
+ * @example
189
+ * response = checkUpgradeService(client, 'stackId')
190
+ */
116
191
const checkUpgradeService = ( client , id ) => {
117
192
let attempts = 0
118
193
let service = { }
119
194
const upgradeTimeout = 5 * 60
195
+ // eslint-disable-next-line require-jsdoc
120
196
const sleep = timeout =>
121
197
new Promise ( resolve => setTimeout ( ( ) => resolve ( ) , timeout ) )
122
198
return pWhilst (
@@ -143,12 +219,27 @@ const checkUpgradeService = (client, id) => {
143
219
)
144
220
}
145
221
222
+ /**
223
+ * @param {AxiosInstance } client -
224
+ * @param {string } id -
225
+ * @returns {Promise<*> } -
226
+ * @example
227
+ * response = finishUpgradeService(client, 'stackId')
228
+ */
146
229
const finishUpgradeService = async ( client , id ) => {
147
230
return ( await client . post ( `services/${ id } /?action=finishupgrade` ) ) . data
148
231
}
149
232
233
+ /**
234
+ * @class
235
+ */
150
236
class Rancher {
237
+ // eslint-disable-next-line jsdoc/require-example
238
+ /**
239
+ * @param {Options } options -
240
+ */
151
241
constructor ( options ) {
242
+ /** @type {Options } */
152
243
this . config = Object . assign (
153
244
{
154
245
dryRun : false ,
@@ -161,6 +252,7 @@ class Rancher {
161
252
options
162
253
)
163
254
255
+ /** @type {AxiosInstance } */
164
256
// @ts -ignore
165
257
this . client = axios . create ( {
166
258
auth : {
@@ -182,17 +274,26 @@ class Rancher {
182
274
return { isValid, errorCode }
183
275
}
184
276
185
- async upgrade ( name , version , commit ) {
277
+ /**
278
+ * @param {string } name -
279
+ * @param {string } version -
280
+ * @param {string } [commit] -
281
+ * @param {boolean } [startFirst=true] -
282
+ * @returns {Promise<Upgrade> } -
283
+ * @example
284
+ * const { isValid, errorCode } = client.upgrade('MyStack/MyService', '1.0.0')
285
+ */
286
+ async upgrade ( name , version , commit , startFirst = true ) {
186
287
const { commitVariable, dryRun, releaseVariable } = this . config
187
288
const service = await findServiceByName ( this . client , name )
188
- let upgrade = await buildUpgradeInstructions ( service , version )
289
+ let upgrade = buildUpgradeInstructions ( service , version , startFirst )
189
290
190
291
if ( commitVariable && commit ) {
191
- upgrade = await withAdditionalEnvVar ( upgrade , commitVariable , commit )
292
+ upgrade = withAdditionalEnvVar ( upgrade , commitVariable , commit )
192
293
}
193
294
194
295
if ( releaseVariable ) {
195
- upgrade = await withAdditionalEnvVar ( upgrade , releaseVariable , version )
296
+ upgrade = withAdditionalEnvVar ( upgrade , releaseVariable , version )
196
297
}
197
298
198
299
let response = ! dryRun
@@ -209,6 +310,4 @@ class Rancher {
209
310
}
210
311
}
211
312
212
- /* eslint-enable require-jsdoc */
213
-
214
313
module . exports = Rancher
0 commit comments