Merge pull request #12617 from getndazn/feat/scaffolder-run-task-auditlog
feat: scaffolder run task auditlog
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
Introduced audit log message when a new scaffolder task is created
|
||||
@@ -35,24 +35,25 @@ import {
|
||||
UrlReaders,
|
||||
} from '@backstage/backend-common';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import ObservableImpl from 'zen-observable';
|
||||
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
import express from 'express';
|
||||
import request from 'supertest';
|
||||
import ObservableImpl from 'zen-observable';
|
||||
|
||||
/**
|
||||
* TODO: The following should import directly from the router file.
|
||||
* Due to a circular dependency between this plugin and the
|
||||
* plugin-scaffolder-backend-module-cookiecutter plugin, it results in an error:
|
||||
* TypeError: _pluginscaffolderbackend.createTemplateAction is not a function
|
||||
*/
|
||||
import { createRouter, DatabaseTaskStore, TaskBroker } from '../index';
|
||||
import { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';
|
||||
import {
|
||||
parseEntityRef,
|
||||
stringifyEntityRef,
|
||||
UserEntity,
|
||||
} from '@backstage/catalog-model';
|
||||
import { createRouter, DatabaseTaskStore, TaskBroker } from '../index';
|
||||
import { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';
|
||||
|
||||
function createDatabase(): PluginDatabaseManager {
|
||||
return DatabaseManager.fromConfig(
|
||||
@@ -74,6 +75,7 @@ const mockUrlReader = UrlReaders.default({
|
||||
|
||||
describe('createRouter', () => {
|
||||
let app: express.Express;
|
||||
let loggerSpy: jest.SpyInstance;
|
||||
let taskBroker: TaskBroker;
|
||||
const catalogClient = { getEntityByRef: jest.fn() } as unknown as CatalogApi;
|
||||
|
||||
@@ -133,9 +135,10 @@ describe('createRouter', () => {
|
||||
jest.spyOn(taskBroker, 'get');
|
||||
jest.spyOn(taskBroker, 'list');
|
||||
jest.spyOn(taskBroker, 'event$');
|
||||
loggerSpy = jest.spyOn(logger, 'info');
|
||||
|
||||
const router = await createRouter({
|
||||
logger: getVoidLogger(),
|
||||
logger: logger,
|
||||
config: new ConfigReader({}),
|
||||
database: createDatabase(),
|
||||
catalogClient,
|
||||
@@ -288,6 +291,48 @@ describe('createRouter', () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should emit auditlog containing without user identifier when no backstage auth is passed', async () => {
|
||||
await request(app)
|
||||
.post('/v2/tasks')
|
||||
.send({
|
||||
templateRef: stringifyEntityRef({
|
||||
kind: 'template',
|
||||
name: 'create-react-app-template',
|
||||
}),
|
||||
values: {
|
||||
required: 'required-value',
|
||||
},
|
||||
});
|
||||
|
||||
expect(loggerSpy).toHaveBeenCalledTimes(1);
|
||||
expect(loggerSpy).toHaveBeenCalledWith(
|
||||
'Scaffolding task for template:default/create-react-app-template',
|
||||
);
|
||||
});
|
||||
|
||||
it('should emit auditlog containing user identifier when backstage auth is passed', async () => {
|
||||
const mockToken =
|
||||
'blob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvZ3Vlc3QiLCJuYW1lIjoiSm9obiBEb2UifQ.blob';
|
||||
|
||||
await request(app)
|
||||
.post('/v2/tasks')
|
||||
.set('Authorization', `Bearer ${mockToken}`)
|
||||
.send({
|
||||
templateRef: stringifyEntityRef({
|
||||
kind: 'template',
|
||||
name: 'create-react-app-template',
|
||||
}),
|
||||
values: {
|
||||
required: 'required-value',
|
||||
},
|
||||
});
|
||||
|
||||
expect(loggerSpy).toHaveBeenCalledTimes(1);
|
||||
expect(loggerSpy).toHaveBeenCalledWith(
|
||||
'Scaffolding task for template:default/create-react-app-template created by user:default/guest',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /v2/tasks', () => {
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
import { PluginDatabaseManager, UrlReader } from '@backstage/backend-common';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import {
|
||||
Entity,
|
||||
parseEntityRef,
|
||||
stringifyEntityRef,
|
||||
UserEntity,
|
||||
} from '@backstage/catalog-model';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Config, JsonObject } from '@backstage/config';
|
||||
import { InputError, NotFoundError, stringifyError } from '@backstage/errors';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import {
|
||||
TemplateEntityV1beta3,
|
||||
TaskSpec,
|
||||
TemplateEntityV1beta3,
|
||||
templateEntityV1beta3Validator,
|
||||
} from '@backstage/plugin-scaffolder-common';
|
||||
import { JsonValue } from '@backstage/types';
|
||||
@@ -35,8 +35,8 @@ import express from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
import { validate } from 'jsonschema';
|
||||
import { Logger } from 'winston';
|
||||
import { TemplateFilter } from '../lib';
|
||||
import { z } from 'zod';
|
||||
import { TemplateFilter } from '../lib';
|
||||
import {
|
||||
createBuiltinActions,
|
||||
DatabaseTaskStore,
|
||||
@@ -47,7 +47,7 @@ import {
|
||||
} from '../scaffolder';
|
||||
import { createDryRunner } from '../scaffolder/dryrun';
|
||||
import { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';
|
||||
import { getEntityBaseUrl, getWorkingDirectory, findTemplate } from './helpers';
|
||||
import { findTemplate, getEntityBaseUrl, getWorkingDirectory } from './helpers';
|
||||
|
||||
/**
|
||||
* RouterOptions
|
||||
@@ -193,6 +193,12 @@ export async function createRouter(
|
||||
? await catalogClient.getEntityByRef(userEntityRef, { token })
|
||||
: undefined;
|
||||
|
||||
let auditLog = `Scaffolding task for ${templateRef}`;
|
||||
if (userEntityRef) {
|
||||
auditLog += ` created by ${userEntityRef}`;
|
||||
}
|
||||
logger.info(auditLog);
|
||||
|
||||
const values = req.body.values;
|
||||
|
||||
const template = await findTemplate({
|
||||
|
||||
Reference in New Issue
Block a user