diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts index 8ee98f5d20..5d169a73fd 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts @@ -95,10 +95,13 @@ export function createCatalogRegisterAction(options: { ctx.logger.info(`Registering ${catalogInfoUrl} in the catalog`); - const result = await catalogClient.addLocation({ - type: 'url', - target: catalogInfoUrl, - }); + const result = await catalogClient.addLocation( + { + type: 'url', + target: catalogInfoUrl, + }, + ...(ctx.token ? [{ token: ctx.token }] : []), + ); if (result.entities.length >= 1) { const { kind, name, namespace } = getEntityName(result.entities[0]); ctx.output('entityRef', `${kind}:${namespace}/${name}`); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts index fdc403ec65..1f1228baf8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts @@ -127,7 +127,7 @@ export class DatabaseTaskStore implements TaskStore { try { const spec = JSON.parse(task.spec); - const secrets = task.secrets ? JSON.parse(task.spec) : undefined; + const secrets = task.secrets ? JSON.parse(task.secrets) : undefined; return { id: task.id, spec, @@ -219,7 +219,7 @@ export class DatabaseTaskStore implements TaskStore { }) .update({ status, - secrets: undefined, + secrets: null as any, }); if (updateCount !== 1) { throw new ConflictError( diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts index fd2de30332..4a025c25e2 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts @@ -21,7 +21,7 @@ import { import { ConfigReader } from '@backstage/config'; import { DatabaseTaskStore } from './DatabaseTaskStore'; import { StorageTaskBroker, TaskAgent } from './StorageTaskBroker'; -import { TaskSpec, DbTaskEventRow } from './types'; +import { TaskSecrets, TaskSpec, DbTaskEventRow } from './types'; async function createStore(): Promise { const manager = SingleConnectionDatabaseManager.fromConfig( @@ -39,6 +39,7 @@ async function createStore(): Promise { describe('StorageTaskBroker', () => { let storage: DatabaseTaskStore; + const fakeSecrets = { identityToken: 'secret' } as TaskSecrets; beforeAll(async () => { storage = await createStore(); @@ -78,6 +79,13 @@ describe('StorageTaskBroker', () => { await expect(taskC.spec.steps[0].id).toBe('c'); }); + it('should store secrets', async () => { + const broker = new StorageTaskBroker(storage, logger); + await broker.dispatch({} as TaskSpec, fakeSecrets); + const task = await broker.claim(); + expect(task.secrets).toEqual(fakeSecrets); + }, 10000); + it('should complete a task', async () => { const broker = new StorageTaskBroker(storage, logger); const dispatchResult = await broker.dispatch({} as TaskSpec); @@ -87,6 +95,16 @@ describe('StorageTaskBroker', () => { expect(taskRow.status).toBe('completed'); }, 10000); + it('should remove secrets after completing a task', async () => { + const broker = new StorageTaskBroker(storage, logger); + const dispatchResult = await broker.dispatch({} as TaskSpec, fakeSecrets); + const task = await broker.claim(); + await task.complete('completed'); + const taskRow = await storage.getTask(dispatchResult.taskId); + expect(taskRow.status).toBe('completed'); + expect(taskRow.secrets).toBeUndefined(); + }, 10000); + it('should fail a task', async () => { const broker = new StorageTaskBroker(storage, logger); const dispatchResult = await broker.dispatch({} as TaskSpec); @@ -96,6 +114,16 @@ describe('StorageTaskBroker', () => { expect(taskRow.status).toBe('failed'); }); + it('should remove secrets afteer failing a task', async () => { + const broker = new StorageTaskBroker(storage, logger); + const dispatchResult = await broker.dispatch({} as TaskSpec, fakeSecrets); + const task = await broker.claim(); + await task.complete('failed'); + const taskRow = await storage.getTask(dispatchResult.taskId); + expect(taskRow.status).toBe('failed'); + expect(taskRow.secrets).toBeUndefined(); + }); + it('multiple brokers should be able to observe a single task', async () => { const broker1 = new StorageTaskBroker(storage, logger); const broker2 = new StorageTaskBroker(storage, logger); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts index 8f30afde6f..6a82fa53ca 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts @@ -49,6 +49,10 @@ export class TaskAgent implements Task { return this.state.spec; } + get secrets() { + return this.state.secrets; + } + async getWorkspaceName() { return this.state.taskId; } @@ -102,6 +106,7 @@ export class TaskAgent implements Task { interface TaskState { spec: TaskSpec; taskId: string; + secrets?: TaskSecrets; } function defer() { @@ -127,6 +132,7 @@ export class StorageTaskBroker implements TaskBroker { { taskId: pendingTask.id, spec: pendingTask.spec, + secrets: pendingTask.secrets, }, this.storage, this.logger,