Skip to content

Commit

Permalink
feat(variables): support service-specific pipeline variables. fixes #686
Browse files Browse the repository at this point in the history
  • Loading branch information
sii41383 committed Mar 22, 2024
1 parent 47fbbf9 commit 2461afb
Show file tree
Hide file tree
Showing 15 changed files with 399 additions and 90 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [14.x, 16.x]
node-version: [16.x]
include:
- os: ubuntu-latest
node-version: 14.x
node-version: 16.x
reportCoverage: true
runs-on: ${{ matrix.os }}

Expand Down
50 changes: 36 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ Cloud Manager Plugin for the [Adobe I/O CLI](https://github.com/adobe/aio-cli)

* [Adobe I/O CLI](https://github.com/adobe/aio-cli)
* Node.js version compatibility:
* 12.x -- 12.0.0 or higher.
* 14.x -- 14.0.0 or higher.
* 16.x -- currently incompatible due to lack of support from aio-cli.
* 16.x -- 16.0.0 or higher.
* Use with odd Node versions is *not* recommended.

> Although not recommended for general use, it is possible to use this plugin outside of the Adobe I/O CLI. See [Standalone Use](#standalone-use) below.
Expand Down Expand Up @@ -1043,19 +1041,43 @@ ARGUMENTS
PIPELINEID the pipeline id
OPTIONS
-d, --delete=delete variables/secrets to delete
-j, --json output in json format
-p, --programId=programId the programId. if not specified, defaults to 'cloudmanager_programid' config value
-s, --secret=secret secret values in KEY VALUE format
-v, --variable=variable variable values in KEY VALUE format
-y, --yaml output in yaml format
--imsContextName=imsContextName the alternate IMS context name to use instead of aio-cli-plugin-cloudmanager
-d, --delete=delete variables/secrets to delete
-j, --json output in json format
-p, --programId=programId the programId. if not specified, defaults to 'cloudmanager_programid' config value
-s, --secret=secret secret values in KEY VALUE format
-v, --variable=variable variable values in KEY VALUE format
-y, --yaml output in yaml format
--imsContextName=imsContextName the alternate IMS context name to use instead of aio-cli-plugin-cloudmanager
--jsonFile=jsonFile if set, read variables from a JSON array provided as a file; variables set through
--variable or --secret flag will take precedence
--jsonFile=jsonFile if set, read variables from a JSON array provided as a file; variables set through
--variable or --secret flag will take precedence
--jsonStdin if set, read variables from a JSON array provided as standard input; variables set
through --variable or --secret flag will take precedence
--jsonStdin if set, read variables from a JSON array provided as standard input; variables set
through --variable or --secret flag will take precedence
--buildDelete=buildDelete variables/secrets to delete for build service
--buildSecret=buildSecret secret values in KEY VALUE format for build service
--buildVariable=buildVariable variable values in KEY VALUE format for build service
--functionalTestDelete=functionalTestDelete variables/secrets to delete for functionalTest service
--functionalTestSecret=functionalTestSecret secret values in KEY VALUE format for functionalTest service
--functionalTestVariable=functionalTestVariable variable values in KEY VALUE format for functionalTest service
--uiTestDelete=uiTestDelete variables/secrets to delete for uiTest service
--uiTestSecret=uiTestSecret secret values in KEY VALUE format for uiTest service
--uiTestVariable=uiTestVariable variable values in KEY VALUE format for uiTest service
--loadTestDelete=loadTestDelete variables/secrets to delete for loadTest service
--loadTestSecret=loadTestSecret secret values in KEY VALUE format for loadTest service
--loadTestVariable=loadTestVariable variable values in KEY VALUE format for loadTest service
--yamlFile=yamlFile if set, read variables from a YAML array provided as a file; variables set through
--variable or --secret flag will take precedence
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@adobe/aio-cli-plugin-cloudmanager",
"description": "Cloud Manager commands for the Adobe I/O CLI",
"version": "4.1.0",
"version": "4.2.0",
"author": "Adobe Inc.",
"bugs": "https://github.com/adobe/aio-cli-plugin-cloudmanager/issues",
"dependencies": {
Expand Down Expand Up @@ -53,7 +53,7 @@
"tmp": "0.2.1"
},
"engines": {
"node": ">=12"
"node": ">=16"
},
"files": [
"/oclif.manifest.json",
Expand Down
80 changes: 57 additions & 23 deletions src/base-variables-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const _ = require('lodash')
const { codes: validationCodes } = require('./ValidationErrors')

class BaseVariablesCommand extends BaseCommand {
getFlagDefs () {
return {
getFlagDefs (services) {
const coreFlagDefs = {
variable: {
type: 'string',
},
Expand All @@ -36,6 +36,21 @@ class BaseVariablesCommand extends BaseCommand {
action: 'delete',
},
}

const result = {
...coreFlagDefs,
}

services.forEach(service => {
Object.keys(coreFlagDefs).forEach(coreFlagKey => {
const flagName = _.camelCase(`${service} ${coreFlagKey}`)
result[flagName] = {
...coreFlagDefs[coreFlagKey],
service,
}
})
})
return result
}

outputTable (result, flags, extraColumns = {}) {
Expand Down Expand Up @@ -167,27 +182,30 @@ BaseVariablesCommand.coreSetterFlags = {
}),
}

BaseVariablesCommand.setterFlags = {
...BaseVariablesCommand.coreSetterFlags,
jsonStdin: flags.boolean({
default: false,
description: 'if set, read variables from a JSON array provided as standard input; variables set through --variable or --secret flag will take precedence',
exclusive: ['jsonFile', 'yamlStdin', 'yamlFile'],
}),
jsonFile: flags.string({
description: 'if set, read variables from a JSON array provided as a file; variables set through --variable or --secret flag will take precedence',
exclusive: ['jsonStdin', 'yamlStdin', 'yamlFile'],
}),
yamlStdin: flags.boolean({
default: false,
description: 'if set, read variables from a YAML array provided as standard input; variables set through --variable or --secret flag will take precedence',
exclusive: ['jsonStdin', 'jsonFile', 'yamlFile'],
}),
yamlFile: flags.string({
description: 'if set, read variables from a YAML array provided as a file; variables set through --variable or --secret flag will take precedence',
exclusive: ['jsonStdin', 'jsonFile', 'yamlStdin'],
}),
...commonFlags.outputFormat,
BaseVariablesCommand.setterFlags = (services) => {
return {
...BaseVariablesCommand.coreSetterFlags,
jsonStdin: flags.boolean({
default: false,
description: 'if set, read variables from a JSON array provided as standard input; variables set through --variable or --secret flag will take precedence',
exclusive: ['jsonFile', 'yamlStdin', 'yamlFile'],
}),
jsonFile: flags.string({
description: 'if set, read variables from a JSON array provided as a file; variables set through --variable or --secret flag will take precedence',
exclusive: ['jsonStdin', 'yamlStdin', 'yamlFile'],
}),
yamlStdin: flags.boolean({
default: false,
description: 'if set, read variables from a YAML array provided as standard input; variables set through --variable or --secret flag will take precedence',
exclusive: ['jsonStdin', 'jsonFile', 'yamlFile'],
}),
yamlFile: flags.string({
description: 'if set, read variables from a YAML array provided as a file; variables set through --variable or --secret flag will take precedence',
exclusive: ['jsonStdin', 'jsonFile', 'yamlStdin'],
}),
...commonFlags.outputFormat,
...BaseVariablesCommand.serviceSetterFlags(services),
}
}

BaseVariablesCommand.getterFlags = {
Expand Down Expand Up @@ -237,4 +255,20 @@ BaseVariablesCommand.loadVariablesFromYaml = (rawData, currentVariableTypes, var
loadVariableData(data, currentVariableTypes, variables)
}

BaseVariablesCommand.serviceSetterFlags = (services) => {
const serviceFlags = {}
services.forEach(service => {
Object.keys(BaseVariablesCommand.coreSetterFlags).forEach(coreFlagKey => {
const coreFlag = BaseVariablesCommand.coreSetterFlags[coreFlagKey]
const flagName = _.camelCase(`${service} ${coreFlagKey}`)
serviceFlags[flagName] = flags.string({
description: `${coreFlag.description} for ${service} service`,
multiple: true,
})
})
})

return serviceFlags
}

module.exports = BaseVariablesCommand
2 changes: 1 addition & 1 deletion src/commands/cloudmanager/environment/bind-ip-allowlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ BindIPAllowlist.description = 'Bind an IP Allowlist to an environment'
BindIPAllowlist.args = [
commonArgs.environmentId,
{ name: 'ipAllowlistId', required: true, description: 'the IP allowlist id' },
commonArgs.service,
commonArgs.environmentServices,
]

BindIPAllowlist.flags = {
Expand Down
31 changes: 3 additions & 28 deletions src/commands/cloudmanager/environment/set-variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ const BaseVariablesCommand = require('../../../base-variables-command')
const { initSdk, sanitizeEnvironmentId } = require('../../../cloudmanager-helpers')
const { flags } = require('@oclif/command')
const Config = require('@adobe/aio-lib-core-config')
const _ = require('lodash')
const commonFlags = require('../../../common-flags')
const commonArgs = require('../../../common-args')
const { services } = require('../../../constants')
const { environmentServices } = require('../../../constants')
const { codes: validationCodes } = require('../../../ValidationErrors')

const IGNORED_PREFIXES = [
Expand All @@ -29,20 +28,7 @@ const IGNORED_PREFIXES = [

class SetEnvironmentVariablesCommand extends BaseEnvironmentVariablesCommand {
getFlagDefs () {
const coreFlagDefs = super.getFlagDefs()
const result = {
...coreFlagDefs,
}
services.forEach(service => {
Object.keys(coreFlagDefs).forEach(coreFlagKey => {
const flagName = _.camelCase(`${service} ${coreFlagKey}`)
result[flagName] = {
...coreFlagDefs[coreFlagKey],
service,
}
})
})
return result
return super.getFlagDefs(environmentServices)
}

async run () {
Expand Down Expand Up @@ -83,21 +69,10 @@ SetEnvironmentVariablesCommand.args = [
SetEnvironmentVariablesCommand.flags = {
...commonFlags.global,
...commonFlags.programId,
...BaseVariablesCommand.setterFlags,
...BaseVariablesCommand.setterFlags(environmentServices),
strict: flags.boolean({ description: 'performs strict validation of internal variables. Can also be enabled by setting configuration property cloudmanager.environmentVariables.strictValidation to a truthy value.' }),
}

services.forEach(service => {
Object.keys(BaseVariablesCommand.coreSetterFlags).forEach(coreFlagKey => {
const coreFlag = BaseVariablesCommand.coreSetterFlags[coreFlagKey]
const flagName = _.camelCase(`${service} ${coreFlagKey}`)
SetEnvironmentVariablesCommand.flags[flagName] = flags.string({
description: `${coreFlag.description} for ${service} service`,
multiple: true,
})
})
})

SetEnvironmentVariablesCommand.aliases = [
'cloudmanager:set-environment-variables',
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ UnbindIPAllowlist.strict = false
UnbindIPAllowlist.args = [
commonArgs.environmentId,
{ name: 'ipAllowlistId', required: true, description: 'the IP allowlist id' },
commonArgs.service,
commonArgs.environmentServices,
]

UnbindIPAllowlist.flags = {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/cloudmanager/ip-allowlist/bind.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ BindIPAllowlist.strict = false
BindIPAllowlist.args = [
{ name: 'ipAllowlistId', required: true, description: 'the IP allowlist id' },
commonArgs.environmentId,
commonArgs.service,
commonArgs.environmentServices,
]

BindIPAllowlist.flags = {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/cloudmanager/ip-allowlist/unbind.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ UnbindIPAllowlist.strict = false
UnbindIPAllowlist.args = [
{ name: 'ipAllowlistId', required: true, description: 'the IP allowlist id' },
commonArgs.environmentId,
commonArgs.service,
commonArgs.environmentServices,
]

UnbindIPAllowlist.flags = {
Expand Down
7 changes: 6 additions & 1 deletion src/commands/cloudmanager/pipeline/set-variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@ const BasePipelineVariablesCommand = require('../../../base-pipeline-variables-c
const BaseVariablesCommand = require('../../../base-variables-command')
const { initSdk } = require('../../../cloudmanager-helpers')
const commonFlags = require('../../../common-flags')
const { pipelineServices } = require('../../../constants')

class SetPipelineVariablesCommand extends BasePipelineVariablesCommand {
getFlagDefs () {
return super.getFlagDefs(pipelineServices)
}

async run () {
const { args, flags } = this.parse(SetPipelineVariablesCommand)

Expand All @@ -37,7 +42,7 @@ SetPipelineVariablesCommand.args = [
SetPipelineVariablesCommand.flags = {
...commonFlags.global,
...commonFlags.programId,
...BaseVariablesCommand.setterFlags,
...BaseVariablesCommand.setterFlags(pipelineServices),
}

SetPipelineVariablesCommand.aliases = [
Expand Down
4 changes: 2 additions & 2 deletions src/common-args.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ OF ANY KIND, either express or implied. See the License for the specific languag
governing permissions and limitations under the License.
*/

const { services } = require('./constants')
const { environmentServices } = require('./constants')

module.exports = {
service: { name: 'service', required: true, options: services, description: 'the service name' },
environmentServices: { name: 'service', required: true, options: environmentServices, description: 'the service name' },
environmentId: { name: 'environmentId', required: true, description: 'the environment id' },
}
3 changes: 2 additions & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ governing permissions and limitations under the License.
*/

module.exports = {
services: ['author', 'publish', 'preview'],
environmentServices: ['author', 'publish', 'preview'],
pipelineServices: ['build', 'functionalTest', 'uiTest', 'loadTest'],
defaultImsContextName: 'aio-cli-plugin-cloudmanager',
exitCodes: {
GENERAL: 1,
Expand Down
10 changes: 10 additions & 0 deletions test/__mocks__/@adobe/aio-lib-cloudmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ function createDefaultMock () {
}, {
name: 'I_AM_A_SECRET',
type: 'secretString',
}, {
name: 'FUNCTIONAL_VARIABLE',
value: 'something',
service: 'functionalTest',
type: 'string',
}, {
name: 'BUILD_SECRET',
value: 'something',
service: 'build',
type: 'secretString',
}])),
setPipelineVariables: jest.fn(() => Promise.resolve()),
deleteProgram: jest.fn(() => Promise.resolve()),
Expand Down
Loading

0 comments on commit 2461afb

Please sign in to comment.