Skip to content

Commit 0fc4501

Browse files
projects (#318)
* projects crud + rename helper + pip projectId filter * update cli docs * add last_updated to project output * valid openapi.json * fix typo + move id to wide display option * update version
1 parent b962c77 commit 0fc4501

File tree

15 files changed

+696
-8
lines changed

15 files changed

+696
-8
lines changed

docs/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const categoriesOrder = {
1919
'operate on resources' : 32,
2020
pipelines : 40,
2121
'pipelines v2 (beta)' : 42,
22+
projects : 45,
2223
builds: 50,
2324
contexts : 70 ,
2425
images : 80 ,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const Command = require('../../Command');
22
const CFError = require('cf-errors');
33
const _ = require('lodash');
4-
const { prepareKeyValueCompostionFromCLIEnvOption } = require('../../helpers/general');
4+
const { prepareKeyValueObjectsFromCLIEnvOption } = require('../../helpers/general');
55
const createRoot = require('../root/create.cmd');
66
const { crudFilenameOption } = require('../../helpers/general');
77
const { sdk } = require('../../../../logic');
@@ -47,7 +47,7 @@ const command = new Command({
4747
handler: async (argv) => {
4848
const data = argv.filename || {
4949
name: argv.name,
50-
vars: prepareKeyValueCompostionFromCLIEnvOption(argv.variable),
50+
vars: prepareKeyValueObjectsFromCLIEnvOption(argv.variable),
5151
yamlJson: argv['compose-file'],
5252
isAdvanced: argv.advanced,
5353
};

lib/interface/cli/commands/composition/replace.cmd.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const _ = require('lodash');
44
const replaceRoot = require('../root/replace.cmd');
55
const { crudFilenameOption } = require('../../helpers/general');
66
const { sdk } = require('../../../../logic');
7-
const { prepareKeyValueCompostionFromCLIEnvOption } = require('../../helpers/general');
7+
const { prepareKeyValueObjectsFromCLIEnvOption } = require('../../helpers/general');
88

99

1010
const command = new Command({
@@ -46,7 +46,7 @@ const command = new Command({
4646
handler: async (argv) => {
4747
const data = argv.filename || {
4848
name: argv.name,
49-
vars: prepareKeyValueCompostionFromCLIEnvOption(argv.variable),
49+
vars: prepareKeyValueObjectsFromCLIEnvOption(argv.variable),
5050
yamlJson: argv['compose-file'],
5151
isAdvanced: argv.advanced,
5252
};

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ const command = new Command({
3232
.option('name', {
3333
describe: 'Filter pipelines by name',
3434
})
35+
.option('project-id', {
36+
describe: 'Filter pipelines by project id',
37+
})
38+
.option('project', {
39+
describe: 'Filter pipelines by project name',
40+
})
3541
.option('label', {
3642
describe: 'Filter by a label',
3743
alias: 'l',
@@ -47,7 +53,7 @@ const command = new Command({
4753
});
4854
},
4955
handler: async (argv) => {
50-
const { id: ids, name, d: decryptVariables } = argv;
56+
const { id: ids, name, d: decryptVariables, projectId, project: projectName } = argv;
5157
const limit = argv.limit;
5258
const offset = (argv.page - 1) * limit;
5359
const labels = prepareKeyValueFromCLIEnvOption(argv.label);
@@ -74,11 +80,21 @@ const command = new Command({
7480
}
7581
Output.print(pipelines);
7682
} else {
83+
let _projectId = projectId;
84+
if (!projectId && projectName) {
85+
const project = await sdk.projects.getByName({ name: projectName })
86+
.catch(e => Promise.reject(new CFError({
87+
message: `Could not get project "${projectName}"`,
88+
cause: e,
89+
})));
90+
_projectId = project.id;
91+
}
7792
const pipelines = await sdk.pipelines.list({
7893
limit,
7994
offset,
8095
id: name,
8196
labels,
97+
projectId: _projectId,
8298
});
8399
Output.print(pipelines.docs.map(Pipeline.fromResponse));
84100
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
const Command = require('../../Command');
2+
const CFError = require('cf-errors');
3+
const _ = require('lodash');
4+
const { sdk } = require('../../../../logic');
5+
6+
const applyRoot = require('../root/apply.cmd');
7+
const { prepareKeyValueObjectsFromCLIEnvOption, ignoreHttpError } = require('../../helpers/general');
8+
9+
const command = new Command({
10+
command: 'project [id|name]',
11+
aliases: [],
12+
parent: applyRoot,
13+
description: 'Patch a project',
14+
webDocs: {
15+
category: 'Projects',
16+
title: 'Patch Project',
17+
},
18+
builder: (yargs) => {
19+
yargs
20+
.positional('id|name', {
21+
describe: 'project id or name',
22+
})
23+
.option('newName', {
24+
describe: 'New name',
25+
alias: 'n',
26+
})
27+
.option('tag', {
28+
array: true,
29+
alias: 't',
30+
describe: 'Project tags',
31+
})
32+
.option('variable', {
33+
array: true,
34+
alias: 'v',
35+
describe: 'Project variables',
36+
coerce: prepareKeyValueObjectsFromCLIEnvOption,
37+
})
38+
.option('encrypted', {
39+
array: true,
40+
alias: 'e',
41+
describe: 'Variable names to encrypt',
42+
})
43+
.example(
44+
'codefresh patch project ID --new-name NEW_NAME --tag test',
45+
'Replace project name and tags. Specifying project by ID',
46+
)
47+
.example(
48+
'codefresh patch project NAME -v test=test',
49+
'Replace project variables. Specifying project by NAME',
50+
);
51+
52+
return yargs;
53+
},
54+
handler: async (argv) => {
55+
const { id, name } = argv;
56+
57+
const {
58+
newName: projectName = name,
59+
tag: tags,
60+
variable: variables,
61+
encrypted,
62+
} = argv;
63+
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+
});
72+
73+
let project = await sdk.projects.get({ id }).catch(ignoreHttpError);
74+
project = project || await sdk.projects.getByName({ name }).catch(ignoreHttpError);
75+
if (!project) {
76+
throw new CFError(`No such project: "${name || id}"`);
77+
}
78+
79+
await sdk.projects.patch({ id: project.id }, { projectName, tags, variables });
80+
console.log(`Project: "${name || id}" patched.`);
81+
},
82+
});
83+
84+
module.exports = command;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const Command = require('../../Command');
2+
const CFError = require('cf-errors');
3+
const _ = require('lodash');
4+
const { sdk } = require('../../../../logic');
5+
const createRoot = require('../root/create.cmd');
6+
const { prepareKeyValueObjectsFromCLIEnvOption, ignoreHttpError } = require('../../helpers/general');
7+
8+
const command = new Command({
9+
command: 'project <name>',
10+
parent: createRoot,
11+
description: 'Create a project',
12+
usage: 'Create a project specifying name unique for account.',
13+
webDocs: {
14+
category: 'Projects',
15+
title: 'Create Project',
16+
},
17+
builder: (yargs) => {
18+
return yargs
19+
.positional('name', {
20+
describe: 'Name of project',
21+
})
22+
.option('tag', {
23+
array: true,
24+
alias: 't',
25+
describe: 'Project tags',
26+
default: [],
27+
})
28+
.option('variable', {
29+
array: true,
30+
alias: 'v',
31+
describe: 'Project variables',
32+
default: [],
33+
coerce: prepareKeyValueObjectsFromCLIEnvOption,
34+
})
35+
.option('encrypted', {
36+
array: true,
37+
alias: 'e',
38+
describe: 'Variable names to encrypt',
39+
default: [],
40+
})
41+
.example('codefresh create project NAME', 'Create a project')
42+
.example('codefresh create project NAME -t test -t run', 'Create a project with tags: [ "test", "run"]')
43+
.example('codefresh create project NAME -v test=true -v run=false', 'Create a project with specific variables')
44+
.example('codefresh create project NAME -v secret=secret -e secret', 'Create a project with encrypted variables');
45+
},
46+
handler: async (argv) => {
47+
const {
48+
name: projectName,
49+
tag: tags,
50+
variable: variables,
51+
encrypted,
52+
} = argv;
53+
54+
const variableMap = _.reduce(variables, (acc, v) => _.assign(acc, { [v.key]: v }), {});
55+
_.forEach(encrypted, (varName) => {
56+
const variable = variableMap[varName];
57+
if (!variable) {
58+
throw new CFError(`Variable is not provided: "${varName}"`);
59+
}
60+
variable.encrypted = true;
61+
});
62+
63+
const existing = await sdk.projects.getByName({ name: projectName }).catch(ignoreHttpError); // ignore not found error
64+
if (existing) {
65+
throw new CFError(`Project already exists: "${projectName}"`);
66+
}
67+
68+
await sdk.projects.create({ projectName, tags, variables });
69+
console.log(`Project: "${projectName}" created`);
70+
},
71+
});
72+
73+
module.exports = command;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const Command = require('../../Command');
2+
const CFError = require('cf-errors');
3+
const { sdk } = require('../../../../logic');
4+
const deleteRoot = require('../root/delete.cmd');
5+
const { ignoreHttpError } = require('../../helpers/general');
6+
7+
const command = new Command({
8+
command: 'project <id|name>',
9+
aliases: [],
10+
parent: deleteRoot,
11+
description: 'Delete a project',
12+
webDocs: {
13+
category: 'Projects',
14+
title: 'Delete Project',
15+
},
16+
builder: (yargs) => {
17+
yargs
18+
.positional('id|name', {
19+
describe: 'project id or name',
20+
})
21+
.example('codefresh delete project NAME', 'Delete project by name.')
22+
.example('codefresh delete project ID', 'Delete project by Id.');
23+
return yargs;
24+
},
25+
handler: async (argv) => {
26+
const { id, name } = argv;
27+
28+
let project = await sdk.projects.get({ id }).catch(ignoreHttpError);
29+
project = project || await sdk.projects.getByName({ name }).catch(ignoreHttpError);
30+
if (!project) {
31+
throw new CFError(`No such project: "${name || id}"`);
32+
}
33+
34+
await sdk.projects.delete({ id: project.id });
35+
console.log(`Project '${name || id}' deleted.`);
36+
},
37+
});
38+
39+
module.exports = command;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
const Command = require('../../Command');
2+
const { sdk } = require('../../../../logic');
3+
const Project = require('../../../../logic/entities/Project');
4+
const Output = require('../../../../output/Output');
5+
const _ = require('lodash');
6+
const DEFAULTS = require('../../defaults');
7+
const { ignoreHttpError } = require('../../helpers/general');
8+
9+
const getRoot = require('../root/get.cmd');
10+
11+
const command = new Command({
12+
command: 'projects [id|name]',
13+
aliases: ['project'],
14+
parent: getRoot,
15+
description: 'Get a specific project or an array of projects',
16+
webDocs: {
17+
category: 'Projects',
18+
title: 'Get Projects',
19+
},
20+
builder: (yargs) => {
21+
return yargs
22+
.positional('id|name', {
23+
describe: 'Project id or name to get one project',
24+
})
25+
.option('name', {
26+
alias: 'n',
27+
describe: 'Project name to filter by',
28+
})
29+
.option('tag', {
30+
alias: 't',
31+
describe: 'Project tags array to filter by',
32+
array: true,
33+
})
34+
.option('limit', {
35+
describe: 'Limit amount of returned results',
36+
default: DEFAULTS.GET_LIMIT_RESULTS,
37+
})
38+
.option('page', {
39+
describe: 'Paginated page',
40+
default: DEFAULTS.GET_PAGINATED_PAGE,
41+
});
42+
},
43+
handler: async (argv) => {
44+
const { id, name, limit, page, tag: tags } = argv; // eslint-disable-line
45+
const offset = (page - 1) * limit;
46+
47+
let projects;
48+
if (id) {
49+
let project = await sdk.projects.get({ id }).catch(ignoreHttpError);
50+
project = project || await sdk.projects.getByName({ name }).catch(ignoreHttpError);
51+
projects = project ? [project] : [];
52+
} else {
53+
const result = await sdk.projects.list({
54+
name,
55+
tags,
56+
limit,
57+
offset,
58+
});
59+
projects = result.projects; // eslint-disable-line
60+
}
61+
Output.print(_.map(projects, Project.fromResponse));
62+
},
63+
});
64+
65+
module.exports = command;

0 commit comments

Comments
 (0)