Skip to content

Commit

Permalink
fix: add support for merging boms using cyclonedx-cli
Browse files Browse the repository at this point in the history
  • Loading branch information
logicflakes committed Apr 22, 2024
1 parent b780d75 commit 87e984e
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
10 changes: 10 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ ARG CI_ENV=noci
ARG GIT_COMMIT=git_commit_undefined
ARG GIT_BRANCH=git_branch_undefined
ARG VERSION=not_versioned
ARG TARGETARCH
ARG TARGETOS
ARG CYCLONE_DX_CLI_VERSION=v0.25.0
RUN if [ "$TARGETARCH" = "amd64" ]; then \
wget https://github.com/CycloneDX/cyclonedx-cli/releases/download/${CYCLONE_DX_CLI_VERSION}/cyclonedx-linux-x64 ;\
mv cyclonedx-linux-x64 /bin//cyclonedx-cli ;\
elif [ "$TARGETARCH" = "arm64" ]; then \
wget https://github.com/CycloneDX/cyclonedx-cli/releases/download/${CYCLONE_DX_CLI_VERSION}/cyclonedx-${TARGETOS}-${TARGETARCH} ;\
mv cyclonedx-${TARGETOS}-${TARGETARCH} /bin//cyclonedx-cli ;\
fi
RUN mkdir /app
RUN echo "version=$VERSION" > /app/version && echo "commit=$GIT_COMMIT" >> /app/version && echo "branch=$GIT_BRANCH" >> /app/version
WORKDIR /app
Expand Down
33 changes: 32 additions & 1 deletion backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const typeDefs = gql`
allBoms: [Bom]
findBom(bomSearch: BomSearch): [Bom]
bomById(id: ID): Object
mergeBoms(ids: [ID]!, group: String!, name: String!, version: String!): Object
}
type Mutation {
Expand Down Expand Up @@ -106,6 +107,13 @@ const typeDefs = gql`
offset: Int
}
input BomMerge {
ids: ID,
version: String,
name: String,
group: String
}
scalar Object
scalar DateTime
`;
Expand All @@ -129,6 +137,14 @@ const resolvers = {
retObj = byIdRows.rows[0].bom
}
return retObj
},
mergeBoms: async (parent: any, mergeInput: any) : Promise<Object| null> => {
let queryRes = await utils.runQuery(`select * from rebom.boms where uuid::text in ('` + mergeInput.ids.join('\',\'') + `')`)
let boms = queryRes.rows as BomRecord[]
var mergedBom = null
if(boms.length)
mergedBom = mergeBoms(boms, mergeInput.group, mergeInput.name, mergeInput.version)
return mergedBom
}
},
Mutation: {
Expand Down Expand Up @@ -325,4 +341,19 @@ async function startApolloServer(typeDefs: any, resolvers: any) {
console.log(`🚀 Server ready at http://localhost:4000`);
}

startApolloServer(typeDefs, resolvers)
async function mergeBoms(boms :BomRecord[], group: String, name: String, version: String): Promise<Object> {
const bomPaths: String[] = await utils.createTmpFiles(boms.map(bom => bom.bom))

const response: Object = await utils.shellExec('cyclonedx-cli', ['merge',
'--output-format', 'json',
'--input-format', 'json',
'--group', group,
'--name', name,
'--version', version,
'--input-files', ...bomPaths
])
utils.deleteTmpFiles(bomPaths)
return response
}

startApolloServer(typeDefs, resolvers)
52 changes: 52 additions & 0 deletions backend/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
const pg = require('pg')
const { spawn } = require('node:child_process')
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';

// init db
const pool = new pg.Pool({
Expand Down Expand Up @@ -26,4 +30,52 @@ export async function runQuery (query: string, params: string[]) : Promise<any>
// just in case the error handling itself throws an error.
client.release()
}
}

export async function shellExec(cmd: string, args: any[], timeout?: number): Promise<string> { // timeout = in ms
return new Promise((resolve, reject) => {
let options: any = {}
if (timeout) options.timeout = timeout
const child = spawn(cmd, args, options)
let resData = ""
child.stdout.on('data', (data: string)=> {
resData += data
})

child.stderr.on('data', (data: any) => {
console.error(`shell command error: ${data}`)
})

child.on('exit', (code: number) => {
if (code !== 0) console.log(`shell process exited with code ${code}`)
if (code === 0) {
if (resData) {
resData = resData.replace(/\n$/, "")
}
resolve(resData)
} else {
console.error(resData)
reject(resData)
}
})
})
}

export async function createTmpFiles(dataArr: any[]): Promise<string[]> {
const tmpDir = os.tmpdir();
const filePaths: string[] = [];

for (const data of dataArr) {
const tmpFilePath = path.join(tmpDir, `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`);
await fs.promises.writeFile(tmpFilePath, JSON.stringify(data));
filePaths.push(tmpFilePath);
}

return filePaths;
}

export async function deleteTmpFiles(filePaths: string[]): Promise<void> {
for (const filePath of filePaths) {
await fs.promises.unlink(filePath);
}
}

0 comments on commit 87e984e

Please sign in to comment.