diff --git a/docs/content/operate on resources/_index.md b/docs/content/operate on resources/_index.md index 5841f8187..99cf5f2fd 100644 --- a/docs/content/operate on resources/_index.md +++ b/docs/content/operate on resources/_index.md @@ -1,6 +1,6 @@ +++ title = "Operate On Resources" -weight = 60 +weight = 31 +++ The CLI supports the ability to work with `spec` files when working with resources.
diff --git a/docs/index.js b/docs/index.js index 9e9ffa50f..77bb43707 100644 --- a/docs/index.js +++ b/docs/index.js @@ -15,15 +15,16 @@ const baseDir = path.resolve(TEMP_DIR, './content'); const ALLOW_BETA_COMMANDS = process.env.ALLOW_BETA_COMMANDS; const categoriesOrder = { authentication: 30, + 'operate on resources' : 31, pipelines : 40, 'pipelines v2 (beta)' : 42, builds: 50, - 'operate on resources' : 60, contexts : 70 , images : 80 , triggers : 90, environments : 100 , compositions : 110 , + 'helm repos' : 111 , 'predefined pipelines': 120, more : 130 , }; diff --git a/lib/interface/cli/commands/helm/repo/apply.cmd.js b/lib/interface/cli/commands/helm/repo/apply.cmd.js new file mode 100644 index 000000000..7b7be6cef --- /dev/null +++ b/lib/interface/cli/commands/helm/repo/apply.cmd.js @@ -0,0 +1,49 @@ +const debug = require('debug')('codefresh:cli:create:pipelines2'); +const Command = require('../../../Command'); +const CFError = require('cf-errors'); +const _ = require('lodash'); +const { helm } = require('../../../../../logic').api; +const { printError } = require('../../../helpers/general'); +const { specifyOutputForArray } = require('../../../helpers/get'); + +const applyRoot = require('../../root/apply.cmd'); + + +const command = new Command({ + command: 'helm-repo [name]', + aliases: [], + parent: applyRoot, + description: 'Update a helm repo', + webDocs: { + category: 'Helm Repos', + title: 'Update Helm Repo', + }, + builder: (yargs) => { + yargs + .positional('name', { + describe: 'Name of context', + }) + .option('public', { + describe: 'Mark the helm repo as public', + alias: 'p', + type: 'boolean', + default: false, + }) + .example('codefresh patch helm-repo my-repo -p', 'Update helm repo to be public') + .example('codefresh patch helm-repo my-repo -p=false', 'Update helm repo to be private'); + + return yargs; + }, + handler: async (argv) => { + const data = { + name: argv.name, + public: argv.public, + }; + + await helm.updateRepo(data.name, data); + console.log(`Helm repo: ${data.name} patched.`); + }, +}); + +module.exports = command; + diff --git a/lib/interface/cli/commands/helm/repo/create.cmd.js b/lib/interface/cli/commands/helm/repo/create.cmd.js new file mode 100644 index 000000000..278f20d4e --- /dev/null +++ b/lib/interface/cli/commands/helm/repo/create.cmd.js @@ -0,0 +1,45 @@ +const debug = require('debug')('codefresh:cli:create:context'); +const Command = require('../../../Command'); +const CFError = require('cf-errors'); +const _ = require('lodash'); +const { helm } = require('../../../../../logic').api; +const createRoot = require('../../root/create.cmd'); + +const command = new Command({ + command: 'helm-repo [name]', + parent: createRoot, + description: 'Create a Codefresh managed helm repo', + usage: 'ATM it is only possible to create a helm repository against Codefresh managed helm registry', + webDocs: { + category: 'Helm Repos', + title: 'Create Helm Repo', + }, + builder: (yargs) => { + yargs + .positional('name', { + describe: 'Name of context', + }) + .option('public', { + describe: 'Mark the helm repo as public', + alias: 'p', + type: 'boolean', + default: false, + }) + .example('codefresh create helm-repo', 'Create a private helm repo managed by Codefresh.') + .example('codefresh create helm-repo --public', 'Create a public helm repo managed by Codefresh.'); + + return yargs; + }, + handler: async (argv) => { + const data = { + name: argv.name, + public: argv.public, + }; + + await helm.createRepo(data); + console.log(`Helm repo: ${data.name} created`); + }, +}); + +module.exports = command; + diff --git a/lib/interface/cli/commands/helm/repo/delete.cmd.js b/lib/interface/cli/commands/helm/repo/delete.cmd.js new file mode 100644 index 000000000..33c535b81 --- /dev/null +++ b/lib/interface/cli/commands/helm/repo/delete.cmd.js @@ -0,0 +1,36 @@ +const debug = require('debug')('codefresh:cli:create:pipelines2'); +const Command = require('../../../Command'); +const CFError = require('cf-errors'); +const _ = require('lodash'); +const { helm } = require('../../../../../logic').api; +const deleteRoot = require('../../root/delete.cmd'); + + +const command = new Command({ + command: 'helm-repo [name]', + aliases: [], + parent: deleteRoot, + description: 'Delete a helm repo', + webDocs: { + category: 'Helm Repos', + title: 'Delete Helm Repo', + }, + builder: (yargs) => { + yargs + .positional('name', { + describe: 'Helm repo name', + }) + .example('codefresh delete helm-repo my-repo', 'Delete a helm repo.'); + return yargs; + }, + handler: async (argv) => { + const { name } = argv; + + await helm.deleteRepo(name); + console.log(`Helm repo '${name}' deleted.`); + }, +}); + + +module.exports = command; + diff --git a/lib/interface/cli/commands/helm/repo/get.cmd.js b/lib/interface/cli/commands/helm/repo/get.cmd.js new file mode 100644 index 000000000..bcbc619a9 --- /dev/null +++ b/lib/interface/cli/commands/helm/repo/get.cmd.js @@ -0,0 +1,60 @@ +const debug = require('debug')('codefresh:cli:create:pipelines2'); +const Command = require('../../../Command'); +const CFError = require('cf-errors'); +const _ = require('lodash'); +const { helm } = require('../../../../../logic').api; +const { printError } = require('../../../helpers/general'); +const { specifyOutputForArray } = require('../../../helpers/get'); + +const getRoot = require('../../root/get.cmd'); + + +const command = new Command({ + command: 'helm-repo [name..]', + aliases: [], + parent: getRoot, + description: 'Get a specific helm-repo or an array of helm-repos', + webDocs: { + category: 'Helm Repos', + title: 'Get Helm Repo', + }, + builder: (yargs) => { + yargs + .positional('name', { + describe: 'Helm repo name', + }) + .example('codefresh get helm-repo', 'Get all helm repos') + .example('codefresh get helm-repo my-repo', 'Get a specific helm repo'); + return yargs; + }, + handler: async (argv) => { + const { name: names, output } = argv; + + if (!_.isEmpty(names)) { + const repos = []; + for (const name of names) { + try { + const currRepo = await helm.getRepoByName(name); + repos.push(currRepo); + } catch (err) { + if (repos.length) { + specifyOutputForArray(output, repos); + } + + debug(err.toString()); + const message = err.toString().includes('not find') ? `Helm repo '${name}' was not found.` : 'Error occurred'; + throw new CFError({ + cause: err, + message, + }); + } + } + specifyOutputForArray(output, repos); + } else { + specifyOutputForArray(output, await helm.getAllRepos()); + } + }, +}); + +module.exports = command; + diff --git a/lib/logic/api/helm.js b/lib/logic/api/helm.js index ecc65ca81..a84408625 100644 --- a/lib/logic/api/helm.js +++ b/lib/logic/api/helm.js @@ -1,19 +1,15 @@ const Promise = require('bluebird'); const _ = require('lodash'); const CFError = require('cf-errors'); // eslint-disable-line -const { - sendHttpRequest, -} = require('./helper'); -const { - getContextByName, -} = require('./context'); +const { sendHttpRequest, } = require('./helper'); +const { getContextByName, } = require('./context'); +const HelmRepo = require('../entities/HelmRepo'); const SUPPORTED_TYPES = [ 'yaml', 'secret-yaml', ]; - const _normalizeValues = async (values = []) => { const normalizedValues = await Promise.reduce(values, async (normalized, name) => { let context; @@ -139,8 +135,74 @@ const deleteRelease = async ({ return res.id; }; + +const _extractFieldsForHelmRepoEntity = helmRepo => _.pick(helmRepo, 'Name', 'CreatedAt', 'Public', 'UpdatedAt'); + +const getAllRepos = async (options = {}) => { + const qs = options.query || {}; + + const RequestOptions = { + url: '/api/helm/repos', + method: 'GET', + qs, + }; + + const result = await sendHttpRequest(RequestOptions); + const helmRepos = []; + _.forEach(result, (helmRepo) => { + const data = _extractFieldsForHelmRepoEntity(helmRepo); + helmRepos.push(new HelmRepo(data)); + }); + + return helmRepos; +}; + +const getRepoByName = async (name) => { + const RequestOptions = { + url: `/api/helm/repos/${name}`, + method: 'GET', + }; + + const result = await sendHttpRequest(RequestOptions); + return new HelmRepo(result); +}; + +const createRepo = async (data) => { + const RequestOptions = { + url: '/api/helm/repos', + method: 'POST', + body: data, + }; + + return sendHttpRequest(RequestOptions); +}; + +const updateRepo = async (name, data) => { + const RequestOptions = { + url: `/api/helm/repos/${name}`, + method: 'PUT', + body: data, + }; + + return sendHttpRequest(RequestOptions); +}; + +const deleteRepo = async (name) => { + const RequestOptions = { + url: `/api/helm/repos/${name}`, + method: 'DELETE', + }; + + return sendHttpRequest(RequestOptions); +}; + module.exports = { installChart, testRelease, deleteRelease, + getAllRepos, + createRepo, + deleteRepo, + getRepoByName, + updateRepo, }; diff --git a/lib/logic/api/index.js b/lib/logic/api/index.js index b80370045..7e07ab541 100644 --- a/lib/logic/api/index.js +++ b/lib/logic/api/index.js @@ -9,6 +9,7 @@ const environment = require('./environment'); const workflow = require('./workflow'); const log = require('./log'); const version = require('./version'); +const helm = require('./helm'); module.exports = { user, @@ -22,4 +23,5 @@ module.exports = { workflow, log, version, + helm, }; diff --git a/lib/logic/entities/HelmRepo.js b/lib/logic/entities/HelmRepo.js new file mode 100644 index 000000000..6ab1f278f --- /dev/null +++ b/lib/logic/entities/HelmRepo.js @@ -0,0 +1,18 @@ +const moment = require('moment'); +const Entity = require('./Entity'); + +class Pipeline extends Entity { + constructor(data) { + super(); + this.entityType = 'helm-repo'; + this.info = data; + this.name = this.info.Name; + this.created = moment(this.info.CreatedAt).fromNow(); + this.updated = moment(this.info.UpdatedAt).fromNow(); + this.public = this.info.Public.toString(); + this.defaultColumns = ['name', 'public', 'created', 'updated']; + this.wideColumns = this.defaultColumns.concat([]); + } +} + +module.exports = Pipeline; diff --git a/package.json b/package.json index a4d6021ec..8edc56a10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codefresh", - "version": "0.8.48", + "version": "0.8.49", "description": "Codefresh command line utility", "main": "index.js", "preferGlobal": true,