feat: migrating things to using catalogService and removing older exports
Signed-off-by: benjdlambert <ben@blam.sh>
This commit is contained in:
@@ -43,11 +43,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/catalog-client": "workspace:^",
|
||||
"@backstage/catalog-model": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/integration": "workspace:^",
|
||||
"@backstage/plugin-catalog-node": "workspace:^",
|
||||
"@backstage/plugin-scaffolder-node": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"@octokit/webhooks": "^10.9.2",
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { CatalogService } from '@backstage/plugin-catalog-node';
|
||||
import { Config } from '@backstage/config';
|
||||
import { createPullRequest } from 'octokit-plugin-create-pull-request';
|
||||
import { GithubCredentialsProvider } from '@backstage/integration';
|
||||
@@ -111,8 +110,7 @@ export function createGithubDeployKeyAction(options: {
|
||||
// @public
|
||||
export function createGithubEnvironmentAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
catalogClient?: CatalogApi;
|
||||
auth?: AuthService;
|
||||
catalogService: CatalogService;
|
||||
}): TemplateAction<
|
||||
{
|
||||
repoUrl: string;
|
||||
|
||||
+7
-9
@@ -16,11 +16,11 @@
|
||||
import { createGithubEnvironmentAction } from './githubEnvironment';
|
||||
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import yaml from 'yaml';
|
||||
import { examples } from './gitHubEnvironment.examples';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
|
||||
const mockOctokit = {
|
||||
rest: {
|
||||
@@ -42,9 +42,7 @@ const mockOctokit = {
|
||||
},
|
||||
},
|
||||
};
|
||||
const mockCatalogClient: Partial<CatalogApi> = {
|
||||
getEntitiesByRefs: jest.fn(),
|
||||
};
|
||||
|
||||
jest.mock('octokit', () => ({
|
||||
Octokit: class {
|
||||
constructor() {
|
||||
@@ -52,9 +50,6 @@ jest.mock('octokit', () => ({
|
||||
}
|
||||
},
|
||||
}));
|
||||
jest.mock('@backstage/catalog-client', () => ({
|
||||
CatalogClient: mockCatalogClient,
|
||||
}));
|
||||
|
||||
const publicKey = '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvvcCU=';
|
||||
|
||||
@@ -72,6 +67,7 @@ describe('github:environment:create examples', () => {
|
||||
let action: TemplateAction<any, any, any>;
|
||||
|
||||
const mockContext = createMockActionContext();
|
||||
const mockCatalogService = catalogServiceMock.mock();
|
||||
|
||||
beforeEach(() => {
|
||||
mockOctokit.rest.actions.getEnvironmentPublicKey.mockResolvedValue({
|
||||
@@ -95,15 +91,17 @@ describe('github:environment:create examples', () => {
|
||||
id: 2,
|
||||
},
|
||||
});
|
||||
(mockCatalogClient.getEntitiesByRefs as jest.Mock).mockResolvedValue({
|
||||
mockCatalogService.getEntitiesByRefs.mockResolvedValue({
|
||||
items: [
|
||||
{
|
||||
apiVersion: 'v1',
|
||||
kind: 'User',
|
||||
metadata: {
|
||||
name: 'johndoe',
|
||||
},
|
||||
},
|
||||
{
|
||||
apiVersion: 'v1',
|
||||
kind: 'Group',
|
||||
metadata: {
|
||||
name: 'team-a',
|
||||
@@ -114,7 +112,7 @@ describe('github:environment:create examples', () => {
|
||||
|
||||
action = createGithubEnvironmentAction({
|
||||
integrations,
|
||||
catalogClient: mockCatalogClient as CatalogApi,
|
||||
catalogService: mockCatalogService,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@ import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
|
||||
import { mockCredentials } from '@backstage/backend-test-utils';
|
||||
|
||||
import { Octokit } from 'octokit';
|
||||
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
|
||||
|
||||
const octokitMock = Octokit as unknown as jest.Mock;
|
||||
|
||||
@@ -47,18 +47,10 @@ const mockOctokit = {
|
||||
},
|
||||
};
|
||||
|
||||
const mockCatalogClient: Partial<CatalogApi> = {
|
||||
getEntitiesByRefs: jest.fn(),
|
||||
};
|
||||
|
||||
jest.mock('octokit', () => ({
|
||||
Octokit: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@backstage/catalog-client', () => ({
|
||||
CatalogClient: mockCatalogClient,
|
||||
}));
|
||||
|
||||
const publicKey = '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvvcCU=';
|
||||
|
||||
describe('github:environment:create', () => {
|
||||
@@ -72,14 +64,10 @@ describe('github:environment:create', () => {
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const mockCatalogService = catalogServiceMock.mock();
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
|
||||
const token = mockCredentials.service.token({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
let action: TemplateAction<any, any, any>;
|
||||
|
||||
const mockContext = createMockActionContext({
|
||||
@@ -87,7 +75,6 @@ describe('github:environment:create', () => {
|
||||
repoUrl: 'github.com?repo=repository&owner=owner',
|
||||
name: 'envname',
|
||||
},
|
||||
secrets: { backstageToken: token },
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -114,15 +101,18 @@ describe('github:environment:create', () => {
|
||||
id: 2,
|
||||
},
|
||||
});
|
||||
(mockCatalogClient.getEntitiesByRefs as jest.Mock).mockResolvedValue({
|
||||
|
||||
mockCatalogService.getEntitiesByRefs.mockResolvedValue({
|
||||
items: [
|
||||
{
|
||||
apiVersion: '1',
|
||||
kind: 'User',
|
||||
metadata: {
|
||||
name: 'johndoe',
|
||||
},
|
||||
},
|
||||
{
|
||||
apiVersion: '1',
|
||||
kind: 'Group',
|
||||
metadata: {
|
||||
name: 'team-a',
|
||||
@@ -133,8 +123,7 @@ describe('github:environment:create', () => {
|
||||
|
||||
action = createGithubEnvironmentAction({
|
||||
integrations,
|
||||
catalogClient: mockCatalogClient as CatalogApi,
|
||||
auth: mockServices.auth(),
|
||||
catalogService: mockCatalogService,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -496,11 +485,11 @@ describe('github:environment:create', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockCatalogClient.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(mockCatalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{
|
||||
entityRefs: ['group:default/team-a', 'user:default/johndoe'],
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
expect(
|
||||
|
||||
@@ -24,9 +24,8 @@ import { getOctokitOptions } from '../util';
|
||||
import { Octokit } from 'octokit';
|
||||
import Sodium from 'libsodium-wrappers';
|
||||
import { examples } from './gitHubEnvironment.examples';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { CatalogService } from '@backstage/plugin-catalog-node';
|
||||
|
||||
/**
|
||||
* Creates an `github:environment:create` Scaffolder action that creates a Github Environment.
|
||||
@@ -35,10 +34,9 @@ import { AuthService } from '@backstage/backend-plugin-api';
|
||||
*/
|
||||
export function createGithubEnvironmentAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
catalogClient?: CatalogApi;
|
||||
auth?: AuthService;
|
||||
catalogService: CatalogService;
|
||||
}) {
|
||||
const { integrations, catalogClient, auth } = options;
|
||||
const { integrations, catalogService } = options;
|
||||
// For more information on how to define custom actions, see
|
||||
// https://backstage.io/docs/features/software-templates/writing-custom-actions
|
||||
return createTemplateAction({
|
||||
@@ -147,11 +145,6 @@ Wildcard characters will not match \`/\`. For example, to match tags that begin
|
||||
reviewers,
|
||||
} = ctx.input;
|
||||
|
||||
const { token } = (await auth?.getPluginRequestToken({
|
||||
onBehalfOf: await ctx.getInitiatorCredentials(),
|
||||
targetPluginId: 'catalog',
|
||||
})) ?? { token: ctx.secrets?.backstageToken };
|
||||
|
||||
// When environment creation step is executed right after a repo publish step, the repository might not be available immediately.
|
||||
// Add a 2-second delay before initiating the steps in this action.
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
@@ -190,12 +183,12 @@ Wildcard characters will not match \`/\`. For example, to match tags that begin
|
||||
if (reviewers) {
|
||||
let reviewersEntityRefs: Array<Entity | undefined> = [];
|
||||
// Fetch reviewers from Catalog
|
||||
const catalogResponse = await catalogClient?.getEntitiesByRefs(
|
||||
const catalogResponse = await catalogService?.getEntitiesByRefs(
|
||||
{
|
||||
entityRefs: reviewers,
|
||||
},
|
||||
{
|
||||
token,
|
||||
credentials: await ctx.getInitiatorCredentials(),
|
||||
},
|
||||
);
|
||||
if (catalogResponse?.items?.length) {
|
||||
|
||||
@@ -39,8 +39,8 @@ import {
|
||||
DefaultGithubCredentialsProvider,
|
||||
ScmIntegrations,
|
||||
} from '@backstage/integration';
|
||||
import { CatalogClient } from '@backstage/catalog-client';
|
||||
import { createHandleAutocompleteRequest } from './autocomplete/autocomplete';
|
||||
import { catalogServiceRef } from '@backstage/plugin-catalog-node';
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -54,17 +54,13 @@ export const githubModule = createBackendModule({
|
||||
deps: {
|
||||
scaffolder: scaffolderActionsExtensionPoint,
|
||||
config: coreServices.rootConfig,
|
||||
discovery: coreServices.discovery,
|
||||
auth: coreServices.auth,
|
||||
catalogService: catalogServiceRef,
|
||||
autocomplete: scaffolderAutocompleteExtensionPoint,
|
||||
},
|
||||
async init({ scaffolder, config, discovery, auth, autocomplete }) {
|
||||
async init({ scaffolder, config, autocomplete, catalogService }) {
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const githubCredentialsProvider =
|
||||
DefaultGithubCredentialsProvider.fromIntegrations(integrations);
|
||||
const catalogClient = new CatalogClient({
|
||||
discoveryApi: discovery,
|
||||
});
|
||||
|
||||
scaffolder.addActions(
|
||||
createGithubActionsDispatchAction({
|
||||
@@ -80,8 +76,7 @@ export const githubModule = createBackendModule({
|
||||
}),
|
||||
createGithubEnvironmentAction({
|
||||
integrations,
|
||||
catalogClient,
|
||||
auth,
|
||||
catalogService,
|
||||
}),
|
||||
createGithubIssuesLabelAction({
|
||||
integrations,
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
"@backstage/backend-common": "^0.25.0",
|
||||
"@backstage/backend-defaults": "workspace:^",
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/catalog-client": "workspace:^",
|
||||
"@backstage/catalog-model": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AuditorService } from '@backstage/backend-plugin-api';
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { BackstageCredentials } from '@backstage/backend-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { CatalogService } from '@backstage/plugin-catalog-node';
|
||||
import { Config } from '@backstage/config';
|
||||
import { DatabaseService } from '@backstage/backend-plugin-api';
|
||||
import { Duration } from 'luxon';
|
||||
@@ -16,7 +16,7 @@ import { HumanDuration } from '@backstage/types';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { JsonValue } from '@backstage/types';
|
||||
import { Knex } from 'knex';
|
||||
import { Logger } from 'winston';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
||||
import { PermissionRule } from '@backstage/plugin-permission-node';
|
||||
import { PermissionRuleParams } from '@backstage/plugin-permission-common';
|
||||
@@ -51,28 +51,10 @@ export type ActionPermissionRuleInput<
|
||||
TParams
|
||||
>;
|
||||
|
||||
// @public
|
||||
export const createBuiltinActions: (
|
||||
options: CreateBuiltInActionsOptions,
|
||||
) => TemplateAction[];
|
||||
|
||||
// @public
|
||||
export interface CreateBuiltInActionsOptions {
|
||||
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
||||
// (undocumented)
|
||||
additionalTemplateGlobals?: Record<string, TemplateGlobal>;
|
||||
auth?: AuthService;
|
||||
catalogClient: CatalogApi;
|
||||
config: Config;
|
||||
integrations: ScmIntegrations;
|
||||
reader: UrlReaderService;
|
||||
}
|
||||
|
||||
// @public
|
||||
export function createCatalogRegisterAction(options: {
|
||||
catalogClient: CatalogApi;
|
||||
catalogService: CatalogService;
|
||||
integrations: ScmIntegrations;
|
||||
auth?: AuthService;
|
||||
}): TemplateAction<
|
||||
| {
|
||||
catalogInfoUrl: string;
|
||||
@@ -124,8 +106,7 @@ export function createDebugLogAction(): TemplateAction<
|
||||
|
||||
// @public
|
||||
export function createFetchCatalogEntityAction(options: {
|
||||
catalogClient: CatalogApi;
|
||||
auth?: AuthService;
|
||||
catalogService: CatalogService;
|
||||
}): TemplateAction<
|
||||
{
|
||||
entityRef?: string | undefined;
|
||||
@@ -290,7 +271,7 @@ export type CreateWorkerOptions = {
|
||||
actionRegistry: TemplateActionRegistry;
|
||||
integrations: ScmIntegrations;
|
||||
workingDirectory: string;
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
auditor?: AuditorService;
|
||||
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
||||
concurrentTasksLimit?: number;
|
||||
@@ -427,7 +408,7 @@ export class TaskManager implements TaskContext {
|
||||
task: CurrentClaimedTask,
|
||||
storage: TaskStore,
|
||||
abortSignal: AbortSignal,
|
||||
logger: Logger,
|
||||
logger: LoggerService,
|
||||
auth?: AuthService,
|
||||
config?: Config,
|
||||
additionalWorkspaceProviders?: Record<string, WorkspaceProvider>,
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
createBackendPlugin,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { catalogServiceRef } from '@backstage/plugin-catalog-node';
|
||||
import { eventsServiceRef } from '@backstage/plugin-events-node';
|
||||
import { TaskBroker, TemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import {
|
||||
@@ -137,7 +137,7 @@ export const scaffolderPlugin = createBackendPlugin({
|
||||
httpRouter: coreServices.httpRouter,
|
||||
httpAuth: coreServices.httpAuth,
|
||||
auditor: coreServices.auditor,
|
||||
catalogClient: catalogServiceRef,
|
||||
catalogService: catalogServiceRef,
|
||||
events: eventsServiceRef,
|
||||
},
|
||||
async init({
|
||||
@@ -149,7 +149,7 @@ export const scaffolderPlugin = createBackendPlugin({
|
||||
auth,
|
||||
httpRouter,
|
||||
httpAuth,
|
||||
catalogClient,
|
||||
catalogService,
|
||||
permissions,
|
||||
events,
|
||||
auditor,
|
||||
@@ -191,8 +191,8 @@ export const scaffolderPlugin = createBackendPlugin({
|
||||
createDebugLogAction(),
|
||||
createWaitAction(),
|
||||
// todo(blam): maybe these should be a -catalog module?
|
||||
createCatalogRegisterAction({ catalogClient, integrations, auth }),
|
||||
createFetchCatalogEntityAction({ catalogClient, auth }),
|
||||
createCatalogRegisterAction({ catalogService, integrations }),
|
||||
createFetchCatalogEntityAction({ catalogService }),
|
||||
createCatalogWriteAction(),
|
||||
createFilesystemDeleteAction(),
|
||||
createFilesystemRenameAction(),
|
||||
@@ -206,11 +206,10 @@ export const scaffolderPlugin = createBackendPlugin({
|
||||
);
|
||||
|
||||
const router = await createRouter({
|
||||
logger: log,
|
||||
logger,
|
||||
config,
|
||||
database,
|
||||
catalogClient,
|
||||
reader,
|
||||
catalogService,
|
||||
lifecycle,
|
||||
actions,
|
||||
taskBroker,
|
||||
|
||||
+7
-15
@@ -19,7 +19,7 @@ import { Entity } from '@backstage/catalog-model';
|
||||
import { createFetchCatalogEntityAction } from './fetch';
|
||||
import { examples } from './fetch.examples';
|
||||
import yaml from 'yaml';
|
||||
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
|
||||
import { mockCredentials } from '@backstage/backend-test-utils';
|
||||
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
|
||||
|
||||
describe('catalog:fetch examples', () => {
|
||||
@@ -31,27 +31,19 @@ describe('catalog:fetch examples', () => {
|
||||
},
|
||||
} as Entity;
|
||||
|
||||
const catalogClient = catalogServiceMock({ entities: [entity] });
|
||||
const catalogService = catalogServiceMock({ entities: [entity] });
|
||||
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
|
||||
const token = mockCredentials.service.token({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const mockContext = createMockActionContext({
|
||||
secrets: { backstageToken: token },
|
||||
});
|
||||
const mockContext = createMockActionContext();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.spyOn(catalogClient, 'getEntityByRef');
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
});
|
||||
|
||||
describe('fetch single entity', () => {
|
||||
@@ -61,9 +53,9 @@ describe('catalog:fetch examples', () => {
|
||||
input: yaml.parse(examples[0].example).steps[0].input,
|
||||
});
|
||||
|
||||
expect(catalogClient.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
'component:default/name',
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(mockContext.output).toHaveBeenCalledWith('entity', entity);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { createFetchCatalogEntityAction } from './fetch';
|
||||
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
|
||||
import { mockCredentials } from '@backstage/backend-test-utils';
|
||||
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
|
||||
|
||||
describe('catalog:fetch', () => {
|
||||
@@ -31,14 +31,7 @@ describe('catalog:fetch', () => {
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
|
||||
const token = mockCredentials.service.token({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const mockContext = createMockActionContext({
|
||||
secrets: { backstageToken: token },
|
||||
});
|
||||
const mockContext = createMockActionContext();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
@@ -46,11 +39,10 @@ describe('catalog:fetch', () => {
|
||||
|
||||
describe('fetch single entity', () => {
|
||||
it('should return entity from catalog', async () => {
|
||||
const catalogClient = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogClient, 'getEntityByRef');
|
||||
const catalogService = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -60,21 +52,20 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogClient.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
'component:default/test',
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(mockContext.output).toHaveBeenCalledWith('entity', component);
|
||||
});
|
||||
|
||||
it('should throw error if entity fetch fails from catalog and optional is false', async () => {
|
||||
const catalogClient = catalogServiceMock.mock({
|
||||
const catalogService = catalogServiceMock.mock({
|
||||
getEntityByRef: () => Promise.reject(new Error('Not found')),
|
||||
});
|
||||
jest.spyOn(catalogClient, 'getEntityByRef');
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -86,19 +77,18 @@ describe('catalog:fetch', () => {
|
||||
}),
|
||||
).rejects.toThrow('Not found');
|
||||
|
||||
expect(catalogClient.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
'component:default/test',
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(mockContext.output).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw error if entity not in catalog and optional is false', async () => {
|
||||
const catalogClient = catalogServiceMock({ entities: [] });
|
||||
jest.spyOn(catalogClient, 'getEntityByRef');
|
||||
const catalogService = catalogServiceMock({ entities: [] });
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -110,9 +100,9 @@ describe('catalog:fetch', () => {
|
||||
}),
|
||||
).rejects.toThrow('Entity component:default/test not found');
|
||||
|
||||
expect(catalogClient.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
'component:default/test',
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(mockContext.output).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -125,11 +115,10 @@ describe('catalog:fetch', () => {
|
||||
namespace: 'ns',
|
||||
},
|
||||
} as Entity;
|
||||
const catalogClient = catalogServiceMock({ entities: [entity] });
|
||||
jest.spyOn(catalogClient, 'getEntityByRef');
|
||||
const catalogService = catalogServiceMock({ entities: [entity] });
|
||||
jest.spyOn(catalogService, 'getEntityByRef');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -141,9 +130,9 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogClient.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
'group:ns/test',
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(mockContext.output).toHaveBeenCalledWith('entity', entity);
|
||||
});
|
||||
@@ -151,11 +140,10 @@ describe('catalog:fetch', () => {
|
||||
|
||||
describe('fetch multiple entities', () => {
|
||||
it('should return entities from catalog', async () => {
|
||||
const catalogClient = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogClient, 'getEntitiesByRefs');
|
||||
const catalogService = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogService, 'getEntitiesByRefs');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -165,19 +153,18 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogClient.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{ entityRefs: ['component:default/test'] },
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(mockContext.output).toHaveBeenCalledWith('entities', [component]);
|
||||
});
|
||||
|
||||
it('should throw error if undefined is returned for some entity', async () => {
|
||||
const catalogClient = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogClient, 'getEntitiesByRefs');
|
||||
const catalogService = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogService, 'getEntitiesByRefs');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -190,21 +177,20 @@ describe('catalog:fetch', () => {
|
||||
}),
|
||||
).rejects.toThrow('Entity component:default/test2 not found');
|
||||
|
||||
expect(catalogClient.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{
|
||||
entityRefs: ['component:default/test', 'component:default/test2'],
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(mockContext.output).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return null in case some of the entities not found and optional is true', async () => {
|
||||
const catalogClient = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogClient, 'getEntitiesByRefs');
|
||||
const catalogService = catalogServiceMock({ entities: [component] });
|
||||
jest.spyOn(catalogService, 'getEntitiesByRefs');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -215,9 +201,9 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogClient.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{ entityRefs: ['component:default/test', 'component:default/test2'] },
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(mockContext.output).toHaveBeenCalledWith('entities', [
|
||||
component,
|
||||
@@ -240,13 +226,12 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
kind: 'User',
|
||||
} as Entity;
|
||||
const catalogClient = catalogServiceMock({
|
||||
const catalogService = catalogServiceMock({
|
||||
entities: [entity1, entity2],
|
||||
});
|
||||
jest.spyOn(catalogClient, 'getEntitiesByRefs');
|
||||
jest.spyOn(catalogService, 'getEntitiesByRefs');
|
||||
const action = createFetchCatalogEntityAction({
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -258,9 +243,9 @@ describe('catalog:fetch', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogClient.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntitiesByRefs).toHaveBeenCalledWith(
|
||||
{ entityRefs: ['group:ns/test', 'user:default/test'] },
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith('entities', [
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { examples } from './fetch.examples';
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { CatalogService } from '@backstage/plugin-catalog-node';
|
||||
|
||||
const id = 'catalog:fetch';
|
||||
|
||||
@@ -28,10 +27,9 @@ const id = 'catalog:fetch';
|
||||
* @public
|
||||
*/
|
||||
export function createFetchCatalogEntityAction(options: {
|
||||
catalogClient: CatalogApi;
|
||||
auth?: AuthService;
|
||||
catalogService: CatalogService;
|
||||
}) {
|
||||
const { catalogClient, auth } = options;
|
||||
const { catalogService } = options;
|
||||
|
||||
return createTemplateAction({
|
||||
id,
|
||||
@@ -95,18 +93,13 @@ export function createFetchCatalogEntityAction(options: {
|
||||
throw new Error('Missing entity reference or references');
|
||||
}
|
||||
|
||||
const { token } = (await auth?.getPluginRequestToken({
|
||||
onBehalfOf: await ctx.getInitiatorCredentials(),
|
||||
targetPluginId: 'catalog',
|
||||
})) ?? { token: ctx.secrets?.backstageToken };
|
||||
|
||||
if (entityRef) {
|
||||
const entity = await catalogClient.getEntityByRef(
|
||||
const entity = await catalogService.getEntityByRef(
|
||||
stringifyEntityRef(
|
||||
parseEntityRef(entityRef, { defaultKind, defaultNamespace }),
|
||||
),
|
||||
{
|
||||
token,
|
||||
credentials: await ctx.getInitiatorCredentials(),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -117,7 +110,7 @@ export function createFetchCatalogEntityAction(options: {
|
||||
}
|
||||
|
||||
if (entityRefs) {
|
||||
const entities = await catalogClient.getEntitiesByRefs(
|
||||
const entities = await catalogService.getEntitiesByRefs(
|
||||
{
|
||||
entityRefs: entityRefs.map(ref =>
|
||||
stringifyEntityRef(
|
||||
@@ -125,9 +118,7 @@ export function createFetchCatalogEntityAction(options: {
|
||||
),
|
||||
),
|
||||
},
|
||||
{
|
||||
token,
|
||||
},
|
||||
{ credentials: await ctx.getInitiatorCredentials() },
|
||||
);
|
||||
|
||||
const finalEntities = entities.items.map((e, i) => {
|
||||
|
||||
+8
-14
@@ -21,7 +21,7 @@ import { createCatalogRegisterAction } from './register';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { examples } from './register.examples';
|
||||
import yaml from 'yaml';
|
||||
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
|
||||
import { mockCredentials } from '@backstage/backend-test-utils';
|
||||
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
|
||||
|
||||
describe('catalog:register', () => {
|
||||
@@ -33,28 +33,22 @@ describe('catalog:register', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
const catalogClient = catalogServiceMock.mock();
|
||||
const catalogService = catalogServiceMock.mock();
|
||||
|
||||
const action = createCatalogRegisterAction({
|
||||
integrations,
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
|
||||
const token = mockCredentials.service.token({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const mockContext = createMockActionContext();
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should register location in catalog', async () => {
|
||||
catalogClient.addLocation
|
||||
catalogService.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -76,16 +70,16 @@ describe('catalog:register', () => {
|
||||
input: yaml.parse(examples[0].example).steps[0].input,
|
||||
});
|
||||
|
||||
expect(catalogClient.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{
|
||||
type: 'url',
|
||||
target:
|
||||
'http://github.com/backstage/backstage/blob/master/catalog-info.yaml',
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogClient.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{
|
||||
dryRun: true,
|
||||
@@ -93,7 +87,7 @@ describe('catalog:register', () => {
|
||||
target:
|
||||
'http://github.com/backstage/backstage/blob/master/catalog-info.yaml',
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
|
||||
+22
-28
@@ -19,7 +19,7 @@ import { ConfigReader } from '@backstage/config';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { createCatalogRegisterAction } from './register';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
|
||||
import { mockCredentials } from '@backstage/backend-test-utils';
|
||||
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
|
||||
|
||||
describe('catalog:register', () => {
|
||||
@@ -31,21 +31,15 @@ describe('catalog:register', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
const catalogClient = catalogServiceMock.mock();
|
||||
const catalogService = catalogServiceMock.mock();
|
||||
|
||||
const action = createCatalogRegisterAction({
|
||||
integrations,
|
||||
catalogClient,
|
||||
auth: mockServices.auth(),
|
||||
catalogService,
|
||||
});
|
||||
|
||||
const credentials = mockCredentials.user();
|
||||
|
||||
const token = mockCredentials.service.token({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const mockContext = createMockActionContext();
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -66,7 +60,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should register location in catalog', async () => {
|
||||
catalogClient.addLocation
|
||||
catalogService.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -90,22 +84,22 @@ describe('catalog:register', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogClient.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{
|
||||
type: 'url',
|
||||
target: 'http://foo/var',
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogClient.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{
|
||||
dryRun: true,
|
||||
type: 'url',
|
||||
target: 'http://foo/var',
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
@@ -119,7 +113,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should return entityRef with the Component entity and not the generated location', async () => {
|
||||
catalogClient.addLocation
|
||||
catalogService.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -170,7 +164,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should return entityRef with the next non-generated entity if no Component kind can be found', async () => {
|
||||
catalogClient.addLocation
|
||||
catalogService.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -214,7 +208,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should return entityRef with the first entity if no non-generated entities can be found', async () => {
|
||||
catalogClient.addLocation
|
||||
catalogService.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -251,7 +245,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should not return entityRef if there are no entities', async () => {
|
||||
catalogClient.addLocation
|
||||
catalogService.addLocation
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
entities: [],
|
||||
@@ -273,7 +267,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should ignore failures when dry running the location in the catalog if `optional` is set', async () => {
|
||||
catalogClient.addLocation
|
||||
catalogService.addLocation
|
||||
.mockRejectedValueOnce(new Error('Not found'))
|
||||
.mockRejectedValueOnce(new Error('Not found'));
|
||||
await action.handler({
|
||||
@@ -284,22 +278,22 @@ describe('catalog:register', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogClient.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{
|
||||
type: 'url',
|
||||
target: 'http://foo/var',
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogClient.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{
|
||||
dryRun: true,
|
||||
type: 'url',
|
||||
target: 'http://foo/var',
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
@@ -309,7 +303,7 @@ describe('catalog:register', () => {
|
||||
});
|
||||
|
||||
it('should fetch entities when adding location in the catalog fails and `optional` is set', async () => {
|
||||
catalogClient.addLocation
|
||||
catalogService.addLocation
|
||||
.mockRejectedValueOnce(new Error('Already registered'))
|
||||
.mockResolvedValueOnce({
|
||||
location: null as any,
|
||||
@@ -331,22 +325,22 @@ describe('catalog:register', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(catalogClient.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{
|
||||
type: 'url',
|
||||
target: 'http://foo/var',
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
expect(catalogClient.addLocation).toHaveBeenNthCalledWith(
|
||||
expect(catalogService.addLocation).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{
|
||||
dryRun: true,
|
||||
type: 'url',
|
||||
target: 'http://foo/var',
|
||||
},
|
||||
{ token },
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { stringifyEntityRef, Entity } from '@backstage/catalog-model';
|
||||
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { examples } from './register.examples';
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { CatalogService } from '@backstage/plugin-catalog-node';
|
||||
|
||||
const id = 'catalog:register';
|
||||
|
||||
@@ -29,11 +28,10 @@ const id = 'catalog:register';
|
||||
* @public
|
||||
*/
|
||||
export function createCatalogRegisterAction(options: {
|
||||
catalogClient: CatalogApi;
|
||||
catalogService: CatalogService;
|
||||
integrations: ScmIntegrations;
|
||||
auth?: AuthService;
|
||||
}) {
|
||||
const { catalogClient, integrations, auth } = options;
|
||||
const { catalogService, integrations } = options;
|
||||
|
||||
return createTemplateAction({
|
||||
id,
|
||||
@@ -99,19 +97,14 @@ export function createCatalogRegisterAction(options: {
|
||||
|
||||
ctx.logger.info(`Registering ${catalogInfoUrl} in the catalog`);
|
||||
|
||||
const { token } = (await auth?.getPluginRequestToken({
|
||||
onBehalfOf: await ctx.getInitiatorCredentials(),
|
||||
targetPluginId: 'catalog',
|
||||
})) ?? { token: ctx.secrets?.backstageToken };
|
||||
|
||||
try {
|
||||
// 1st try to register the location, this will throw an error if the location already exists (see catch)
|
||||
await catalogClient.addLocation(
|
||||
await catalogService.addLocation(
|
||||
{
|
||||
type: 'url',
|
||||
target: catalogInfoUrl,
|
||||
},
|
||||
token ? { token } : {},
|
||||
{ credentials: await ctx.getInitiatorCredentials() },
|
||||
);
|
||||
} catch (e) {
|
||||
if (!input.optional) {
|
||||
@@ -122,13 +115,13 @@ export function createCatalogRegisterAction(options: {
|
||||
|
||||
try {
|
||||
// 2nd retry the registration as a dry run, this will not throw an error if the location already exists
|
||||
const result = await catalogClient.addLocation(
|
||||
const result = await catalogService.addLocation(
|
||||
{
|
||||
dryRun: true,
|
||||
type: 'url',
|
||||
target: catalogInfoUrl,
|
||||
},
|
||||
token ? { token } : {},
|
||||
{ credentials: await ctx.getInitiatorCredentials() },
|
||||
);
|
||||
|
||||
if (result.entities.length) {
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
import {
|
||||
DefaultGithubCredentialsProvider,
|
||||
GithubCredentialsProvider,
|
||||
ScmIntegrations,
|
||||
} from '@backstage/integration';
|
||||
import {
|
||||
TemplateAction,
|
||||
TemplateFilter,
|
||||
TemplateGlobal,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
import {
|
||||
createCatalogRegisterAction,
|
||||
createCatalogWriteAction,
|
||||
createFetchCatalogEntityAction,
|
||||
} from './catalog';
|
||||
|
||||
import { createDebugLogAction, createWaitAction } from './debug';
|
||||
import {
|
||||
createFetchPlainAction,
|
||||
createFetchPlainFileAction,
|
||||
createFetchTemplateAction,
|
||||
createFetchTemplateFileAction,
|
||||
} from './fetch';
|
||||
import {
|
||||
createFilesystemDeleteAction,
|
||||
createFilesystemReadDirAction,
|
||||
createFilesystemRenameAction,
|
||||
} from './filesystem';
|
||||
import {
|
||||
createGithubActionsDispatchAction,
|
||||
createGithubAutolinksAction,
|
||||
createGithubDeployKeyAction,
|
||||
createGithubEnvironmentAction,
|
||||
createGithubIssuesLabelAction,
|
||||
createGithubRepoCreateAction,
|
||||
createGithubRepoPushAction,
|
||||
createGithubWebhookAction,
|
||||
createPublishGithubAction,
|
||||
createPublishGithubPullRequestAction,
|
||||
} from '@backstage/plugin-scaffolder-backend-module-github';
|
||||
|
||||
import { createPublishAzureAction } from '@backstage/plugin-scaffolder-backend-module-azure';
|
||||
|
||||
import { createPublishBitbucketAction } from '@backstage/plugin-scaffolder-backend-module-bitbucket';
|
||||
|
||||
import {
|
||||
createPublishBitbucketCloudAction,
|
||||
createBitbucketPipelinesRunAction,
|
||||
createPublishBitbucketCloudPullRequestAction,
|
||||
} from '@backstage/plugin-scaffolder-backend-module-bitbucket-cloud';
|
||||
|
||||
import {
|
||||
createPublishBitbucketServerAction,
|
||||
createPublishBitbucketServerPullRequestAction,
|
||||
} from '@backstage/plugin-scaffolder-backend-module-bitbucket-server';
|
||||
|
||||
import {
|
||||
createPublishGerritAction,
|
||||
createPublishGerritReviewAction,
|
||||
} from '@backstage/plugin-scaffolder-backend-module-gerrit';
|
||||
|
||||
import {
|
||||
createPublishGitlabAction,
|
||||
createGitlabRepoPushAction,
|
||||
createPublishGitlabMergeRequestAction,
|
||||
} from '@backstage/plugin-scaffolder-backend-module-gitlab';
|
||||
|
||||
import { createPublishGiteaAction } from '@backstage/plugin-scaffolder-backend-module-gitea';
|
||||
import { AuthService, UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
|
||||
/**
|
||||
* The options passed to {@link createBuiltinActions}
|
||||
* @public
|
||||
*/
|
||||
export interface CreateBuiltInActionsOptions {
|
||||
/**
|
||||
* The {@link @backstage/backend-plugin-api#UrlReaderService} interface that will be used in the default actions.
|
||||
*/
|
||||
reader: UrlReaderService;
|
||||
/**
|
||||
* The {@link @backstage/integrations#ScmIntegrations} that will be used in the default actions.
|
||||
*/
|
||||
integrations: ScmIntegrations;
|
||||
/**
|
||||
* The {@link @backstage/catalog-client#CatalogApi} that will be used in the default actions.
|
||||
*/
|
||||
catalogClient: CatalogApi;
|
||||
/**
|
||||
* The {@link @backstage/backend-plugin-api#AuthService} that will be used in the default actions.
|
||||
*/
|
||||
auth?: AuthService;
|
||||
/**
|
||||
* The {@link @backstage/config#Config} that will be used in the default actions.
|
||||
*/
|
||||
config: Config;
|
||||
/**
|
||||
* Additional custom filters that will be passed to the nunjucks template engine for use in
|
||||
* Template Manifests and also template skeleton files when using `fetch:template`.
|
||||
*/
|
||||
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
||||
additionalTemplateGlobals?: Record<string, TemplateGlobal>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to generate create a list of default actions that the scaffolder provides.
|
||||
* Is called internally in the default setup, but can be used when adding your own actions or overriding the default ones
|
||||
*
|
||||
* TODO(blam): version 2 of the scaffolder shouldn't ship with the additional modules. We should ship the basics, and let people install
|
||||
* modules for the providers they want to use.
|
||||
* @public
|
||||
* @returns A list of actions that can be used in the scaffolder
|
||||
*
|
||||
*/
|
||||
export const createBuiltinActions = (
|
||||
options: CreateBuiltInActionsOptions,
|
||||
): TemplateAction[] => {
|
||||
const {
|
||||
reader,
|
||||
integrations,
|
||||
catalogClient,
|
||||
auth,
|
||||
config,
|
||||
additionalTemplateFilters,
|
||||
additionalTemplateGlobals,
|
||||
} = options;
|
||||
|
||||
const githubCredentialsProvider: GithubCredentialsProvider =
|
||||
DefaultGithubCredentialsProvider.fromIntegrations(integrations);
|
||||
|
||||
const actions = [
|
||||
createFetchPlainAction({
|
||||
reader,
|
||||
integrations,
|
||||
}),
|
||||
createFetchPlainFileAction({
|
||||
reader,
|
||||
integrations,
|
||||
}),
|
||||
createFetchTemplateAction({
|
||||
integrations,
|
||||
reader,
|
||||
additionalTemplateFilters,
|
||||
additionalTemplateGlobals,
|
||||
}),
|
||||
createFetchTemplateFileAction({
|
||||
integrations,
|
||||
reader,
|
||||
additionalTemplateFilters,
|
||||
additionalTemplateGlobals,
|
||||
}),
|
||||
createPublishGerritAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishGerritReviewAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishGiteaAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishGithubAction({
|
||||
integrations,
|
||||
config,
|
||||
githubCredentialsProvider,
|
||||
}),
|
||||
createPublishGithubPullRequestAction({
|
||||
integrations,
|
||||
githubCredentialsProvider,
|
||||
config,
|
||||
}),
|
||||
createPublishGitlabAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishGitlabMergeRequestAction({
|
||||
integrations,
|
||||
}),
|
||||
createGitlabRepoPushAction({
|
||||
integrations,
|
||||
}),
|
||||
createPublishBitbucketAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishBitbucketCloudAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishBitbucketCloudPullRequestAction({ integrations, config }),
|
||||
createPublishBitbucketServerAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishBitbucketServerPullRequestAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishAzureAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createDebugLogAction(),
|
||||
createWaitAction(),
|
||||
createCatalogRegisterAction({ catalogClient, integrations, auth }),
|
||||
createFetchCatalogEntityAction({ catalogClient, auth }),
|
||||
createCatalogWriteAction(),
|
||||
createFilesystemDeleteAction(),
|
||||
createFilesystemReadDirAction(),
|
||||
createFilesystemRenameAction(),
|
||||
createGithubActionsDispatchAction({
|
||||
integrations,
|
||||
githubCredentialsProvider,
|
||||
}),
|
||||
createGithubWebhookAction({
|
||||
integrations,
|
||||
githubCredentialsProvider,
|
||||
}),
|
||||
createGithubIssuesLabelAction({
|
||||
integrations,
|
||||
githubCredentialsProvider,
|
||||
}),
|
||||
createGithubRepoCreateAction({
|
||||
integrations,
|
||||
githubCredentialsProvider,
|
||||
}),
|
||||
createGithubRepoPushAction({
|
||||
integrations,
|
||||
config,
|
||||
githubCredentialsProvider,
|
||||
}),
|
||||
createGithubEnvironmentAction({
|
||||
integrations,
|
||||
catalogClient,
|
||||
}),
|
||||
createGithubDeployKeyAction({
|
||||
integrations,
|
||||
}),
|
||||
createGithubAutolinksAction({
|
||||
integrations,
|
||||
githubCredentialsProvider,
|
||||
}),
|
||||
createBitbucketPipelinesRunAction({
|
||||
integrations,
|
||||
}),
|
||||
];
|
||||
|
||||
return actions as TemplateAction[];
|
||||
};
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
export * from './catalog';
|
||||
export * from './createBuiltinActions';
|
||||
export * from './debug';
|
||||
export * from './fetch';
|
||||
export * from './filesystem';
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import {
|
||||
AuditorService,
|
||||
BackstageCredentials,
|
||||
LoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import type { UserEntity } from '@backstage/catalog-model';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
@@ -36,7 +37,6 @@ import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { Logger } from 'winston';
|
||||
import { TemplateActionRegistry } from '../actions';
|
||||
import { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner';
|
||||
import { DecoratedActionsRegistry } from './DecoratedActionsRegistry';
|
||||
@@ -61,7 +61,7 @@ interface DryRunResult {
|
||||
|
||||
/** @internal */
|
||||
export type TemplateTesterCreateOptions = {
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
auditor?: AuditorService;
|
||||
integrations: ScmIntegrations;
|
||||
actionRegistry: TemplateActionRegistry;
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
AuditorService,
|
||||
AuthService,
|
||||
BackstageCredentials,
|
||||
LoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { Config } from '@backstage/config';
|
||||
import { TaskSpec } from '@backstage/plugin-scaffolder-common';
|
||||
@@ -38,7 +39,6 @@ import {
|
||||
Observable,
|
||||
createDeferred,
|
||||
} from '@backstage/types';
|
||||
import { Logger } from 'winston';
|
||||
import ObservableImpl from 'zen-observable';
|
||||
import { DefaultWorkspaceService, WorkspaceService } from './WorkspaceService';
|
||||
import { readDuration } from './helper';
|
||||
@@ -71,7 +71,7 @@ export class TaskManager implements TaskContext {
|
||||
task: CurrentClaimedTask,
|
||||
storage: TaskStore,
|
||||
abortSignal: AbortSignal,
|
||||
logger: Logger,
|
||||
logger: LoggerService,
|
||||
auth?: AuthService,
|
||||
config?: Config,
|
||||
additionalWorkspaceProviders?: Record<string, WorkspaceProvider>,
|
||||
@@ -100,7 +100,7 @@ export class TaskManager implements TaskContext {
|
||||
private readonly task: CurrentClaimedTask,
|
||||
private readonly storage: TaskStore,
|
||||
private readonly signal: AbortSignal,
|
||||
private readonly logger: Logger,
|
||||
private readonly logger: LoggerService,
|
||||
private readonly workspaceService: WorkspaceService,
|
||||
private readonly auth?: AuthService,
|
||||
) {}
|
||||
@@ -269,7 +269,7 @@ export interface CurrentClaimedTask {
|
||||
export class StorageTaskBroker implements TaskBroker {
|
||||
constructor(
|
||||
private readonly storage: TaskStore,
|
||||
private readonly logger: Logger,
|
||||
private readonly logger: LoggerService,
|
||||
private readonly config?: Config,
|
||||
private readonly auth?: AuthService,
|
||||
private readonly additionalWorkspaceProviders?: Record<
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AuditorService } from '@backstage/backend-plugin-api';
|
||||
import { AuditorService, LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { assertError, stringifyError } from '@backstage/errors';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
TemplateGlobal,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
import PQueue from 'p-queue';
|
||||
import { Logger } from 'winston';
|
||||
import { TemplateActionRegistry } from '../actions';
|
||||
import { NunjucksWorkflowRunner } from './NunjucksWorkflowRunner';
|
||||
import { WorkflowRunner } from './types';
|
||||
@@ -43,7 +42,7 @@ export type TaskWorkerOptions = {
|
||||
};
|
||||
concurrentTasksLimit: number;
|
||||
permissions?: PermissionEvaluator;
|
||||
logger?: Logger;
|
||||
logger?: LoggerService;
|
||||
auditor?: AuditorService;
|
||||
gracefulShutdown?: boolean;
|
||||
};
|
||||
@@ -58,7 +57,7 @@ export type CreateWorkerOptions = {
|
||||
actionRegistry: TemplateActionRegistry;
|
||||
integrations: ScmIntegrations;
|
||||
workingDirectory: string;
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
auditor?: AuditorService;
|
||||
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
||||
/**
|
||||
@@ -86,7 +85,7 @@ export type CreateWorkerOptions = {
|
||||
*/
|
||||
export class TaskWorker {
|
||||
private taskQueue: PQueue;
|
||||
private logger: Logger | undefined;
|
||||
private logger: LoggerService | undefined;
|
||||
private auditor: AuditorService | undefined;
|
||||
private stopWorkers: boolean;
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import {
|
||||
BackstageCredentials,
|
||||
LoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import {
|
||||
ANNOTATION_LOCATION,
|
||||
ANNOTATION_SOURCE_LOCATION,
|
||||
@@ -25,14 +28,14 @@ import {
|
||||
} from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { assertError, InputError, NotFoundError } from '@backstage/errors';
|
||||
import { CatalogService } from '@backstage/plugin-catalog-node';
|
||||
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
import fs from 'fs-extra';
|
||||
import os from 'os';
|
||||
import { Logger } from 'winston';
|
||||
|
||||
export async function getWorkingDirectory(
|
||||
config: Config,
|
||||
logger: Logger,
|
||||
logger: LoggerService,
|
||||
): Promise<string> {
|
||||
if (!config.has('backend.workingDirectory')) {
|
||||
return os.tmpdir();
|
||||
@@ -89,16 +92,18 @@ export function getEntityBaseUrl(entity: Entity): string | undefined {
|
||||
*/
|
||||
export async function findTemplate(options: {
|
||||
entityRef: CompoundEntityRef;
|
||||
token?: string;
|
||||
catalogApi: CatalogApi;
|
||||
catalogService: CatalogService;
|
||||
credentials: BackstageCredentials;
|
||||
}): Promise<TemplateEntityV1beta3> {
|
||||
const { entityRef, token, catalogApi } = options;
|
||||
const { entityRef, catalogService, credentials } = options;
|
||||
|
||||
if (entityRef.kind.toLocaleLowerCase('en-US') !== 'template') {
|
||||
throw new InputError(`Invalid kind, only 'Template' kind is supported`);
|
||||
}
|
||||
|
||||
const template = await catalogApi.getEntityByRef(entityRef, { token });
|
||||
const template = await catalogService.getEntityByRef(entityRef, {
|
||||
credentials,
|
||||
});
|
||||
if (!template) {
|
||||
throw new NotFoundError(
|
||||
`Template ${stringifyEntityRef(entityRef)} not found`,
|
||||
|
||||
@@ -53,7 +53,6 @@ import {
|
||||
createTemplateGlobalFunction,
|
||||
createTemplateGlobalValue,
|
||||
} from '@backstage/plugin-scaffolder-node/alpha';
|
||||
import { UrlReaders } from '@backstage/backend-defaults/urlReader';
|
||||
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
|
||||
import { EventsService } from '@backstage/plugin-events-node';
|
||||
import { DatabaseService } from '@backstage/backend-plugin-api';
|
||||
@@ -96,11 +95,6 @@ function createDatabase(): DatabaseService {
|
||||
).forPlugin('scaffolder');
|
||||
}
|
||||
|
||||
const mockUrlReader = UrlReaders.default({
|
||||
logger: mockServices.logger.mock(),
|
||||
config: new ConfigReader({}),
|
||||
});
|
||||
|
||||
const config = new ConfigReader({});
|
||||
|
||||
describe.each([
|
||||
@@ -188,7 +182,7 @@ describe.each([
|
||||
let app: express.Express;
|
||||
let loggerSpy: jest.SpyInstance;
|
||||
let taskBroker: TaskBroker;
|
||||
const catalogClient = catalogServiceMock.mock();
|
||||
const catalogService = catalogServiceMock.mock();
|
||||
const permissionApi = {
|
||||
authorize: jest.fn(),
|
||||
authorizeConditional: jest.fn(),
|
||||
@@ -303,8 +297,7 @@ describe.each([
|
||||
logger: logger,
|
||||
config: new ConfigReader({}),
|
||||
database: createDatabase(),
|
||||
catalogClient,
|
||||
reader: mockUrlReader,
|
||||
catalogService,
|
||||
taskBroker,
|
||||
permissions: permissionApi,
|
||||
auth,
|
||||
@@ -315,7 +308,7 @@ describe.each([
|
||||
});
|
||||
app = express().use(router);
|
||||
|
||||
catalogClient.getEntityByRef.mockImplementation(async ref => {
|
||||
catalogService.getEntityByRef.mockImplementation(async ref => {
|
||||
const { kind } = parseEntityRef(ref);
|
||||
|
||||
if (kind.toLocaleLowerCase() === 'template') {
|
||||
@@ -851,9 +844,9 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
directoryContents: [],
|
||||
});
|
||||
|
||||
expect(catalogClient.getEntityByRef).toHaveBeenCalledTimes(1);
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(catalogClient.getEntityByRef).toHaveBeenCalledWith(
|
||||
expect(catalogService.getEntityByRef).toHaveBeenCalledWith(
|
||||
'user:default/mock',
|
||||
expect.anything(),
|
||||
);
|
||||
@@ -879,8 +872,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
logger: logger,
|
||||
config: new ConfigReader({}),
|
||||
database: createDatabase(),
|
||||
catalogClient,
|
||||
reader: mockUrlReader,
|
||||
catalogService,
|
||||
taskBroker,
|
||||
permissions: permissionApi,
|
||||
auth,
|
||||
@@ -888,7 +880,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
});
|
||||
app = express().use(router);
|
||||
|
||||
catalogClient.getEntityByRef.mockImplementation(async ref => {
|
||||
catalogService.getEntityByRef.mockImplementation(async ref => {
|
||||
const { kind } = parseEntityRef(ref);
|
||||
|
||||
if (kind.toLocaleLowerCase() === 'template') {
|
||||
@@ -1649,8 +1641,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{
|
||||
logger: loggerToWinstonLogger(mockServices.logger.mock()),
|
||||
config: new ConfigReader({}),
|
||||
database: createDatabase(),
|
||||
catalogClient,
|
||||
reader: mockUrlReader,
|
||||
catalogService,
|
||||
taskBroker,
|
||||
permissions: permissionApi,
|
||||
auth,
|
||||
|
||||
@@ -21,12 +21,11 @@ import {
|
||||
DatabaseService,
|
||||
HttpAuthService,
|
||||
LifecycleService,
|
||||
LoggerService,
|
||||
PermissionsService,
|
||||
resolveSafeChildPath,
|
||||
SchedulerService,
|
||||
UrlReaderService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import {
|
||||
CompoundEntityRef,
|
||||
Entity,
|
||||
@@ -81,10 +80,8 @@ import { validate } from 'jsonschema';
|
||||
import { Duration } from 'luxon';
|
||||
import { pathToFileURL } from 'url';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { Logger } from 'winston';
|
||||
import { z } from 'zod';
|
||||
import {
|
||||
createBuiltinActions,
|
||||
DatabaseTaskStore,
|
||||
TaskWorker,
|
||||
TemplateActionRegistry,
|
||||
@@ -115,17 +112,17 @@ import {
|
||||
isTemplatePermissionRuleInput,
|
||||
TemplatePermissionRuleInput,
|
||||
} from './permissions';
|
||||
import { CatalogService } from '@backstage/plugin-catalog-node';
|
||||
|
||||
/**
|
||||
* RouterOptions
|
||||
*/
|
||||
export interface RouterOptions {
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
config: Config;
|
||||
reader: UrlReaderService;
|
||||
lifecycle?: LifecycleService;
|
||||
database: DatabaseService;
|
||||
catalogClient: CatalogApi;
|
||||
catalogService: CatalogService;
|
||||
scheduler?: SchedulerService;
|
||||
actions?: TemplateAction<any, any, any>[];
|
||||
/**
|
||||
@@ -180,9 +177,8 @@ export async function createRouter(
|
||||
const {
|
||||
logger: parentLogger,
|
||||
config,
|
||||
reader,
|
||||
database,
|
||||
catalogClient,
|
||||
catalogService,
|
||||
actions,
|
||||
scheduler,
|
||||
additionalTemplateFilters,
|
||||
@@ -285,18 +281,7 @@ export async function createRouter(
|
||||
workers.push(worker);
|
||||
}
|
||||
|
||||
const actionsToRegister = Array.isArray(actions)
|
||||
? actions
|
||||
: createBuiltinActions({
|
||||
integrations,
|
||||
catalogClient,
|
||||
reader,
|
||||
config,
|
||||
auth,
|
||||
...templateExtensions,
|
||||
});
|
||||
|
||||
actionsToRegister.forEach(action => actionRegistry.register(action));
|
||||
actions?.forEach(action => actionRegistry.register(action));
|
||||
|
||||
const launchWorkers = () => workers.forEach(worker => worker.start());
|
||||
|
||||
@@ -370,16 +355,7 @@ export async function createRouter(
|
||||
try {
|
||||
const credentials = await httpAuth.credentials(req);
|
||||
|
||||
const { token } = await auth.getPluginRequestToken({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const template = await authorizeTemplate(
|
||||
req.params,
|
||||
token,
|
||||
credentials,
|
||||
);
|
||||
const template = await authorizeTemplate(req.params, credentials);
|
||||
|
||||
const parameters = [template.spec.parameters ?? []].flat();
|
||||
|
||||
@@ -458,17 +434,12 @@ export async function createRouter(
|
||||
permissionService: permissions,
|
||||
});
|
||||
|
||||
const { token } = await auth.getPluginRequestToken({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const userEntityRef = auth.isPrincipal(credentials, 'user')
|
||||
? credentials.principal.userEntityRef
|
||||
: undefined;
|
||||
|
||||
const userEntity = userEntityRef
|
||||
? await catalogClient.getEntityByRef(userEntityRef, { token })
|
||||
? await catalogService.getEntityByRef(userEntityRef, { credentials })
|
||||
: undefined;
|
||||
|
||||
let auditLog = `Scaffolding task for ${templateRef}`;
|
||||
@@ -481,7 +452,6 @@ export async function createRouter(
|
||||
|
||||
const template = await authorizeTemplate(
|
||||
{ kind, namespace, name },
|
||||
token,
|
||||
credentials,
|
||||
);
|
||||
|
||||
@@ -529,7 +499,7 @@ export async function createRouter(
|
||||
|
||||
const secrets: InternalTaskSecrets = {
|
||||
...req.body.secrets,
|
||||
backstageToken: token,
|
||||
backstageToken: (credentials as any).token,
|
||||
__initiatorCredentials: JSON.stringify({
|
||||
...credentials,
|
||||
// credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly
|
||||
@@ -887,17 +857,12 @@ export async function createRouter(
|
||||
throw new InputError('Input template is not a template');
|
||||
}
|
||||
|
||||
const { token } = await auth.getPluginRequestToken({
|
||||
onBehalfOf: credentials,
|
||||
targetPluginId: 'catalog',
|
||||
});
|
||||
|
||||
const userEntityRef = auth.isPrincipal(credentials, 'user')
|
||||
? credentials.principal.userEntityRef
|
||||
: undefined;
|
||||
|
||||
const userEntity = userEntityRef
|
||||
? await catalogClient.getEntityByRef(userEntityRef, { token })
|
||||
? await catalogService.getEntityByRef(userEntityRef, { credentials })
|
||||
: undefined;
|
||||
|
||||
const templateRef: string = `${template.kind}:${
|
||||
@@ -963,7 +928,7 @@ export async function createRouter(
|
||||
})),
|
||||
secrets: {
|
||||
...body.secrets,
|
||||
...(token && { backstageToken: token }),
|
||||
backstageToken: (credentials as any).token,
|
||||
},
|
||||
credentials,
|
||||
});
|
||||
@@ -1026,13 +991,12 @@ export async function createRouter(
|
||||
|
||||
async function authorizeTemplate(
|
||||
entityRef: CompoundEntityRef,
|
||||
token: string | undefined,
|
||||
credentials: BackstageCredentials,
|
||||
) {
|
||||
const template = await findTemplate({
|
||||
catalogApi: catalogClient,
|
||||
catalogService,
|
||||
entityRef,
|
||||
token,
|
||||
credentials,
|
||||
});
|
||||
|
||||
if (!isSupportedTemplate(template)) {
|
||||
|
||||
@@ -7601,12 +7601,12 @@ __metadata:
|
||||
dependencies:
|
||||
"@backstage/backend-plugin-api": "workspace:^"
|
||||
"@backstage/backend-test-utils": "workspace:^"
|
||||
"@backstage/catalog-client": "workspace:^"
|
||||
"@backstage/catalog-model": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/config": "workspace:^"
|
||||
"@backstage/errors": "workspace:^"
|
||||
"@backstage/integration": "workspace:^"
|
||||
"@backstage/plugin-catalog-node": "workspace:^"
|
||||
"@backstage/plugin-scaffolder-node": "workspace:^"
|
||||
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
|
||||
"@backstage/types": "workspace:^"
|
||||
@@ -7721,7 +7721,6 @@ __metadata:
|
||||
"@backstage/backend-defaults": "workspace:^"
|
||||
"@backstage/backend-plugin-api": "workspace:^"
|
||||
"@backstage/backend-test-utils": "workspace:^"
|
||||
"@backstage/catalog-client": "workspace:^"
|
||||
"@backstage/catalog-model": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/config": "workspace:^"
|
||||
|
||||
Reference in New Issue
Block a user