Skip to content

Commit

Permalink
Cr 1885 release2 (#605)
Browse files Browse the repository at this point in the history
* Revert "Cr 1885 revert3 (#604)"

This reverts commit 0c31cc1

* install gitops codefresh

* release-2, tests

* update branch

* format

* СК-1885

* CR-1885

* CR-1885

* CR-1885

* CR-1885

* CR-1885

* fix test

Co-authored-by: olegz-codefresh <[email protected]>
  • Loading branch information
andrii-codefresh and olegz-codefresh authored Dec 16, 2020
1 parent e3a987e commit cdbf0fd
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 19 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ module.exports = {
'code': 140,
'ignoreComments': true
}],
'no-console': 0
'no-console': 0,
'object-curly-newline': 0,
},
'env': {
'jest': true,
Expand Down
114 changes: 114 additions & 0 deletions lib/interface/cli/commands/gitops/install-codefresh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const cp = require('child_process');
const rp = require('request-promise');
const promiseRetry = require('promise-retry');

const getExternalIp = namespace => async (retry) => {
process.stdout.write('.');
const ip = cp.execSync(
`kubectl get svc argocd-server -n ${namespace} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}'`,
{ encoding: 'utf-8' },
);
if (ip) {
return ip;
}

return retry(new Error('Can\'t get argocd external-ip address'));
};

async function install({ installManifest, kubeNamespace, setArgoPassword }) {
// sanitizing
const namespace = kubeNamespace.replace('"', '');
const manifest = installManifest.replace('"', '');
const password = setArgoPassword.replace('"', '');

try {
console.log(`Creating namespace ${namespace}...`);
cp.execSync(`kubectl create ns "${namespace}"`);
console.log(`\u2705 Created namespace ${namespace}`);
} catch (err) {
if (!err.message.match(/AlreadyExists/)) {
process.exit(err.status);
}
}

try {
console.log('Creating argocd resources...');
cp.execSync(`kubectl apply -n "${namespace}" -f "${manifest}"`, { stdio: 'inherit' });
console.log('\u2705 Created argocd resources');
} catch (err) {
process.exit(err.status);
}

let host;
try {
console.log('Changing service type to "LoadBalancer"...');
cp.execSync(
`kubectl patch svc argocd-server -n "${namespace}" -p '{"spec": {"type": "LoadBalancer"}}'`,
{ stdio: 'inherit' },
);
console.log('\u2705 Changed service type to "LoadBalancer"');

process.stdout.write('Getting argocd ip address...');
host = `https://${await promiseRetry(getExternalIp(namespace), { retries: 100, factor: 1, minTimeout: 5000 })}`;
console.log(`\n\u2705 Argocd ip address is ${host}`);
} catch (err) {
console.error(err.message);
process.exit(err.status);
}

// get autogenerated password
let autogenerated;
try {
console.log('Getting autogenerated password...');
autogenerated = cp.execSync(
`kubectl get pods -n "${namespace}" -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2 | xargs echo -n`,
{ encoding: 'utf-8' },
);
console.log('\u2705 Got autogenerated password');
} catch (err) {
console.error(err.message);
process.exit(err.status);
}

// update password
try {
console.log('Getting argocd token...');
const argocdToken = await rp({
method: 'POST',
uri: `${host}/api/v1/session`,
body: {
username: 'admin',
password: autogenerated,
},
json: true,
});
console.log('\u2705 Got argocd token');

console.log('Updating admin password...');
await rp({
method: 'PUT',
uri: `${host}/api/v1/account/password`,
headers: {
Authorization: `Bearer ${argocdToken.token}`,
},
body: {
currentPassword: autogenerated,
name: 'admin',
newPassword: password,
},
json: true,
});
console.log('\u2705 Updated admin password');
} catch (err) {
console.error(err.message);
process.exit(err.status);
}

return {
host,
};
}

module.exports = {
install,
};
63 changes: 46 additions & 17 deletions lib/interface/cli/commands/gitops/install.cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ const installRoot = require('../root/install.cmd');
const { detectProxy } = require('../../helpers/general');
const { downloadProvider } = require('../hybrid/helper');
const { Runner, components } = require('../../../../binary');
const { install: installArgocd } = require('./install-codefresh');

const installArgoCmd = new Command({
root: false,
parent: installRoot,
command: 'gitops <provider>',
description: 'Install gitops agent',
description: 'Install gitops',
webDocs: {
category: 'Gitops',
title: 'Install',
Expand All @@ -20,14 +21,14 @@ const installArgoCmd = new Command({
.env('CF_ARG_')
.positional('provider', {
describe: 'Gitops provider',
choices: ['argocd-agent'],
choices: ['codefresh', 'argocd-agent'],
required: true,
})
.option('git-integration', {
describe: 'Name of git integration in Codefresh',
})
.option('codefresh-integration', {
describe: 'Name of argocd integration in Codefresh',
describe: 'Name of gitops integration in Codefresh',
})
.option('argo-host', {
describe: 'Host of argocd installation',
Expand All @@ -36,13 +37,13 @@ const installArgoCmd = new Command({
describe: 'Token of argocd installation. Preferred auth method',
})
.option('argo-username', {
describe: 'Username of argocd installation. Should be used with argo-password',
describe: 'Username of existing argocd installation. Should be used with argo-password',
})
.option('argo-password', {
describe: 'Username of argocd installation. Should be used with argo-username',
describe: 'Password of existing argocd installation. Should be used with argo-username',
})
.option('update', {
describe: 'Update argocd integration if exists',
describe: 'Update gitops integration if exists',
})
.option('kube-config-path', {
describe: 'Path to kubeconfig file (default is $HOME/.kube/config)',
Expand Down Expand Up @@ -70,16 +71,41 @@ const installArgoCmd = new Command({
})
.option('https-proxy', {
describe: 'https proxy to be used in the runner',
})
// argocd options
.option('install-manifest', {
describe: 'Url of argocd install manifest',
default: 'https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml',
})
.option('set-argo-password', {
describe: 'Set password for admin user of new argocd installation',
}),
handler: async (argv) => {
let {
// eslint-disable-next-line prefer-const
'kube-config-path': kubeConfigPath,
// eslint-disable-next-line prefer-const
provider,
'http-proxy': httpProxy,
'https-proxy': httpsProxy,
} = argv;
let { provider, httpProxy, httpsProxy, argoHost, argoUsername, argoPassword } = argv;
const { kubeConfigPath, installManifest, kubeNamespace, setArgoPassword } = argv;

if (provider === 'codefresh') {
if (!setArgoPassword) {
console.error('\nMissing required argument: set-argo-password');
process.exit(1);
}

if (!kubeNamespace) {
console.error('\nMissing required argument: kube-namespace');
process.exit(1);
}

const result = await installArgocd({
installManifest,
kubeNamespace,
setArgoPassword,
});

provider = 'argocd-agent';
argoHost = result.host;
argoUsername = 'admin';
argoPassword = setArgoPassword;
}

const binLocation = await downloadProvider({ provider });
const componentRunner = new Runner(binLocation);
Expand All @@ -93,10 +119,13 @@ const installArgoCmd = new Command({
commands.push(kubeConfigPath);
}

const installOptions = _.pick(argv, ['git-integration', 'codefresh-integration', 'argo-host', 'argo-token', 'output',
'argo-username', 'argo-password', 'update', 'kube-context-name', 'kube-namespace', 'sync-mode', 'sync-apps']);
const installOptions = _.pick(argv, ['git-integration', 'codefresh-integration', 'argo-token', 'output',
'update', 'kube-context-name', 'kube-namespace', 'sync-mode', 'sync-apps']);
installOptions['argo-host'] = argoHost;
installOptions['argo-username'] = argoUsername;
installOptions['argo-password'] = argoPassword;

_.forEach(installOptions, (value, key) => {
_.forEach(_.pickBy(installOptions, _.identity), (value, key) => {
if (_.isArray(value)) {
value.forEach((item) => {
commands.push(`--${key}`);
Expand Down
87 changes: 87 additions & 0 deletions lib/interface/cli/commands/gitops/install.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const installCmd = require('./install.cmd').toCommand();
const { Runner } = require('../../../../binary');
const yargs = require('yargs');

jest.mock('./install-codefresh', () => ({
install: async () => ({ host: 'host' }),
}));

jest.mock('../hybrid/helper', () => ({
downloadProvider: async () => {},
}));

jest.mock('../../../../binary');

describe('install gitops', () => {
beforeEach(async () => {
Runner.mockClear();
});

it('install gitops argocd-agent w/o arguments', async () => {
const argv = { provider: 'argocd-agent' };
await installCmd.handler(argv);
const { calls } = Runner.mock.instances[0].run.mock;
expect(calls).toHaveLength(1);
const [component, commands] = calls[0];
expect(component.name).toEqual('gitops');
expect(commands).toEqual(['install']);
});

it('install gitops argocd-agent with arguments', async () => {
const argv = {
provider: 'argocd-agent',
'git-integration': 'gitIntegration',
'codefresh-integration': 'codefreshIntegration',
'kube-context-name': 'kubeContextName',
'kube-namespace': 'kubeNamespace',
'sync-mode': 'SELECT',
'sync-apps': 'syncApps',
};
await installCmd.handler(argv);
const { calls } = Runner.mock.instances[0].run.mock;
expect(calls).toHaveLength(1);
const [component, commands] = calls[0];
expect(component.name).toEqual('gitops');
expect(commands).toEqual([
'install',
'--git-integration',
'gitIntegration',
'--codefresh-integration',
'codefreshIntegration',
'--kube-context-name',
'kubeContextName',
'--kube-namespace',
'kubeNamespace',
'--sync-mode',
'SELECT',
'--sync-apps',
'syncApps',
]);
});

it('install gitops codefresh with required arguments', async () => {
const argv = {
provider: 'codefresh',
'set-argo-password': 'pass',
setArgoPassword: 'pass',
'kube-namespace': 'ns',
kubeNamespace: 'ns',
};
await installCmd.handler(argv);
const { calls } = Runner.mock.instances[0].run.mock;
expect(calls).toHaveLength(1);
const [component, commands] = calls[0];
expect(component.name).toEqual('gitops');
expect(commands).toEqual([
'install',
'--kube-namespace',
'ns',
'--argo-host',
'host',
'--argo-username',
'admin',
'--argo-password',
'pass',
]);
});
});
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codefresh",
"version": "0.73.32",
"version": "0.73.33",
"description": "Codefresh command line utility",
"main": "index.js",
"preferGlobal": true,
Expand Down Expand Up @@ -64,6 +64,7 @@
"mongodb": "^3.0.1",
"ora": "^3.0.0",
"prettyjson": "^1.2.1",
"promise-retry": "^2.0.1",
"recursive-readdir": "^2.2.1",
"request": "^2.88.0",
"request-promise": "^4.2.2",
Expand Down
18 changes: 18 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,11 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"

err-code@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==

error-ex@^1.2.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
Expand Down Expand Up @@ -5462,6 +5467,14 @@ [email protected], progress@^2.0.0, progress@~2.0.0:
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==

promise-retry@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22"
integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==
dependencies:
err-code "^2.0.2"
retry "^0.12.0"

prompts@^0.1.9:
version "0.1.14"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2"
Expand Down Expand Up @@ -5971,6 +5984,11 @@ retry@^0.10.0:
resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4"
integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=

retry@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=

rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
Expand Down

0 comments on commit cdbf0fd

Please sign in to comment.