Skip to content

Commit acbce01

Browse files
CR-17813 (#800)
* CR-17813 * WIP * WIP * WIP * WIP * WIP * WIP * WIP * WIP * add tests * add tests files * wip * add documentation * add documentation * wip documentation * wip documentation * wip documentation * address Kim comments * address Daniel comments * address Daniel comments * wip
1 parent 28f40bf commit acbce01

File tree

10 files changed

+197
-54
lines changed

10 files changed

+197
-54
lines changed

docs/content/pipelines/Run Pipeline.md

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,44 @@ The pipeline will be triggered multiple times according to the array length.
1515

1616
#### Variable yaml file with 2 sets of variables
1717
```yaml
18-
- key: value
19-
key2: key1
20-
- key: value
21-
key2: key2
18+
- VARIABLE_A: value_a_for_the_first_build
19+
VARIABLE_B: value_b_for_the_first_build
20+
- VARIABLE_A: value_a_for_the_first_build
21+
VARIABLE_B: value_b_for_the_first_build
2222
```
2323
2424
#### Variable json file with 2 sets of variables
2525
```json
2626
[
2727
{
28-
"key": "value",
29-
"key2": "key1"
28+
"VARIABLE_A": "value_a_for_the_first_build",
29+
"VARIABLE_B": "value_b_for_the_first_build"
3030
},
3131
{
32-
"key": "value",
33-
"key2": "key2"
32+
"VARIABLE_A": "value_a_for_the_first_build",
33+
"VARIABLE_B": "value_b_for_the_first_build"
34+
}
35+
]
36+
```
37+
### Use encrypted variables in Codefresh build runs; supported from CLI version: 0.82.8
38+
#### Variable yaml file with single variable set with encrypted variables
39+
```yaml
40+
- key:
41+
val: value
42+
encrypted: true
43+
key2: key1
44+
45+
```
46+
47+
#### Variable json file single variable set with encrypted variables
48+
```json
49+
[
50+
{
51+
"key": {
52+
"val": "value",
53+
"encrypted": true
54+
},
55+
"key2": "key1"
3456
}
3557
]
3658
```

lib/interface/cli/commands/pipeline/pipeline.sdk.spec.js

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
const yaml = require('js-yaml');
2+
const request = require('requestretry');
3+
const fs = require('fs');
14
const DEFAULTS = require('../../defaults');
25
const getCmd = require('./get.cmd').toCommand();
36
const deleteCmd = require('./delete.cmd').toCommand();
@@ -10,18 +13,16 @@ jest.mock('../../helpers/validation'); // eslint-disable-line
1013
jest.mock('../../../../../check-version');
1114
jest.mock('../../completion/helpers', () => { // eslint-disable-line
1215
return {
13-
authContextWrapper: func => func,
16+
authContextWrapper: (func) => func,
1417
};
1518
});
1619

1720
jest.mock('../../../../logic/entities/Pipeline', () => { // eslint-disable-line
1821
return {
19-
fromResponse: res => res,
22+
fromResponse: (res) => res,
2023
};
2124
});
2225

23-
const request = require('requestretry');
24-
2526
const DEFAULT_RESPONSE = request.__defaultResponse();
2627

2728
describe('pipeline', () => {
@@ -57,11 +58,11 @@ describe('pipeline', () => {
5758
});
5859

5960
it('should return default limit', async () => {
60-
expect(_getLimit(undefined,false)).toEqual(DEFAULTS.GET_LIMIT_RESULTS);
61+
expect(_getLimit(undefined, false)).toEqual(DEFAULTS.GET_LIMIT_RESULTS);
6162
});
6263

6364
it('should return `unlimited` value', async () => {
64-
expect(_getLimit(undefined,true)).toEqual(DEFAULTS.GET_ALL_PIPELINES_LIMIT);
65+
expect(_getLimit(undefined, true)).toEqual(DEFAULTS.GET_ALL_PIPELINES_LIMIT);
6566
});
6667
});
6768

@@ -84,6 +85,75 @@ describe('pipeline', () => {
8485
});
8586
});
8687

