Skip to content

Commit 41b82a7

Browse files
committed
feat(client): enable startFirst as extra option in service upgrade
fix #52
1 parent 7952e10 commit 41b82a7

File tree

4 files changed

+314
-13
lines changed

4 files changed

+314
-13
lines changed

index.js

Lines changed: 110 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
'use strict'
22

3-
/* eslint-disable require-jsdoc */
4-
53
const axios = require('axios')
64
const merge = require('lodash.merge')
75
const pWhilst = require('p-whilst')
86

97
/**
108
* @typedef {import('./types').Validate} Validate
119
* @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
1215
* @typedef {import('axios').AxiosInstance} AxiosInstance
1316
*/
1417

@@ -36,36 +39,77 @@ const validate = async client => {
3639
}
3740
}
3841

42+
/**
43+
* @param {AxiosInstance} client -
44+
* @returns {Promise<Array<Stack>>} -
45+
* @example
46+
* const stacks = getStacks(client)
47+
*/
3948
const getStacks = async client => {
4049
return (await client.get('environments/')).data.data
4150
}
4251

52+
/**
53+
* @param {AxiosInstance} client -
54+
* @returns {Promise<Array<Service>>} -
55+
* @example
56+
* const services = getServices(client)
57+
*/
4358
const getServices = async client => {
4459
return (await client.get('services/')).data.data
4560
}
4661

62+
/**
63+
* @param {Array<Stack>} stacks -
64+
* @param {string} name -
65+
* @returns {Stack} -
66+
* @example
67+
* const stack = fetchStackByName(stacks, 'MyStack')
68+
*/
4769
const fetchStackByName = (stacks, name) => {
4870
return stacks.filter(stack => stack.name === name).pop()
4971
}
5072

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+
*/
5181
const fetchServiceByName = (services, name, stackId = null) => {
5282
return services
5383
.filter(s => s.name === name)
5484
.filter(s => !stackId || s.environmentId === stackId)
5585
.pop()
5686
}
5787

88+
/**
89+
* @param {AxiosInstance} client -
90+
* @param {string} name -
91+
* @returns {Promise<Stack>} -
92+
* @example
93+
* const stack = findStackByName(client, 'MyStack')
94+
*/
5895
const findStackByName = async (client, name) => {
5996
const stacks = await getStacks(client)
6097
const stack = await fetchStackByName(stacks, name)
6198

6299
if (!stack) {
63-
throw new Error(`Unable to locate stack '${stack}'`)
100+
throw new Error(`Unable to locate stack '${name}'`)
64101
}
65102

66103
return stack
67104
}
68105

106+
/**
107+
* @param {AxiosInstance} client -
108+
* @param {string} name -
109+
* @returns {Promise<Service>} -
110+
* @example
111+
* const service = findServiceByName(client, 'MyStack/MyService')
112+
*/
69113
const findServiceByName = async (client, name) => {
70114
const [service, stack] = name
71115
.toLowerCase()
@@ -83,7 +127,15 @@ const findServiceByName = async (client, name) => {
83127
return locatedService
84128
}
85129

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) => {
87139
const {
88140
launchConfig,
89141
launchConfig: { imageUuid }
@@ -97,26 +149,50 @@ const buildUpgradeInstructions = (service, newVersion) => {
97149
{
98150
inServiceStrategy: {
99151
launchConfig: { imageUuid: image },
100-
startFirst: true
152+
startFirst
101153
}
102154
}
103155
)
104156
}
105157

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+
*/
106166
const withAdditionalEnvVar = (instruction, variable, value) => {
107167
const launchConfig = { environment: { [variable]: value } }
108168

109169
return merge(instruction, { inServiceStrategy: { launchConfig } })
110170
}
111171

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+
*/
112180
const upgradeService = async (client, id, upgrade) => {
113181
return (await client.post(`services/${id}/?action=upgrade`, upgrade)).data
114182
}
115183

184+
/**
185+
* @param {AxiosInstance} client -
186+
* @param {string} id -
187+
* @returns {Promise<*>} -
188+
* @example
189+
* response = checkUpgradeService(client, 'stackId')
190+
*/
116191
const checkUpgradeService = (client, id) => {
117192
let attempts = 0
118193
let service = {}
119194
const upgradeTimeout = 5 * 60
195+
// eslint-disable-next-line require-jsdoc
120196
const sleep = timeout =>
121197
new Promise(resolve => setTimeout(() => resolve(), timeout))
122198
return pWhilst(
@@ -143,12 +219,27 @@ const checkUpgradeService = (client, id) => {
143219
)
144220
}
145221

222+
/**
223+
* @param {AxiosInstance} client -
224+
* @param {string} id -
225+
* @returns {Promise<*>} -
226+
* @example
227+
* response = finishUpgradeService(client, 'stackId')
228+
*/
146229
const finishUpgradeService = async (client, id) => {
147230
return (await client.post(`services/${id}/?action=finishupgrade`)).data
148231
}
149232

233+
/**
234+
* @class
235+
*/
150236
class Rancher {
237+
// eslint-disable-next-line jsdoc/require-example
238+
/**
239+
* @param {Options} options -
240+
*/
151241
constructor (options) {
242+
/** @type {Options} */
152243
this.config = Object.assign(
153244
{
154245
dryRun: false,
@@ -161,6 +252,7 @@ class Rancher {
161252
options
162253
)
163254

255+
/** @type {AxiosInstance} */
164256
// @ts-ignore
165257
this.client = axios.create({
166258
auth: {
@@ -182,17 +274,26 @@ class Rancher {
182274
return { isValid, errorCode }
183275
}
184276

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) {
186287
const { commitVariable, dryRun, releaseVariable } = this.config
187288
const service = await findServiceByName(this.client, name)
188-
let upgrade = await buildUpgradeInstructions(service, version)
289+
let upgrade = buildUpgradeInstructions(service, version, startFirst)
189290

190291
if (commitVariable && commit) {
191-
upgrade = await withAdditionalEnvVar(upgrade, commitVariable, commit)
292+
upgrade = withAdditionalEnvVar(upgrade, commitVariable, commit)
192293
}
193294

194295
if (releaseVariable) {
195-
upgrade = await withAdditionalEnvVar(upgrade, releaseVariable, version)
296+
upgrade = withAdditionalEnvVar(upgrade, releaseVariable, version)
196297
}
197298

198299
let response = !dryRun
@@ -209,6 +310,4 @@ class Rancher {
209310
}
210311
}
211312

212-
/* eslint-enable require-jsdoc */
213-
214313
module.exports = Rancher

package-lock.json

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"@semantic-release/changelog": "5.0.1",
3434
"@semantic-release/git": "9.0.0",
3535
"@types/axios": "0.14.0",
36+
"@types/lodash.merge": "4.6.6",
3637
"eslint": "6.8.0",
3738
"eslint-plugin-array-func": "3.1.5",
3839
"eslint-plugin-eslint-comments": "3.1.2",

0 commit comments

Comments
 (0)