Skip to content

Commit bb7fbf2

Browse files
Feature: functional interface
- Added functional interface logic: Re-added getAllByRepo() and getPipelineByNameAndRepo() - Various fixes to functional lib, as required by Tzatziki - Added showWorkflowLogs, restartWorkflow, terminateWorkflow, waitForWorkflows, installHelmChart Fixed up workflows, images, pipelines - and others that were out of date with the standard interface/cli/ - Made Helm repository description clearer - Fixed runPipelineById() and installHelmChart() in the functional interface Made installChart in the logic/api module not fail if the values is an empty array - Made showWorkflowLogs return true Made restartWorkflow work in parity to runPipelineById Made terminateWOrkflow return true Made waitForStatus return true
1 parent ba8cfa7 commit bb7fbf2

File tree

13 files changed

+1002
-2
lines changed

13 files changed

+1002
-2
lines changed

lib/interface/cli/commands/pipeline/dynamic/install-chart.cmd.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const install = new Command({
3333
.option('repository', {
3434
description: 'Helm repository (absolute url or name of context with type help-repository)',
3535
type: 'string',
36+
default: 'https://kubernetes-charts.storage.googleapis.com',
3637
required: true,
3738
})
3839
.option('name', {
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
require('debug')('codefresh:functional:functions:auth');
2+
3+
const CFError = require('cf-errors');
4+
const { auth } = require('../../../logic/index');
5+
const DEFAULTS = require('../defaults');
6+
7+
const { JWTContext, APIKeyContext } = auth.contexts;
8+
const authManager = auth.manager;
9+
10+
//--------------------------------------------------------------------------------------------------
11+
// Private
12+
//--------------------------------------------------------------------------------------------------
13+
14+
// eslint-disable-next-line no-unused-vars
15+
const _loginWithUserPassword = async (url, username, password) => {
16+
try {
17+
// TODO implement logic to get token by calling the pai
18+
} catch (err) {
19+
throw new CFError({
20+
cause: err,
21+
message: 'Failed to login with username and password',
22+
});
23+
}
24+
};
25+
26+
27+
const _loginWithToken = async (url, token) => {
28+
let authContext;
29+
try {
30+
authContext = JWTContext.createFromToken(token, url);
31+
return authContext;
32+
} catch (err) {
33+
try {
34+
authContext = APIKeyContext.createFromToken(token, url);
35+
return authContext;
36+
} catch (err2) {
37+
const error = new CFError({
38+
cause: err2,
39+
message: 'Failed to login with api key',
40+
});
41+
throw error;
42+
}
43+
}
44+
};
45+
46+
//--------------------------------------------------------------------------------------------------
47+
// Public
48+
//--------------------------------------------------------------------------------------------------
49+
50+
const getAllAuthContexts = async () => {
51+
const allAuthContexts = authManager.getAllContexts();
52+
53+
return allAuthContexts;
54+
};
55+
56+
const getCurrentAuthContext = async () => {
57+
const currentContext = authManager.getCurrentContext();
58+
if (currentContext) {
59+
return currentContext.getName();
60+
}
61+
62+
throw new CFError('There are no contexts in cfconfig file');
63+
};
64+
65+
const setCurrentAuthContext = async (name) => {
66+
const contextName = name;
67+
68+
const currentContextName = await getCurrentAuthContext();
69+
if (currentContextName === contextName) {
70+
// Context already set - do nothing
71+
return;
72+
}
73+
74+
75+
const context = authManager.getContextByName(contextName);
76+
if (context) {
77+
authManager.setCurrentContext(context);
78+
authManager.persistContexts();
79+
console.log(`Switched to context ${contextName}`);
80+
} else {
81+
throw new CFError(`No context exists with the name: ${contextName}`);
82+
}
83+
};
84+
85+
const createAuthContextWithLogin = async (username, password, url = DEFAULTS.URL) => {
86+
const authContext = await _loginWithUserPassword(username, password, url);
87+
88+
await authContext.validate();
89+
await authManager.addContext(authContext);
90+
await authManager.setCurrentContext(authContext);
91+
await authManager.persistContexts(authContext);
92+
93+
console.log(`Login succeeded to ${authContext.url}`);
94+
console.log(`Switched to context: ${authContext.name}`);
95+
};
96+
97+
98+
const createAuthContextWithToken = async (token, name, url = DEFAULTS.URL) => {
99+
// const type = JWTContext.TYPE;
100+
const authContext = await _loginWithToken(url, token);
101+
102+
await authContext.validate();
103+
104+
if (name) {
105+
authContext.setName(name);
106+
}
107+
108+
let updatedExistingContext = false;
109+
if (authManager.getContextByName(authContext.getName())) {
110+
updatedExistingContext = true;
111+
}
112+
113+
await authManager.addContext(authContext);
114+
await authManager.setCurrentContext(authContext);
115+
await authManager.persistContexts(authContext);
116+
117+
if (updatedExistingContext) {
118+
console.log(`Updated context: ${authContext.name}`);
119+
} else {
120+
console.log(`Created new context: ${authContext.name}`);
121+
}
122+
123+
console.log(`Switched to context: ${authContext.name}`);
124+
};
125+
126+
module.exports = {
127+
getAllAuthContexts,
128+
getCurrentAuthContext,
129+
setCurrentAuthContext,
130+
createAuthContextWithLogin,
131+
createAuthContextWithToken,
132+
};
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* eslint-disable prefer-destructuring */
2+
require('debug')('codefresh:functional:functions:composition');
3+
const CFError = require('cf-errors');
4+
const { composition } = require('../../../logic/index').api;
5+
6+
7+
//--------------------------------------------------------------------------------------------------
8+
// Private
9+
//--------------------------------------------------------------------------------------------------
10+
11+
//--------------------------------------------------------------------------------------------------
12+
// Public
13+
//--------------------------------------------------------------------------------------------------
14+
15+
const getComposition = async (name) => {
16+
if (!name) {
17+
throw new CFError('Missing name of the composition');
18+
}
19+
20+
return composition.getCompositionByIdentifier(name);
21+
};
22+
23+
const getAllCompositions = async () => composition.getCompositions();
24+
25+
const createComposition = async (
26+
name,
27+
envVarsDict = {},
28+
yamlFilePath = null,
29+
isAdvanced = false,
30+
) => {
31+
const data = {
32+
name,
33+
vars: envVarsDict,
34+
isAdvanced,
35+
};
36+
37+
if (yamlFilePath) {
38+
data.yamlJson = yamlFilePath;
39+
}
40+
41+
return composition.createComposition(data);
42+
};
43+
44+
const deleteComposition = async (name) => {
45+
const currComposition = await composition.getCompositionByIdentifier(name);
46+
const id = currComposition ? currComposition.info.id : null;
47+
if (!id) {
48+
throw new CFError(`Cannot found composition: ${name}`);
49+
}
50+
return composition.deleteCompositionById(id);
51+
};
52+
53+
const replaceComposition = async (name, newData) => {
54+
let id;
55+
56+
if (!name) {
57+
throw new CFError('Missing name of the composition');
58+
}
59+
60+
const currComposition = await composition.getCompositionByIdentifier(name);
61+
if (currComposition) {
62+
id = currComposition.info.id;
63+
}
64+
if (!id) {
65+
throw new CFError(`Cannot found composition: ${name}`);
66+
}
67+
68+
return composition.replaceById(id, newData);
69+
};
70+
71+
72+
module.exports = {
73+
getComposition,
74+
getAllCompositions,
75+
createComposition,
76+
deleteComposition,
77+
replaceComposition,
78+
};
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
require('debug')('codefresh:functional:functions:context');
2+
const CFError = require('cf-errors');
3+
const { context } = require('../../../logic/index').api;
4+
5+
//--------------------------------------------------------------------------------------------------
6+
// Private
7+
//--------------------------------------------------------------------------------------------------
8+
9+
//--------------------------------------------------------------------------------------------------
10+
// Public
11+
//--------------------------------------------------------------------------------------------------
12+
13+
const TYPE_CHOICES = [
14+
'config',
15+
'secret',
16+
'helm-repository',
17+
'helm-plain-text-values',
18+
'plain-yaml',
19+
'secret-yaml',
20+
];
21+
const OWNER_CHOICES = ['account', 'user'];
22+
23+
const getContext = async (name, owner = OWNER_CHOICES[0]) => {
24+
if (!name) {
25+
throw new CFError('Name must be provided');
26+
}
27+
28+
try {
29+
return context.getContextByName(name, owner);
30+
} catch (err) {
31+
throw new CFError({
32+
cause: err,
33+
message: `get context ${name} failed.`,
34+
});
35+
}
36+
};
37+
38+
const getAllContexts = async (type = null, owner = OWNER_CHOICES[0]) => {
39+
const data = {};
40+
if (type) {
41+
data.type = type;
42+
}
43+
if (owner) {
44+
data.owner = owner;
45+
}
46+
47+
try {
48+
return context.getContexts(data);
49+
} catch (err) {
50+
throw new CFError({
51+
cause: err,
52+
message: 'get contexts failed',
53+
});
54+
}
55+
};
56+
57+
58+
const createContext = async (name, type = null, owner = OWNER_CHOICES[0], envVarsDict = {}) => {
59+
if (!name) {
60+
throw new CFError('Name must be provided');
61+
}
62+
63+
const data = {
64+
apiVersion: 'v1',
65+
kind: 'context',
66+
owner,
67+
metadata: {
68+
name,
69+
},
70+
spec: {
71+
type,
72+
data: envVarsDict,
73+
},
74+
};
75+
76+
if (!data.metadata.name || !data.spec.type) {
77+
throw new CFError('Name and type must be provided');
78+
}
79+
80+
return context.createContext(data);
81+
};
82+
83+
const deleteContext = async (name, owner = OWNER_CHOICES[0]) => {
84+
if (!name) {
85+
throw new CFError('Name must be provided');
86+
}
87+
88+
return context.deleteContextByName(name, owner);
89+
};
90+
91+
const applyContext = async (name, data) => {
92+
if (!name) {
93+
throw new CFError('Name must be provided');
94+
}
95+
96+
try {
97+
await context.getContextByName(name);
98+
99+
return context.applyByName(name, data);
100+
} catch (err) {
101+
if (err) {
102+
return context.createContext(data);
103+
}
104+
throw err;
105+
}
106+
};
107+
108+
const replaceContext = async (name, newData) => {
109+
if (!name) {
110+
throw new CFError('Name must be provided');
111+
}
112+
113+
return context.replaceByName(name, newData);
114+
};
115+
116+
117+
module.exports = {
118+
getContext,
119+
getAllContexts,
120+
createContext,
121+
deleteContext,
122+
applyContext,
123+
replaceContext,
124+
125+
TYPE_CHOICES,
126+
OWNER_CHOICES,
127+
};

lib/interface/functional/defaults.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const DEFAULTS = {
2+
URL: 'https://g.codefresh.io',
3+
CFCONFIG: `${process.env.HOME}/.cfconfig`,
4+
DEBUG_PATTERN: 'codefresh',
5+
GET_LIMIT_RESULTS: 25,
6+
GET_PAGINATED_PAGE: 1,
7+
CODEFRESH_REGISTRIES: ['r.cfcr.io'],
8+
WATCH_INTERVAL_MS: 3000,
9+
MAX_CONSECUTIVE_ERRORS_LIMIT: 10,
10+
};
11+
12+
module.exports = DEFAULTS;

0 commit comments

Comments
 (0)