88+
describe('run', () => {
89+
it('should handle running pipeline with encrypted variables', async () => {
90+
const argv = { name: 'some name',
91+
detach: true,
92+
annotation: [],
93+
variable:
94+
[{
95+
key: 'secret',
96+
value: 'secret',
97+
},
98+
{
99+
key: 'VAR1',
100+
value: 'VAL1',
101+
},
102+
],
103+
encrypted: ['secret'],
104+
};
105+
const pip = new CfPipeline(argv);
106+
await pip.run();
107+
expect(pip.executionRequests[0].options.variables).toEqual([
108+
{
109+
key: 'secret',
110+
value: 'secret',
111+
encrypted: true,
112+
},
113+
{
114+
key: 'VAR1',
115+
value: 'VAL1',
116+
},
117+
]);
118+
await verifyResponsesReturned([DEFAULT_RESPONSE]); // eslint-disable-line
119+
});
120+
121+
it('should handle running pipeline with encrypted variables passing inside json file', async () => {
122+
const rawFile = fs.readFileSync('lib/interface/cli/commands/pipeline/var.json', 'utf8');
123+
124+
const argv = { name: 'some name',
125+
detach: true,
126+
annotation: [],
127+
'var-file': JSON.parse(rawFile),
128+
};
129+
const pip = new CfPipeline(argv);
130+
await pip.run();
131+
expect(pip.executionRequests[0].options.variables).toEqual(
132+
[{ key: 'help6', value: '85858' },
133+
{ key: 'should_be_encrepted', value: '0000' },
134+
{ encrypted: true, key: 'help7', value: 'test' }],
135+
);
136+
await verifyResponsesReturned([DEFAULT_RESPONSE]); // eslint-disable-line
137+
});
138+
139+
it('should handle running pipeline with encrypted variables passing inside yaml file', async () => {
140+
const rawFile = fs.readFileSync('lib/interface/cli/commands/pipeline/var.yml', 'utf8');
141+
142+
const argv = { name: 'some name',
143+
detach: true,
144+
annotation: [],
145+
'var-file': yaml.safeLoad(rawFile),
146+
};
147+
const pip = new CfPipeline(argv);
148+
await pip.run();
149+
expect(pip.executionRequests[0].options.variables).toEqual(
150+
[{ key: 'VAR1', value: 'VAL1' },
151+
{ encrypted: true, key: 'VAR2', value: 'VAL2' }],
152+
);
153+
await verifyResponsesReturned([DEFAULT_RESPONSE]); // eslint-disable-line
154+
});
155+
});
156+
87157
describe('runImpl', () => {
88158
it('should handle running pipeline', async () => {
89159
const argv = { name: 'some name', detach: true };

lib/interface/cli/commands/pipeline/run.base.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
const _ = require('lodash');
22
const Promise = require('bluebird');
3-
const { prepareKeyValueFromCLIEnvOption } = require('../../helpers/general');
3+
const CFError = require('cf-errors');
4+
const { prepareKeyValueFromCLIEnvOption,
5+
markEncryptedFlagOnRequestedVariables,
6+
prepareKeyValueObjectsFromEnvFileOption } = require('../../helpers/general');
47
const { validatePipelineYaml } = require('../../helpers/validation');
58
const { printResult } = require('../root/validate.cmd');
6-
const CFError = require('cf-errors');
79
const { sdk } = require('../../../../logic');
810

911
class RunBaseCommand {
@@ -59,18 +61,18 @@ class RunBaseCommand {
5961
if (variablesFromFile) {
6062
_.forEach(variablesFromFile, (variables) => {
6163
const request = _.cloneDeep(executionRequestTemplate);
62-
request.options.variables = variables;
64+
request.options.variables = prepareKeyValueObjectsFromEnvFileOption(variables);
6365
this.executionRequests.push(request);
6466
});
6567
} else {
66-
const variables = prepareKeyValueFromCLIEnvOption(this.argv.variable);
68+
const variables = markEncryptedFlagOnRequestedVariables(this.argv.variable, this.argv.encrypted);
6769
const request = _.cloneDeep(executionRequestTemplate);
6870
request.options.variables = variables;
6971
request.options.contexts = contexts;
7072
this.executionRequests.push(request);
7173
}
7274

73-
const results = await Promise.all(this.executionRequests.map(request => this.runImpl(request)));
75+
const results = await Promise.all(this.executionRequests.map((request) => this.runImpl(request)));
7476
const findMaxReducer = (accumulator, currentValue) => (currentValue > accumulator ? currentValue : accumulator);
7577
const exitCode = results.reduce(findMaxReducer);
7678
await this.postRunRequest();

lib/interface/cli/commands/pipeline/run.cmd.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
const debug = require('debug')('codefresh:cli:run:pipeline');
21
const Command = require('../../Command');
3-
const { crudFilenameOption } = require('../../helpers/general');
2+
const { crudFilenameOption, prepareKeyValueObjectsFromCLIEnvOption } = require('../../helpers/general');
43
const RunLocalCommand = require('./run.local');
54
const RunExternalCommand = require('./run.cf');
65

@@ -85,6 +84,13 @@ const run = new Command({
8584
describe: 'Set build variables',
8685
default: [],
8786
alias: 'v',
87+
coerce: prepareKeyValueObjectsFromCLIEnvOption,
88+
})
89+
.option('encrypted', {
90+
array: true,
91+
alias: 'e',
92+
describe: 'Variable names to encrypt',
93+
default: [],
8894
})
8995
.option('detach', {
9096
alias: 'd',
@@ -126,6 +132,7 @@ const run = new Command({
126132
.example('codefresh run PIPELINE_ID | PIPELINE_NAME -b=master', 'Defining the source control context using a branch')
127133
.example('codefresh run PIPELINE_ID | PIPELINE_NAME -s=52b992e783d2f84dd0123c70ac8623b4f0f938d1', 'Defining the source control context using a commit')
128134
.example('codefresh run PIPELINE_ID | PIPELINE_NAME -b=master -v key1=value1 -v key2=value2', 'Setting variables through the command')
135+
.example('codefresh run PIPELINE_ID | PIPELINE_NAME -b=master -v key1=value1 -v key2=value2 -e key1', 'Setting variables through the command with encrypted option')
129136
.example('codefresh run PIPELINE_ID | PIPELINE_NAME -b=master --var-file ./var_file.yml', 'Settings variables through a yml file')
130137
.example('codefresh run PIPELINE_ID | PIPELINE_NAME -b=master --context context', 'Inject contexts to the pipeline execution')
131138
.example('codefresh run PIPELINE_ID | PIPELINE_NAME --skip step1 step2 step3', 'Skip specific steps');
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"build1": {
3+
"help6": "85858",
4+
"should_be_encrepted": "0000",
5+
"help7": {
6+
"value": "test",
7+
"encrypted": true
8+
}
9+
}
10+
}
11+
12+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
build1:
2+
VAR1: 'VAL1'
3+
VAR2:
4+
value: VAL2
5+
encrypted: true

lib/interface/cli/commands/project/apply.cmd.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const _ = require('lodash');
44
const { sdk } = require('../../../../logic');
55

66
const applyRoot = require('../root/apply.cmd');
7-
const { prepareKeyValueObjectsFromCLIEnvOption, ignoreHttpError } = require('../../helpers/general');
7+
const { prepareKeyValueObjectsFromCLIEnvOption, ignoreHttpError, markEncryptedFlagOnRequestedVariables } = require('../../helpers/general');
88

99
const command = new Command({
1010
command: 'project [id|name]',
@@ -61,14 +61,7 @@ const command = new Command({
6161
encrypted,
6262
} = argv;
6363

64-
const variableMap = _.reduce(variables, (acc, v) => _.assign(acc, { [v.key]: v }), {});
65-
_.forEach(encrypted, (varName) => {
66-
const variable = variableMap[varName];
67-
if (!variable) {
68-
throw new CFError(`Variable is not provided: "${varName}"`);
69-
}
70-
variable.encrypted = true;
71-
});
64+
const requestedProjectVariables = markEncryptedFlagOnRequestedVariables(variables, encrypted);
7265

7366
let project = await sdk.projects.get({ id }).catch(ignoreHttpError);
7467
project = project || await sdk.projects.getByName({ name }).catch(ignoreHttpError);
@@ -81,7 +74,7 @@ const command = new Command({
8174
const updatePayload = _.pickBy({
8275
projectName,
8376
tags: tags || existingTags,
84-
variables: variables || existingVariables,
77+
variables: requestedProjectVariables || existingVariables,
8578
}, _.identity);
8679

8780
await sdk.projects.patch({ id: project.id }, updatePayload);

lib/interface/cli/commands/project/create.cmd.js

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
const Command = require('../../Command');
2-
const CFError = require('cf-errors');
3-
const _ = require('lodash');
42
const { sdk } = require('../../../../logic');
53
const createRoot = require('../root/create.cmd');
64
const { checkOrProjectExists } = require('../../helpers/validation');
7-
const { prepareKeyValueObjectsFromCLIEnvOption } = require('../../helpers/general');
5+
const { prepareKeyValueObjectsFromCLIEnvOption, markEncryptedFlagOnRequestedVariables } = require('../../helpers/general');
86

97
const command = new Command({
108
command: 'project <name>',
@@ -52,17 +50,10 @@ const command = new Command({
5250
encrypted,
5351
} = argv;
5452

55-
const variableMap = _.reduce(variables, (acc, v) => _.assign(acc, { [v.key]: v }), {});
56-
_.forEach(encrypted, (varName) => {
57-
const variable = variableMap[varName];
58-
if (!variable) {
59-
throw new CFError(`Variable is not provided: "${varName}"`);
60-
}
61-
variable.encrypted = true;
62-
});
53+
const requestedProjectVariables = markEncryptedFlagOnRequestedVariables(variables, encrypted);
6354

6455
await checkOrProjectExists(projectName);
65-
await sdk.projects.create({ projectName, tags, variables });
56+
await sdk.projects.create({ projectName, tags, variables: requestedProjectVariables });
6657
console.log(`Project: "${projectName}" created`);
6758
},
6859
});

0 commit comments

Comments
 (0)