Skip to content

Commit

Permalink
feat: build/install checksum link (#134)
Browse files Browse the repository at this point in the history
* feat: build/install checksum link
* feat: add artifact api
* feat: update dependencies
  • Loading branch information
mbystedt authored Nov 21, 2023
1 parent 3cbdd7c commit 7790688
Show file tree
Hide file tree
Showing 23 changed files with 863 additions and 422 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ lerna-debug.log*
/env-prod.hcl
/scripts/db/mongo-setup-ext.js
/scripts/setenv-common.sh
/scripts/provision-app-quick-build.artifact.sha256
/scripts/provision-app-quick-build.trace.id
507 changes: 327 additions & 180 deletions package-lock.json

Large diffs are not rendered by default.

30 changes: 16 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nr-broker",
"version": "5.4.1",
"version": "5.5.0",
"description": "",
"author": "",
"private": true,
Expand All @@ -19,17 +19,18 @@
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
"test:e2e": "jest --config ./test/jest-e2e.json",
"typeorm": "typeorm-ts-node-commonjs"
},
"dependencies": {
"@aws-sdk/client-kinesis": "^3.451.0",
"@aws-sdk/client-kinesis": "^3.454.0",
"@nestjs/axios": "^3.0.1",
"@nestjs/common": "^10.2.8",
"@nestjs/common": "^10.2.10",
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.2.8",
"@nestjs/core": "^10.2.10",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.2",
"@nestjs/platform-express": "^10.2.8",
"@nestjs/platform-express": "^10.2.10",
"@nestjs/schedule": "^4.0.0",
"@nestjs/serve-static": "^4.0.0",
"@nestjs/swagger": "^7.1.16",
Expand All @@ -53,29 +54,30 @@
"reflect-metadata": "^0.1.13",
"rimraf": "^5.0.5",
"rxjs": "^7.8.1",
"snakecase-keys": "^5.5.0",
"typeorm": "^0.3.17",
"uuid": "^9.0.1"
},
"devDependencies": {
"@golevelup/ts-jest": "^0.4.0",
"@nestjs/cli": "^10.2.1",
"@nestjs/schematics": "^10.0.3",
"@nestjs/testing": "^10.2.8",
"@nestjs/testing": "^10.2.10",
"@types/cron": "^2.4.0",
"@types/ejs": "^3.1.5",
"@types/express": "^4.17.21",
"@types/express-session": "^1.17.10",
"@types/jest": "^29.5.8",
"@types/jest": "^29.5.9",
"@types/lodash.merge": "^4.6.9",
"@types/node": "^20.9.0",
"@types/passport": "^1.0.15",
"@types/node": "^20.9.3",
"@types/passport": "^1.0.16",
"@types/passport-http": "^0.3.11",
"@types/passport-jwt": "^3.0.13",
"@types/supertest": "^2.0.16",
"@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^6.11.0",
"@typescript-eslint/parser": "^6.11.0",
"eslint": "^8.53.0",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.12.0",
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"jest": "^29.7.0",
Expand All @@ -86,7 +88,7 @@
"ts-loader": "^9.5.1",
"ts-node": "^10.0.0",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.2.2"
"typescript": "^5.3.2"
},
"jest": {
"moduleFileExtensions": [
Expand Down
7 changes: 6 additions & 1 deletion scripts/provision-app-quick-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
cd "$this_dir"

BUILD_VERSION="12.0.3"
sha256=($(echo $RANDOM $RANDOM $RANDOM | shasum -a 256))
echo -n $sha256 > provision-app-quick-build.artifact.sha256
echo "sha256: $sha256"

echo "===> Intention open"
# Open intention
Expand All @@ -25,6 +28,8 @@ fi

# Save intention token for later
INTENTION_TOKEN=$(echo $RESPONSE | jq -r '.token')
BUILD_TRACE_ID=$(echo $RESPONSE | jq -r '.actions.build.trace_id')
echo -n $BUILD_TRACE_ID > provision-app-quick-build.trace.id
# echo "Hashed transaction.id: $(echo -n $INTENTION_TOKEN | shasum -a 256)"

echo "===> Build"
Expand All @@ -37,7 +42,7 @@ ACTIONS_BUILD_TOKEN=$(echo $RESPONSE | jq -r '.actions.build.token')
curl -s -X POST $BROKER_URL/v1/intention/action/artifact \
-H 'Content-Type: application/json' \
-H 'X-Broker-Token: '"$ACTIONS_BUILD_TOKEN"'' \
-d '{"checksum": "sha256:1db1bf6ca413a9294ab0348fa8193d6646a8f201ebd8ac3a3de373d712900636", "name": "build.zip", "size": 1234 }'
-d '{"checksum": "sha256:'$sha256'", "name": "build.zip", "size": '$RANDOM', "type": "zip" }'

echo "===> Intention close"

Expand Down
25 changes: 25 additions & 0 deletions scripts/provision-app-quick-install.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"event": {
"provider": "github-action-demo",
"reason": "Job triggered",
"url": "JOB_URL"
},
"actions": [
{
"action": "package-installation",
"id": "install",
"provision": [],
"service": {
"project": "superapp",
"name": "superapp-backend",
"environment": "development"
},
"package": {
"type": "zip"
}
}
],
"user": {
"name": "USER_ID@IDP"
}
}
41 changes: 41 additions & 0 deletions scripts/provision-app-quick-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
[ -n "$ZSH_VERSION" ] && this_dir=$(dirname "${(%):-%x}") \
|| this_dir=$(dirname "${BASH_SOURCE[0]:-$0}")
cd "$this_dir"

BUILD_CHECKSUM="sha256:$(cat provision-app-quick-build.artifact.sha256)"
echo $BUILD_CHECKSUM
BUILD_GUID="$(cat provision-app-quick-build.trace.id)"
echo $BUILD_GUID

echo "===> Intention open"
# Open intention
RESPONSE=$(curl -s -X POST $BROKER_URL/v1/intention/open?ttl=30\&quickstart=true \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $BROKER_JWT" \
-d @<(cat provision-app-quick-install.json | \
jq ".event.url=\"http://sample.com/job\" | \
.user.name=\"hgoddard@idp\" | \
(.actions[] | select(.id == \"install\") .package.buildGuid) |= \"$BUILD_GUID\" | \
" \
))
echo "$BROKER_URL/v1/intention/open:"
echo $RESPONSE | jq '.'
if [ "$(echo $RESPONSE | jq '.error')" != "null" ]; then
echo "Exit: Error detected"
exit 0
fi

