Skip to content
This repository was archived by the owner on Jan 30, 2022. It is now read-only.

Commit 1b49455

Browse files
authored
Bring pipeline-cli and nr-pipeline-ext into nrdk code base (js -> ts) (#84)
* Ported OpenShiftClient.js * Rename * src/pipeline-cli/util.ts - indentation * util.ts + name(), parseName() and isUrl() * OpenShiftClient.ts +ts conversion * +OpenShiftResourceSelector.ts * +OpenShiftStaticSelector.ts * OpenShiftClient - swap requires for imports * package.lock + debug, lodash.isstring, lodash.isplainobject and types * package-lock.json update * Renames for kebab-case * Renames for kebab-case * Cleaned up incomplete JSDoc and self=this * Source OpenShiftClient from local * openshift-client-ts +requires from pipeline-cli (still .js format) * is-openshift-list.ts converted * package.json + @types/lodash.isempty * is-openshift-result.ts converted * constants.ts converted * Added and converted logger.ts * logger.ts - revise export structure * utils.ts + hashString(), hashObject(), execSync() * transformers.ts converted * util.ts + export normalizeKind(), getBuildConfigStrategy(), hashDirector(), fullName() * openshift-client-x.ts converted * Typing and removing 'use stricts' (handled by tsconfig) * openshift-resource-selector.ts converted * package-lock.json + @types/lodash.isempty * Switch remaining pipeline-cli references to local * basic-java-application-clean.ts copied and converted * basic-functional-tester.ts copied and converted * Switch nr-pipeline-ext references to local * index.ts - replace one, remove four from @bcgov/nr-pipeline-ex imports * custom-error.ts copied and converted * constants.ts copied and converted * util-functions copied and converted * git-operation copied and converted * constants.ts + CONST export (instead of default) * Clean up remaining imports, general cleanup * src/pipeline-cli/index.ts + exports * +test/pipeline-cli/index.test.ts - checks against index * +test/nr-pipeline-ext/index.test.ts and src/.../index.ts * +openshift-client.test.ts - copied and converted, but only partially working * Finish polishing fns for copied openshift-client.test.ts * test/pipeline-cli/util.test.ts copied and converted * test/pipeline-cli/lib.test.ts copied and converted * src/pipeline-cli/util.ts +fns: isArray, isPlainObject, isString, parseArgumentsFromArray * +test/pipeline-cli/resources - consumed by tests * lib.test.ts - fixed bug emptying params * +openshift-client.e2e.test.ts (stuck pending) * +openshift-client-x.e2e.test.ts (stuck pending) * +openshift-client-x.test.ts (stuck on stubs/fakes) * Minor adjustments * openshift-client-x.ts fix null checks * test/nr-pipeline-ext - first pass for tests - copy, change to .ts and eslint --fix * unicorn-case renames * basic-java-application-clean.test.ts - finished up * test/tsconfig.json + include - fixes under-linting in test folders * util-functions.test.ts - finish up * Remove unnecessary or incomplete tests * util-functions.test.ts - fixed .skip * +test/nr-pipeline-ext/index.test.ts * pipeline-cli/openshift-client-x.test.ts rolled in lib.test.ts * tests/ - cleanup and skips * src/pipeline-cli/openshift-client-x.ts - cleanup * test/commands/on/jira.issue.tests.ts - remove imrt @gov/nr-pipeline-ext * Use src/error.ts instead of src/nr-pipeline-ext/custom-error.ts * Replaced nr-pipeline-ext/util-functions with util/util-functions * test/tsconfig.json - reverted changes * Remove unfinished pipeline-cli e2e tests * src/pipeline-cli/openshift-client.ts - clean up after js-ts conversion * src/pipeline-cli/openshift-client-result.ts - revise case * src/pipeline-cli/util.ts - clean up after js-ts conversion * src/pipeline-cli/openshift-client-x.ts - clean up after js-ts conversion * test/pipeline-cli/openshift-client-x.test.ts - small fixes, reenable/unskip last 3 tests * package.json - remove link script and dependencies * package.json, package-lock.json + lodash.isempty * Post-rebase cleanup * Update merge conflict
1 parent 19e20b0 commit 1b49455

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+5732
-1339
lines changed

package-lock.json

Lines changed: 1146 additions & 1205 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,22 @@
1919
"@aws-sdk/credential-provider-node": "^3.11.0",
2020
"@aws-sdk/protocol-http": "^3.10.0",
2121
"@aws-sdk/signature-v4": "^3.10.0",
22-
"@bcgov/nr-pipeline-ext": "0.1.0-rc.13",
23-
"@bcgov/pipeline-cli": "^1.0.1-2",
2422
"@oclif/command": "^1.8.0",
2523
"@oclif/plugin-help": "^3.2.0",
24+
"@types/lodash.isplainobject": "^4.0.6",
2625
"axios": "^0.21.1",
2726
"chalk": "^4.1.0",
2827
"cli-ux": "^5.5.0",
28+
"debug": "^4.2.0",
2929
"form-data": "^3.0.0",
3030
"inquirer": "^7.3.3",
3131
"isomorphic-git": "^1.7.8",
3232
"jira-connector": "^3.1.0",
3333
"jira.js": "^1.7.3",
3434
"keycloak-admin": "^1.14.10",
35+
"lodash.isempty": "^4.4.0",
36+
"lodash.isplainobject": "^4.0.6",
37+
"lodash.isstring": "^4.0.1",
3538
"lodash.merge": "^4.6.2",
3639
"rsync": "^0.6.1",
3740
"safe-buffer": "^5.2.1",
@@ -45,7 +48,10 @@
4548
"@oclif/dev-cli": "^1",
4649
"@oclif/test": "^1",
4750
"@types/chai": "^4.2.12",
51+
"@types/debug": "^4.1.5",
4852
"@types/inquirer": "^7.3.1",
53+
"@types/lodash.isempty": "^4.4.6",
54+
"@types/lodash.isstring": "^4.0.6",
4955
"@types/lodash.merge": "^4.6.6",
5056
"@types/mocha": "^8.0.3",
5157
"@types/node": "^12.19.1",
@@ -126,7 +132,6 @@
126132
"mocha": "mocha --timeout 9999999",
127133
"version": "oclif-dev readme && git add README.md",
128134
"oclif": "oclif",
129-
"link": "npm link @bcgov/nr-pipeline-ext && npm link @bcgov/pipeline-cli",
130135
"publish:latest": "npm --no-git-tag-version version prerelease && npm publish --tag latest",
131136
"publish:alpha": "npm --no-git-tag-version version prerelease && npm publish --tag alpha"
132137
},