# Save intention token for later
INTENTION_TOKEN=$(echo $RESPONSE | jq -r '.token')
# echo "Hashed transaction.id: $(echo -n $INTENTION_TOKEN | shasum -a 256)"

echo "===> Install"

# Not shown: Install superapp
echo "===> ..."
echo "===> Install - Success!"
echo "===> Intention close"

# Use saved intention token to close intention
curl -s -X POST $BROKER_URL/v1/intention/close -H 'X-Broker-Token: '"$INTENTION_TOKEN"''
2 changes: 1 addition & 1 deletion scripts/setenv-backend-dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export ACTION_VALIDATE_TEAM_DBA=64fa194693b3afd6ee63aa99

export HOSTNAME=nr-broker-app-0

export NESTJS_UI_ROOT_PATH=ui/dist/ui/browser
export NESTJS_UI_ROOT_PATH=../ui/dist/ui/browser
export NESTJS_HELMET_HSTS=off

export OAUTH2_CLIENT_REGISTRATION_LOGIN_REDIRECT_URI=http://localhost:3000/auth/callback
Expand Down
5 changes: 3 additions & 2 deletions src/audit/audit.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { BadRequestException, HttpException, Injectable } from '@nestjs/common';
import { from, map } from 'rxjs';
import merge from 'lodash.merge';
import os from 'os';
import snakecaseKeys from 'snakecase-keys';

import { ActionDto } from '../intention/dto/action.dto';
import { IntentionDto } from '../intention/dto/intention.dto';
Expand Down Expand Up @@ -524,10 +525,10 @@ export class AuditService {
? action.service.target.project
: action.service.project,
},
package: {
package: snakecaseKeys({
...(artifact ?? {}),
...(action.package ?? {}),
},
}),
service: {
target: {
name: action.service.name,
Expand Down
2 changes: 1 addition & 1 deletion src/graph/graph.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { CollectionDtoUnion } from '../persistence/dto/collection-dto-union.type
import { validate } from 'class-validator';
import { ValidatorUtil } from '../util/validator.util';
import { get, set } from 'radash';
import { CollectionConfigDto } from 'src/persistence/dto/collection-config.dto';
import { CollectionConfigDto } from '../persistence/dto/collection-config.dto';

@Injectable()
export class GraphService {
Expand Down
31 changes: 31 additions & 0 deletions src/intention/action.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { UserDto } from '../persistence/dto/user.dto';
import { UserCollectionService } from '../collection/user-collection.service';
import { PersistenceUtilService } from '../persistence/persistence-util.service';
import { PackageInstallationActionDto } from './dto/package-installation-action.dto';
import { IntentionRepository } from '../persistence/interfaces/intention.repository';

/**
* Assists with the validation of intention actions
Expand All @@ -27,6 +28,7 @@ export class ActionService {
private readonly collectionRepository: CollectionRepository,
private readonly userCollectionService: UserCollectionService,
private readonly graphRepository: GraphRepository,
private readonly intentionRepository: IntentionRepository,
private readonly persistenceUtil: PersistenceUtilService,
) {}

Expand Down Expand Up @@ -66,6 +68,35 @@ export class ActionService {
}
}

public async annotate(action: ActionDto) {
if (action.action === 'package-installation') {
if (action.package) {
const foundArtifact = await this.intentionRepository.searchArtifacts(
action.package.buildGuid,
action.package.checksum,
action.package.name,
action.package.type,
action.service.name,
0,
1,
);
if (
foundArtifact.meta.total !== 1 &&
foundArtifact.artifacts.length !== 1
) {
// Skip: Could not uniquely identify artifact based on package
return;
}

action.package = {
...(foundArtifact.artifacts[0].action.package ?? {}),
...foundArtifact.artifacts[0].artifact,
...action.package,
};
}
}
}

public async validate(
intention: IntentionDto,
action: ActionDto,
Expand Down
31 changes: 31 additions & 0 deletions src/intention/dto/artifact-search-query.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Type } from 'class-transformer';
import { IsInt, IsOptional, IsString } from 'class-validator';

export class ArtifactSearchQuery {
@IsString()
@IsOptional()
buildGuid?: string;

@IsString()
@IsOptional()
checksum?: string;

@IsString()
@IsOptional()
name?: string;

@IsString()
service: string;

@IsInt()
@Type(() => Number)
offset: number;

@IsString()
@IsOptional()
type?: string;

@IsInt()
@Type(() => Number)
limit: number;
}
17 changes: 17 additions & 0 deletions src/intention/dto/artifact-search-result.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Shared DTO: Copy in back-end and front-end should be identical

import { ActionDto } from './action.dto';
import { ArtifactDto } from './artifact.dto';
import { IntentionDto } from './intention.dto';

export class ArtifactActionCombo {
action!: ActionDto;
artifact!: ArtifactDto;
}
export class ArtifactSearchResult {
data!: IntentionDto[];
artifacts!: ArtifactActionCombo[];
meta!: {
total: number;
};
}
5 changes: 5 additions & 0 deletions src/intention/dto/artifact.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,9 @@ export class ArtifactDto {
@IsDefined()
@IsNumber()
size: number;

@Column()
@IsDefined()
@IsString()
type: string;
}
1 change: 1 addition & 0 deletions src/intention/dto/intention.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { ServerAccessActionDto } from './server-access-action.dto';
import { UrlDto } from './url.dto';

@Entity({ name: 'intention' })
// @Index(['actions.transaction.hash'])
export class IntentionDto {
static projectAction(
intention: IntentionDto,
Expand Down
13 changes: 12 additions & 1 deletion src/intention/dto/package.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ export class PackageDto {
@Column()
architecture?: string;

@IsString()
@IsOptional()
@Column()
buildGuid?: string;

@IsNumber()
@IsOptional()
@Column()
buildNumber?: number;

@IsString()
@IsOptional()
@Column()
Expand Down Expand Up @@ -59,6 +69,7 @@ export class PackageDto {
type?: string;

@IsString()
@IsOptional()
@Column()
version: string;
version?: string;
}
Loading

0 comments on commit 7790688

Please sign in to comment.