src/commands/clean.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default class Clean extends BaseCommand {
2222
const {flags} = this.parse(Clean)
2323
await applyFlagDefaults(flags)
2424
const settings = loadConfigScript(flags)
25-
const {BasicJavaApplicationClean} = require('@bcgov/nr-pipeline-ext')
25+
const {BasicJavaApplicationClean} = await import('../nr-pipeline-ext/basic-java-application-clean')
2626
new BasicJavaApplicationClean(settings).clean()
2727
// const task = loadScript(flags, FlagNames.CLEAN_SCRIPT)
2828
// task(Object.assign(settings, {phase: settings.options.env}))

src/commands/functionaltest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default class FunctionalTest extends BaseCommand {
3131
const {flags} = this.parse(FunctionalTest)
3232
await applyFlagDefaults(flags)
3333
const settings = loadConfigScript(flags)
34-
const {BasicFunctionalTester} = require('@bcgov/nr-pipeline-ext')
34+
const {BasicFunctionalTester} = await import('../nr-pipeline-ext/basic-functional-tester')
3535
new BasicFunctionalTester(settings).runFunctionalTests()
3636
}
3737
}

src/index.ts

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,20 @@
1-
import {
2-
BasicJavaApplicationBuilder,
3-
BasicFunctionalTester,
4-
InputDeployerVerify,
5-
Liquibase,
6-
Jira,
7-
GitOperation,
8-
CONST,
9-
} from '@bcgov/nr-pipeline-ext'
10-
import {OpenShiftClient, OpenShiftClientX} from '@bcgov/pipeline-cli'
11-
import {BasicJavaApplicationDeployer} from './util/basic-java-application-deployer'
12-
import {SecretManager} from './api/service/secret-manager'
131
import {BasicBuilder} from './util/basic-builder'
142
import {BasicDeployer} from './util/basic-deployer'
3+
import {BasicFunctionalTester} from './nr-pipeline-ext/basic-functional-tester'
4+
import {BasicJavaApplicationDeployer} from './util/basic-java-application-deployer'
5+
import {CONST} from './nr-pipeline-ext/constants'
156
import {GeneralError as GenericError} from './error'
7+
import {GitOperation} from './nr-pipeline-ext/git-operation'
8+
import {OpenShiftClientX} from './pipeline-cli/openshift-client-x'
9+
import {OpenShiftClient} from './pipeline-cli/openshift-client'
10+
import {SecretManager} from './api/service/secret-manager'
1611
export {
1712
OpenShiftClient,
1813
OpenShiftClientX,
1914
BasicBuilder,
2015
BasicDeployer,
21-
BasicJavaApplicationBuilder,
2216
BasicJavaApplicationDeployer,
2317
BasicFunctionalTester,
24-
InputDeployerVerify,
25-
Liquibase,
26-
Jira,
2718
GitOperation,
2819
CONST,
2920
SecretManager,

src/main.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/* eslint-disable no-console */
2+
/**
3+
* Calling the script would expect to contain arguments of:
4+
* --env=[target environment],
5+
* --pr=[the pr number]
6+
*
7+
* Script assumes:
8+
* 'srcFolderName' = "functional-testing" to be the folder to contain source code for testing using "NodeJs".
9+
* 'runCommand': default running command for Node using npm to run
10+
* The two above can be configured from project's config.js file.
11+
*
12+
* Environment variables:
13+
* - TARGET_TESTING_URL: will be internally constructed from query route object to Openshift namespace, and
14+
* is exposed to test environment before running tests.
15+
* - TARGET_ENV: will also be exposed to test environment as specified from --env argument
16+
* - UITEST_SKIP: can be used to skip tests
17+
*/
18+
19+
import {OpenShiftClientX} from '../pipeline-cli/openshift-client-x'
20+
import * as fs from 'fs'
21+
import * as path from 'path'
22+
import * as util from 'util'
23+
const exec = util.promisify(require('child_process').exec)
24+
25+
export class BasicFunctionalTester {
26+
settings: any
27+
28+
constructor(settings: any) {
29+
this.settings = settings
30+
}
31+
32+
async runFunctionalTests() {
33+
const options = this.settings.options
34+
const targetEnv = options.env
35+
console.log(`Working under directory: ${process.cwd()}`)
36+
console.log(`Target environment: ${targetEnv}`)
37+
console.log('User arguments:', options)
38+
39+
const currentPhase = this.settings.phases[targetEnv]
40+
const oc = new OpenShiftClientX(Object.assign({namespace: currentPhase.namespace}, options))
41+
const routeSpce = oc.get('route', {
42+
selector: `app=${currentPhase.instance},env-id=${currentPhase.changeId},github-owner=${oc.git.owner}`,
43+
namespace: currentPhase.namespace,
44+
})[0].spec
45+
const targetUrl = ''.concat(
46+
routeSpce.tls.termination === 'edge' ? 'https' : 'http',
47+
'://',
48+
routeSpce.host,
49+
routeSpce.path
50+
)
51+
console.log(`Targeted URL for testing is retrived as: '${targetUrl}' for environment: ${targetEnv}`)
52+
53+
// current phase settings
54+
const uitestConfig = {
55+
srcFolderName: 'functional-testing', // default test folder name, relative to project folder
56+
skip: 'false', // default
57+
runCommand: 'npm ci && npm run headless-chrome-tests', // sample command
58+
env: Object.assign(
59+
{},
60+
{PATH: process.env.PATH, HOME: process.env.HOME},
61+
{TARGET_ENV: targetEnv, TARGET_TESTING_URL: targetUrl},
62+
{APPDATA: process.env.APPDATA}
63+
),
64+
}
65+
if (currentPhase.uitest !== undefined) {
66+
const userConfig = currentPhase.uitest
67+
uitestConfig.srcFolderName =
68+
userConfig.srcFolderName && userConfig.srcFolderName.trim() !== '' ?
69+
userConfig.srcFolderName :
70+
uitestConfig.srcFolderName
71+
uitestConfig.skip = process.env.UITEST_SKIP ? process.env.UITEST_SKIP : uitestConfig.skip
72+
uitestConfig.runCommand =
73+
userConfig.runCommand && userConfig.runCommand.trim() !== '' ?
74+
userConfig.runCommand :
75+
uitestConfig.runCommand
76+
userConfig.env ?
77+
Object.assign(uitestConfig.env, userConfig.env) :
78+
Object.assign(uitestConfig.env)
79+
}
80+
81+
if (uitestConfig.skip && uitestConfig.skip.trim() === 'true') {
82+
console.log('User UITEST_SKIP is set. Skipping functional tests.')
83+
} else {
84+
const testFolderDir = path.resolve(process.cwd(), `./${uitestConfig.srcFolderName}/`)
85+
console.log('Resolved Testing Folder Dir:', testFolderDir)
86+
fs.access(testFolderDir, function (error) {
87+
if (error) {
88+
console.error('Directory does not exist or no permission', error)
89+
throw error
90+
}
91+
})
92+
93+
console.log('Process environments: ', uitestConfig.env)
94+
console.log('Run Command: ', uitestConfig.runCommand)
95+
try {
96+
const {stdout} = await exec(`${uitestConfig.runCommand}`, {
97+
cwd: `${testFolderDir}`,
98+
env: uitestConfig.env,
99+
})
100+
console.log('Finished running test: \n', stdout)
101+
} catch (error) {
102+
console.error('Error: Command execution failed: ', error)
103+
throw error
104+
}
105+
}
106+
} // end of runFunctionalTests method
107+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import {OpenShiftClientX} from '../pipeline-cli/openshift-client-x'
2+
3+
export class BasicJavaApplicationClean {
4+
settings: any
5+
6+
constructor(settings: any) {
7+
this.settings = settings
8+
}
9+
10+
clean(): void {
11+
const settings = this.settings
12+
const env = settings.options.env.toLowerCase()
13+
const phases = settings.phases
14+
const options = settings.options
15+
const oc = new OpenShiftClientX(Object.assign({namespace: phases.build.namespace}, options))
16+
const targetPhase = this.getTargetPhases(env)
17+
18+
for (const t of targetPhase) {
19+
const phase = phases[t]
20+
const buildConfigs = oc.get('bc', {
21+
selector: `app=${phase.instance},env-id=${phase.changeId},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`,
22+
namespace: phase.namespace,
23+
})
24+
if (buildConfigs) {
25+
buildConfigs.forEach((bc: any) => {
26+
if (bc.spec.output.to.kind === 'ImageStreamTag') {
27+
oc.delete([`ImageStreamTag/${bc.spec.output.to.name}`], {
28+
'ignore-not-found': 'true',
29+
wait: 'true',
30+
namespace: phase.namespace,
31+
})
32+
}
33+
})
34+
}
35+
36+
const deploymentConfigs = oc.get('dc', {
37+
selector: `app=${phase.instance},env-id=${phase.changeId},env-name=${t},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`,
38+
namespace: phase.namespace,
39+
})
40+
if (deploymentConfigs) {
41+
deploymentConfigs.forEach((dc: any) => {
42+
dc.spec.triggers.forEach((trigger: any) => {
43+
if (
44+
trigger.type === 'ImageChange' &&
45+
trigger.imageChangeParams.from.kind === 'ImageStreamTag'
46+
) {
47+
oc.delete([`ImageStreamTag/${trigger.imageChangeParams.from.name}`], {
48+
'ignore-not-found': 'true',
49+
wait: 'true',
50+
namespace: phase.namespace,
51+
})
52+
}
53+
})
54+
})
55+
}
56+
57+
oc.raw('delete', ['all'], {
58+
selector: `app=${phase.instance},env-id=${phase.changeId},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`,
59+
wait: 'true',
60+
namespace: phase.namespace,
61+
})
62+
oc.raw('delete', ['pvc,Secret,configmap,endpoints,RoleBinding,role,ServiceAccount,Endpoints'], {
63+
selector: `app=${phase.instance},env-id=${phase.changeId},!shared,github-repo=${oc.git.repository},github-owner=${oc.git.owner}`,
64+
wait: 'true',
65+
namespace: phase.namespace,
66+
})
67+
}
68+
} // end clean()
69+
70+
// /**
71+
// * Obtaining the target (phases) to clean up based on passed user argument 'env'.
72+
// * @param {string} env user passed argument for environment(s) to be cleaned.
73+
// * @returns Array(string) of targeted environments.
74+
// */
75+
getTargetPhases(env: string): string[] {
76+
const targetPhase = []
77+
const phases = this.settings.phases
78+
for (const phase in phases) {
79+
if (env.match(/^(all|transient)$/) && phases[phase].transient) {
80+
targetPhase.push(phase)
81+
} else if (env === phase) {
82+
targetPhase.push(phase)
83+
break
84+
}
85+
}
86+
87+
return targetPhase
88+
} // end getTargetPhases()
89+
} // end class

src/nr-pipeline-ext/constants.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
export const ISSUE_TYPE_CODE = Object.freeze({RFD: 'RFD', RFD_SUBTASK: 'RFD-subtask'})
2+
3+
export const ISSUE_LINK_TYPE_NAME = Object.freeze({RFC_FRD: 'RFC-RFD'})
4+
5+
export const ENV = Object.freeze({BUILD: 'build', DEV: 'dev', DLVR: 'dlvr', TEST: 'test', PROD: 'prod'})
6+
7+
export const JIRA_TARGET_ENV = Object.freeze({DLVR: 'DLVR', TEST: 'TEST', PROD: 'PROD'})
8+
9+
export const JIRA_ENV_REVIEWER = Object.freeze([
10+
Object.freeze({ENV: JIRA_TARGET_ENV.DLVR, REVIEWER: 'Developer'}),
11+
Object.freeze({ENV: JIRA_TARGET_ENV.TEST, REVIEWER: 'IIT'}),
12+
Object.freeze({ENV: JIRA_TARGET_ENV.PROD, REVIEWER: 'Business'}),
13+
])
14+
15+
export const DB_ACTION = Object.freeze({BACKUP: 'backup', RECOVERY: 'recovery'})
16+
17+
export const VERIFY_STATUS = Object.freeze({READY: 'Ready', NOT_READY: 'Not Ready'})
18+
19+
export const REASON = Object.freeze({
20+
REASON_CODE_RFD_BLOCKED: 'RFD_BLOCKED',
21+
REASON_DESC_RFD_BLOCKED: 'RFD(s) are blocked',
22+
REASON_CODE_RFD_NOT_APPROVED: 'RFD_NOT_APPROVED',
23+
REASON_DESC_RFD_NOT_APPROVED: 'RFD(s) are not approved',
24+
REASON_CODE_PREVIOUS_RFD_NOT_CLOSED: 'PREVIOUS_RFD_NOT_CLOSED',
25+
REASON_DESC_PREVIOUS_RFD_NOT_CLOSED: 'Previous stage RFD(s) are not closed',
26+
REASON_CODE_RFC_NOT_AUTHORIZED: 'RFC_NOT_AUTHORIZED',
27+
REASON_DESC_RFC_NOT_AUTHORIZED: 'RFC is not authorized to target environment',
28+
})
29+
30+
export const CONST = {
31+
ISSUE_TYPE_CODE: ISSUE_TYPE_CODE,
32+
ISSUE_LINK_TYPE_NAME: ISSUE_LINK_TYPE_NAME,
33+
ENV: ENV,
34+
JIRA_TARGET_ENV: JIRA_TARGET_ENV,
35+
JIRA_ENV_REVIEWER: JIRA_ENV_REVIEWER,
36+
DB_ACTION: DB_ACTION,
37+
VERIFY_STATUS: VERIFY_STATUS,
38+
REASON: REASON,
39+
}

0 commit comments

Comments
 (0)