Merge pull request #9754 from backstage/freben/the-ref-revolution
Remove all usage of, and deprecate, `EntityRef`
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
---
|
||||
'@backstage/plugin-bazaar': patch
|
||||
'@backstage/plugin-code-coverage-backend': patch
|
||||
'@backstage/plugin-jenkins': patch
|
||||
'@backstage/plugin-jenkins-backend': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/plugin-tech-insights-backend': patch
|
||||
'@backstage/plugin-todo-backend': patch
|
||||
---
|
||||
|
||||
Remove usages of `EntityRef` and `parseEntityName` from `@backstage/catalog-model`
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/catalog-model': patch
|
||||
---
|
||||
|
||||
**DEPRECATED**: The `EntityRef` type and `parseEntityName` function are now
|
||||
deprecated, and will soon be removed. This is part of a larger movement toward
|
||||
fixing the poorly named `EntityName` type which should instead have been named
|
||||
`EntityRef`. Please remove any usage of these as soon as possible.
|
||||
@@ -69,7 +69,14 @@ export class CommonValidatorFunctions {
|
||||
// @public @deprecated
|
||||
export function compareEntityToRef(
|
||||
entity: Entity,
|
||||
ref: EntityRef | EntityName,
|
||||
ref:
|
||||
| string
|
||||
| {
|
||||
kind?: string;
|
||||
namespace?: string;
|
||||
name: string;
|
||||
}
|
||||
| EntityName,
|
||||
context?: {
|
||||
defaultKind?: string;
|
||||
defaultNamespace?: string;
|
||||
@@ -212,7 +219,7 @@ export type EntityPolicy = {
|
||||
enforce(entity: Entity): Promise<Entity | undefined>;
|
||||
};
|
||||
|
||||
// @public
|
||||
// @public @deprecated
|
||||
export type EntityRef =
|
||||
| string
|
||||
| {
|
||||
@@ -385,9 +392,15 @@ export class NoForeignRootFieldsEntityPolicy implements EntityPolicy {
|
||||
export const ORIGIN_LOCATION_ANNOTATION =
|
||||
'backstage.io/managed-by-origin-location';
|
||||
|
||||
// @public
|
||||
// @public @deprecated
|
||||
export function parseEntityName(
|
||||
ref: EntityRef,
|
||||
ref:
|
||||
| string
|
||||
| {
|
||||
kind?: string;
|
||||
namespace?: string;
|
||||
name: string;
|
||||
},
|
||||
context?: {
|
||||
defaultKind?: string;
|
||||
defaultNamespace?: string;
|
||||
@@ -396,7 +409,13 @@ export function parseEntityName(
|
||||
|
||||
// @public
|
||||
export function parseEntityRef(
|
||||
ref: EntityRef,
|
||||
ref:
|
||||
| string
|
||||
| {
|
||||
kind?: string;
|
||||
namespace?: string;
|
||||
name: string;
|
||||
},
|
||||
context?: {
|
||||
defaultKind: string;
|
||||
defaultNamespace: string;
|
||||
@@ -405,7 +424,13 @@ export function parseEntityRef(
|
||||
|
||||
// @public
|
||||
export function parseEntityRef(
|
||||
ref: EntityRef,
|
||||
ref:
|
||||
| string
|
||||
| {
|
||||
kind?: string;
|
||||
namespace?: string;
|
||||
name: string;
|
||||
},
|
||||
context?: {
|
||||
defaultKind: string;
|
||||
},
|
||||
@@ -417,7 +442,13 @@ export function parseEntityRef(
|
||||
|
||||
// @public
|
||||
export function parseEntityRef(
|
||||
ref: EntityRef,
|
||||
ref:
|
||||
| string
|
||||
| {
|
||||
kind?: string;
|
||||
namespace?: string;
|
||||
name: string;
|
||||
},
|
||||
context?: {
|
||||
defaultNamespace: string;
|
||||
},
|
||||
|
||||
@@ -194,12 +194,12 @@ describe('ref', () => {
|
||||
});
|
||||
expect(parseEntityRef('a:c')).toEqual({
|
||||
kind: 'a',
|
||||
namespace: undefined,
|
||||
namespace: 'default',
|
||||
name: 'c',
|
||||
});
|
||||
expect(parseEntityRef('c')).toEqual({
|
||||
kind: undefined,
|
||||
namespace: undefined,
|
||||
namespace: 'default',
|
||||
name: 'c',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EntityName, EntityRef } from '../types';
|
||||
import { DEFAULT_NAMESPACE } from './constants';
|
||||
import { EntityName } from '../types';
|
||||
import { Entity } from './Entity';
|
||||
|
||||
function parseRefString(ref: string): {
|
||||
@@ -76,13 +76,14 @@ export type EntityRefContext = {
|
||||
* otherwise specified as part of the options, and will throw an error if no
|
||||
* kind was specified in the input reference and no default kind was given.
|
||||
*
|
||||
* @deprecated Please use parseEntityRef instead
|
||||
* @public
|
||||
* @param ref - The reference to parse
|
||||
* @param context - The context of defaults that the parsing happens within
|
||||
* @returns A complete entity name
|
||||
*/
|
||||
export function parseEntityName(
|
||||
ref: EntityRef,
|
||||
ref: string | { kind?: string; namespace?: string; name: string },
|
||||
context: {
|
||||
/** The default kind, if none is given in the reference */
|
||||
defaultKind?: string;
|
||||
@@ -119,7 +120,7 @@ export function parseEntityName(
|
||||
* @returns The compound form of the reference
|
||||
*/
|
||||
export function parseEntityRef(
|
||||
ref: EntityRef,
|
||||
ref: string | { kind?: string; namespace?: string; name: string },
|
||||
context?: { defaultKind: string; defaultNamespace: string },
|
||||
): EntityName;
|
||||
/**
|
||||
@@ -128,7 +129,7 @@ export function parseEntityRef(
|
||||
* @public
|
||||
*/
|
||||
export function parseEntityRef(
|
||||
ref: EntityRef,
|
||||
ref: string | { kind?: string; namespace?: string; name: string },
|
||||
context?: { defaultKind: string },
|
||||
): {
|
||||
kind: string;
|
||||
@@ -141,7 +142,7 @@ export function parseEntityRef(
|
||||
* @public
|
||||
*/
|
||||
export function parseEntityRef(
|
||||
ref: EntityRef,
|
||||
ref: string | { kind?: string; namespace?: string; name: string },
|
||||
context?: { defaultNamespace: string },
|
||||
): {
|
||||
kind?: string;
|
||||
@@ -154,7 +155,7 @@ export function parseEntityRef(
|
||||
* @public
|
||||
*/
|
||||
export function parseEntityRef(
|
||||
ref: EntityRef,
|
||||
ref: string | { kind?: string; namespace?: string; name: string },
|
||||
context: {
|
||||
/** The default kind, if none is given in the reference */
|
||||
defaultKind?: string;
|
||||
@@ -170,11 +171,13 @@ export function parseEntityRef(
|
||||
throw new Error(`Entity reference must not be empty`);
|
||||
}
|
||||
|
||||
const defaultNamespace = context.defaultNamespace || DEFAULT_NAMESPACE;
|
||||
|
||||
if (typeof ref === 'string') {
|
||||
const parsed = parseRefString(ref);
|
||||
return {
|
||||
kind: parsed.kind ?? context.defaultKind,
|
||||
namespace: parsed.namespace ?? context.defaultNamespace,
|
||||
namespace: parsed.namespace ?? defaultNamespace,
|
||||
name: parsed.name,
|
||||
};
|
||||
}
|
||||
@@ -190,7 +193,7 @@ export function parseEntityRef(
|
||||
|
||||
return {
|
||||
kind: kind ?? context.defaultKind,
|
||||
namespace: namespace ?? context.defaultNamespace,
|
||||
namespace: namespace ?? defaultNamespace,
|
||||
name,
|
||||
};
|
||||
}
|
||||
@@ -249,7 +252,10 @@ export function stringifyEntityRef(
|
||||
*/
|
||||
export function compareEntityToRef(
|
||||
entity: Entity,
|
||||
ref: EntityRef | EntityName,
|
||||
ref:
|
||||
| string
|
||||
| { kind?: string; namespace?: string; name: string }
|
||||
| EntityName,
|
||||
context?: {
|
||||
/** The default kind, if none is given in the reference */
|
||||
defaultKind?: string;
|
||||
|
||||
@@ -40,6 +40,7 @@ export type EntityName = {
|
||||
* A reference by name to an entity, either as a compact string representation,
|
||||
* or as a compound reference structure.
|
||||
*
|
||||
* @deprecated Please use string directly, or EntityName (depending on what you actually need)
|
||||
* @remarks
|
||||
*
|
||||
* The string representation is on the form `[<kind>:][<namespace>/]<name>`.
|
||||
|
||||
@@ -47,7 +47,6 @@ import useAsyncFn from 'react-use/lib/useAsyncFn';
|
||||
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
|
||||
import {
|
||||
parseEntityName,
|
||||
stringifyEntityRef,
|
||||
Entity,
|
||||
parseEntityRef,
|
||||
@@ -150,7 +149,7 @@ export const HomePageBazaarInfoCard = ({
|
||||
|
||||
const getEntityPageLink = () => {
|
||||
if (bazaarProject?.value?.entityRef) {
|
||||
const { name, kind, namespace } = parseEntityName(
|
||||
const { name, kind, namespace } = parseEntityRef(
|
||||
bazaarProject.value.entityRef,
|
||||
);
|
||||
return entityLink({ kind, namespace, name });
|
||||
|
||||
@@ -107,7 +107,7 @@ export const SortView = () => {
|
||||
if (catalogEntityRefs) {
|
||||
bazaarProjects.value?.forEach(async (project: BazaarProject) => {
|
||||
if (project.entityRef) {
|
||||
if (!catalogEntityRefs?.includes(project.entityRef as string)) {
|
||||
if (!catalogEntityRefs?.includes(project.entityRef)) {
|
||||
await bazaarApi.updateProject({
|
||||
...project,
|
||||
entityRef: null,
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EntityRef } from '@backstage/catalog-model';
|
||||
|
||||
export type Member = {
|
||||
itemId: number;
|
||||
userId: string;
|
||||
@@ -30,7 +28,7 @@ export type Size = 'small' | 'medium' | 'large';
|
||||
export type BazaarProject = {
|
||||
name: string;
|
||||
id: number;
|
||||
entityRef?: EntityRef;
|
||||
entityRef?: string;
|
||||
community: string;
|
||||
status: Status;
|
||||
description: string;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { resolvePackagePath } from '@backstage/backend-common';
|
||||
import { NotFoundError } from '@backstage/errors';
|
||||
import { parseEntityName, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { Knex } from 'knex';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { aggregateCoverage } from './CoverageUtils';
|
||||
@@ -103,7 +103,7 @@ export class CodeCoverageDatabase implements CodeCoverageStore {
|
||||
.map(r => JSON.parse(r.coverage))
|
||||
.map(c => aggregateCoverage(c));
|
||||
|
||||
const entityName = parseEntityName(entity);
|
||||
const entityName = parseEntityRef(entity);
|
||||
|
||||
return {
|
||||
entity: {
|
||||
|
||||
@@ -34,9 +34,8 @@ import { Cobertura } from './converter/cobertura';
|
||||
import { Jacoco } from './converter/jacoco';
|
||||
import { Converter } from './converter';
|
||||
import {
|
||||
EntityRef,
|
||||
getEntitySourceLocation,
|
||||
parseEntityName,
|
||||
parseEntityRef,
|
||||
} from '@backstage/catalog-model';
|
||||
|
||||
export interface RouterOptions {
|
||||
@@ -78,7 +77,7 @@ export const makeRouter = async (
|
||||
*/
|
||||
router.get('/report', async (req, res) => {
|
||||
const { entity } = req.query;
|
||||
const entityName = parseEntityName(entity as EntityRef);
|
||||
const entityName = parseEntityRef(entity as string);
|
||||
const entityLookup = await catalogApi.getEntityByName(entityName);
|
||||
if (!entityLookup) {
|
||||
throw new NotFoundError(`No entity found matching ${entity}`);
|
||||
@@ -101,7 +100,7 @@ export const makeRouter = async (
|
||||
*/
|
||||
router.get('/history', async (req, res) => {
|
||||
const { entity } = req.query;
|
||||
const entityName = parseEntityName(entity as EntityRef);
|
||||
const entityName = parseEntityRef(entity as string);
|
||||
const entityLookup = await catalogApi.getEntityByName(entityName);
|
||||
if (!entityLookup) {
|
||||
throw new NotFoundError(`No entity found matching ${entity}`);
|
||||
@@ -120,7 +119,7 @@ export const makeRouter = async (
|
||||
*/
|
||||
router.get('/file-content', async (req, res) => {
|
||||
const { entity, path } = req.query;
|
||||
const entityName = parseEntityName(entity as EntityRef);
|
||||
const entityName = parseEntityRef(entity as string);
|
||||
const entityLookup = await catalogApi.getEntityByName(entityName);
|
||||
if (!entityLookup) {
|
||||
throw new NotFoundError(`No entity found matching ${entity}`);
|
||||
@@ -172,7 +171,7 @@ export const makeRouter = async (
|
||||
*/
|
||||
router.post('/report', async (req, res) => {
|
||||
const { entity, coverageType } = req.query;
|
||||
const entityName = parseEntityName(entity as EntityRef);
|
||||
const entityName = parseEntityRef(entity as string);
|
||||
const entityLookup = await catalogApi.getEntityByName(entityName);
|
||||
if (!entityLookup) {
|
||||
throw new NotFoundError(`No entity found matching ${entity}`);
|
||||
|
||||
@@ -18,7 +18,7 @@ import { createServiceBuilder } from '@backstage/backend-common';
|
||||
import { Server } from 'http';
|
||||
import { Logger } from 'winston';
|
||||
import { createRouter } from './router';
|
||||
import { EntityRef } from '@backstage/catalog-model';
|
||||
import { EntityName } from '@backstage/catalog-model';
|
||||
import { JenkinsInfo } from './jenkinsInfoProvider';
|
||||
|
||||
export interface ServerOptions {
|
||||
@@ -35,7 +35,7 @@ export async function startStandaloneServer(
|
||||
const router = await createRouter({
|
||||
logger,
|
||||
jenkinsInfoProvider: {
|
||||
async getInstance(_: { entityRef: EntityRef }): Promise<JenkinsInfo> {
|
||||
async getInstance(_: { entityRef: EntityName }): Promise<JenkinsInfo> {
|
||||
return { baseUrl: 'https://example.com/', jobFullName: 'build-foo' };
|
||||
},
|
||||
},
|
||||
|
||||
@@ -10,7 +10,6 @@ import { BackstagePlugin } from '@backstage/core-plugin-api';
|
||||
import { DiscoveryApi } from '@backstage/core-plugin-api';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import type { EntityName } from '@backstage/catalog-model';
|
||||
import type { EntityRef } from '@backstage/catalog-model';
|
||||
import { IdentityApi } from '@backstage/core-plugin-api';
|
||||
import { InfoCardVariants } from '@backstage/core-components';
|
||||
import { RouteRef } from '@backstage/core-plugin-api';
|
||||
@@ -55,7 +54,7 @@ export interface JenkinsApi {
|
||||
}): Promise<Build>;
|
||||
// Warning: (ae-forgotten-export) The symbol "Project" needs to be exported by the entry point index.d.ts
|
||||
getProjects(options: {
|
||||
entity: EntityRef;
|
||||
entity: EntityName;
|
||||
filter: {
|
||||
branch?: string;
|
||||
};
|
||||
@@ -82,31 +81,20 @@ export class JenkinsClient implements JenkinsApi {
|
||||
identityApi: IdentityApi;
|
||||
});
|
||||
// (undocumented)
|
||||
getBuild({
|
||||
entity,
|
||||
jobFullName,
|
||||
buildNumber,
|
||||
}: {
|
||||
getBuild(options: {
|
||||
entity: EntityName;
|
||||
jobFullName: string;
|
||||
buildNumber: string;
|
||||
}): Promise<Build>;
|
||||
// (undocumented)
|
||||
getProjects({
|
||||
entity,
|
||||
filter,
|
||||
}: {
|
||||
getProjects(options: {
|
||||
entity: EntityName;
|
||||
filter: {
|
||||
branch?: string;
|
||||
};
|
||||
}): Promise<Project[]>;
|
||||
// (undocumented)
|
||||
retry({
|
||||
entity,
|
||||
jobFullName,
|
||||
buildNumber,
|
||||
}: {
|
||||
retry(options: {
|
||||
entity: EntityName;
|
||||
jobFullName: string;
|
||||
buildNumber: string;
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
DiscoveryApi,
|
||||
IdentityApi,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import type { EntityName, EntityRef } from '@backstage/catalog-model';
|
||||
import type { EntityName } from '@backstage/catalog-model';
|
||||
import { ResponseError } from '@backstage/errors';
|
||||
|
||||
export const jenkinsApiRef = createApiRef<JenkinsApi>({
|
||||
@@ -80,7 +80,7 @@ export interface JenkinsApi {
|
||||
*/
|
||||
getProjects(options: {
|
||||
/** the entity whose jobs should be retrieved. */
|
||||
entity: EntityRef;
|
||||
entity: EntityName;
|
||||
/** a filter on jobs. Currently this just takes a branch (and assumes certain structures in jenkins) */
|
||||
filter: { branch?: string };
|
||||
}): Promise<Project[]>;
|
||||
@@ -117,13 +117,11 @@ export class JenkinsClient implements JenkinsApi {
|
||||
this.identityApi = options.identityApi;
|
||||
}
|
||||
|
||||
async getProjects({
|
||||
entity,
|
||||
filter,
|
||||
}: {
|
||||
async getProjects(options: {
|
||||
entity: EntityName;
|
||||
filter: { branch?: string };
|
||||
}): Promise<Project[]> {
|
||||
const { entity, filter } = options;
|
||||
const url = new URL(
|
||||
`${await this.discoveryApi.getBaseUrl(
|
||||
'jenkins',
|
||||
@@ -158,15 +156,12 @@ export class JenkinsClient implements JenkinsApi {
|
||||
);
|
||||
}
|
||||
|
||||
async getBuild({
|
||||
entity,
|
||||
jobFullName,
|
||||
buildNumber,
|
||||
}: {
|
||||
async getBuild(options: {
|
||||
entity: EntityName;
|
||||
jobFullName: string;
|
||||
buildNumber: string;
|
||||
}): Promise<Build> {
|
||||
const { entity, jobFullName, buildNumber } = options;
|
||||
const url = `${await this.discoveryApi.getBaseUrl(
|
||||
'jenkins',
|
||||
)}/v1/entity/${encodeURIComponent(entity.namespace)}/${encodeURIComponent(
|
||||
@@ -186,15 +181,12 @@ export class JenkinsClient implements JenkinsApi {
|
||||
return (await response.json()).build;
|
||||
}
|
||||
|
||||
async retry({
|
||||
entity,
|
||||
jobFullName,
|
||||
buildNumber,
|
||||
}: {
|
||||
async retry(options: {
|
||||
entity: EntityName;
|
||||
jobFullName: string;
|
||||
buildNumber: string;
|
||||
}): Promise<void> {
|
||||
const { entity, jobFullName, buildNumber } = options;
|
||||
const url = `${await this.discoveryApi.getBaseUrl(
|
||||
'jenkins',
|
||||
)}/v1/entity/${encodeURIComponent(entity.namespace)}/${encodeURIComponent(
|
||||
|
||||
@@ -20,11 +20,11 @@ import {
|
||||
ANNOTATION_LOCATION,
|
||||
parseLocationRef,
|
||||
ANNOTATION_SOURCE_LOCATION,
|
||||
EntityRef,
|
||||
parseEntityRef,
|
||||
EntityName,
|
||||
DEFAULT_NAMESPACE,
|
||||
} from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { assertError, ConflictError, NotFoundError } from '@backstage/errors';
|
||||
import { assertError, InputError, NotFoundError } from '@backstage/errors';
|
||||
import {
|
||||
TemplateEntityV1beta2,
|
||||
TemplateEntityV1beta3,
|
||||
@@ -87,47 +87,29 @@ export function getEntityBaseUrl(entity: Entity): string | undefined {
|
||||
}
|
||||
|
||||
/**
|
||||
* Will use the provided CatalogApi to go find the template entity ref that is provided with and additional token
|
||||
* Returns the first matching template, throws a NotFoundError or ConflictError if 0 or multiple templates are found.
|
||||
* Will use the provided CatalogApi to go find the given template entity with an additional token.
|
||||
* Returns the matching template, or throws a NotFoundError if no such template existed.
|
||||
*/
|
||||
export async function findTemplate({
|
||||
entityRef,
|
||||
token,
|
||||
catalogApi,
|
||||
}: {
|
||||
entityRef: EntityRef;
|
||||
export async function findTemplate(options: {
|
||||
entityRef: EntityName;
|
||||
token?: string;
|
||||
catalogApi: CatalogApi;
|
||||
}): Promise<TemplateEntityV1beta3 | TemplateEntityV1beta2> {
|
||||
const parsedEntityRef = parseEntityRef(entityRef, {
|
||||
defaultKind: 'template',
|
||||
defaultNamespace: 'default',
|
||||
});
|
||||
const { items } = await catalogApi.getEntities(
|
||||
{
|
||||
filter: {
|
||||
kind: 'template',
|
||||
'metadata.name': parsedEntityRef.name,
|
||||
'metadata.namespace': parsedEntityRef.namespace,
|
||||
},
|
||||
},
|
||||
{
|
||||
token,
|
||||
},
|
||||
);
|
||||
const { entityRef, token, catalogApi } = options;
|
||||
|
||||
const templates = items.filter(
|
||||
(entity): entity is TemplateEntityV1beta3 | TemplateEntityV1beta2 =>
|
||||
entity.kind === 'Template',
|
||||
);
|
||||
|
||||
if (templates.length !== 1) {
|
||||
if (templates.length > 1) {
|
||||
throw new ConflictError('Templates lookup resulted in multiple matches');
|
||||
} else {
|
||||
throw new NotFoundError('Template not found');
|
||||
}
|
||||
if (entityRef.namespace.toLocaleLowerCase('en-US') !== DEFAULT_NAMESPACE) {
|
||||
throw new InputError(
|
||||
`Invalid namespace, only '${DEFAULT_NAMESPACE}' namespace is supported`,
|
||||
);
|
||||
}
|
||||
if (entityRef.kind.toLocaleLowerCase('en-US') !== 'template') {
|
||||
throw new InputError(`Invalid kind, only 'Template' kind is supported`);
|
||||
}
|
||||
|
||||
return templates[0];
|
||||
const template = await catalogApi.getEntityByName(entityRef, { token });
|
||||
if (!template) {
|
||||
throw new NotFoundError(`Template ${entityRef} not found`);
|
||||
}
|
||||
|
||||
return template as TemplateEntityV1beta3 | TemplateEntityV1beta2;
|
||||
}
|
||||
|
||||
@@ -50,10 +50,10 @@ import request from 'supertest';
|
||||
import { createRouter, DatabaseTaskStore, TaskBroker } from '../index';
|
||||
import { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';
|
||||
|
||||
const createCatalogClient = (templates: any[] = []) =>
|
||||
const createCatalogClient = (template: any) =>
|
||||
({
|
||||
getEntities: async () => ({ items: templates }),
|
||||
} as CatalogApi);
|
||||
getEntityByName: async () => template,
|
||||
} as unknown as CatalogApi);
|
||||
|
||||
function createDatabase(): PluginDatabaseManager {
|
||||
return DatabaseManager.fromConfig(
|
||||
@@ -120,7 +120,7 @@ describe('createRouter', () => {
|
||||
logger: getVoidLogger(),
|
||||
config: new ConfigReader({}),
|
||||
database: createDatabase(),
|
||||
catalogClient: createCatalogClient([template]),
|
||||
catalogClient: createCatalogClient(template),
|
||||
containerRunner: new DockerContainerRunner({} as any),
|
||||
reader: mockUrlReader,
|
||||
taskBroker,
|
||||
|
||||
@@ -20,7 +20,10 @@ import {
|
||||
UrlReader,
|
||||
} from '@backstage/backend-common';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import {
|
||||
DEFAULT_NAMESPACE,
|
||||
stringifyEntityRef,
|
||||
} from '@backstage/catalog-model';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { InputError, NotFoundError } from '@backstage/errors';
|
||||
@@ -141,18 +144,6 @@ export async function createRouter(
|
||||
'/v2/templates/:namespace/:kind/:name/parameter-schema',
|
||||
async (req, res) => {
|
||||
const { namespace, kind, name } = req.params;
|
||||
|
||||
if (namespace !== 'default') {
|
||||
throw new InputError(
|
||||
`Invalid namespace, only 'default' namespace is supported`,
|
||||
);
|
||||
}
|
||||
if (kind.toLowerCase() !== 'template') {
|
||||
throw new InputError(
|
||||
`Invalid kind, only 'Template' kind is supported`,
|
||||
);
|
||||
}
|
||||
|
||||
const template = await findTemplate({
|
||||
catalogApi: catalogClient,
|
||||
entityRef: { kind, namespace, name },
|
||||
@@ -188,16 +179,13 @@ export async function createRouter(
|
||||
})
|
||||
.post('/v2/tasks', async (req, res) => {
|
||||
const templateName: string = req.body.templateName;
|
||||
const { kind, namespace } = { kind: 'template', namespace: 'default' };
|
||||
const kind = 'template';
|
||||
const namespace = DEFAULT_NAMESPACE;
|
||||
const values = req.body.values;
|
||||
const token = getBearerToken(req.headers.authorization);
|
||||
const template = await findTemplate({
|
||||
catalogApi: catalogClient,
|
||||
entityRef: {
|
||||
name: templateName,
|
||||
kind,
|
||||
namespace,
|
||||
},
|
||||
entityRef: { kind, namespace, name: templateName },
|
||||
token: getBearerToken(req.headers.authorization),
|
||||
});
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { parseEntityName } from '@backstage/catalog-model';
|
||||
import { parseEntityRef } from '@backstage/catalog-model';
|
||||
import { entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { Box } from '@material-ui/core';
|
||||
import LanguageIcon from '@material-ui/icons/Language';
|
||||
@@ -57,7 +57,7 @@ export const TaskPageLinks = ({ output }: TaskPageLinksProps) => {
|
||||
.filter(({ url, entityRef }) => url || entityRef)
|
||||
.map(({ url, entityRef, title, icon }) => {
|
||||
if (entityRef) {
|
||||
const entityName = parseEntityName(entityRef);
|
||||
const entityName = parseEntityRef(entityRef);
|
||||
const target = entityRoute(entityName);
|
||||
return { title, icon, url: target };
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import { rsort } from 'semver';
|
||||
import { groupBy, omit } from 'lodash';
|
||||
import { DateTime } from 'luxon';
|
||||
import { Logger } from 'winston';
|
||||
import { parseEntityName, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
|
||||
import { isMaxItems, isTtl } from '../fact/factRetrievers/utils';
|
||||
|
||||
type Transaction = Knex.Transaction;
|
||||
@@ -161,7 +161,7 @@ export class TechInsightsDatabase implements TechInsightsStore {
|
||||
|
||||
return groupBy(
|
||||
results.map(it => {
|
||||
const { namespace, kind, name } = parseEntityName(it.entity);
|
||||
const { namespace, kind, name } = parseEntityRef(it.entity);
|
||||
const timestamp =
|
||||
typeof it.timestamp === 'string'
|
||||
? DateTime.fromISO(it.timestamp)
|
||||
@@ -253,7 +253,7 @@ export class TechInsightsDatabase implements TechInsightsStore {
|
||||
|
||||
private dbFactRowsToTechInsightFacts(rows: RawDbFactRow[]) {
|
||||
return rows.reduce((acc, it) => {
|
||||
const { namespace, kind, name } = parseEntityName(it.entity);
|
||||
const { namespace, kind, name } = parseEntityRef(it.entity);
|
||||
const timestamp =
|
||||
typeof it.timestamp === 'string'
|
||||
? DateTime.fromISO(it.timestamp)
|
||||
|
||||
@@ -28,8 +28,7 @@ import { DateTime } from 'luxon';
|
||||
import { PersistenceContext } from './persistence/persistenceContext';
|
||||
import {
|
||||
EntityName,
|
||||
EntityRef,
|
||||
parseEntityName,
|
||||
parseEntityRef,
|
||||
stringifyEntityRef,
|
||||
} from '@backstage/catalog-model';
|
||||
import { errorHandler } from '@backstage/backend-common';
|
||||
@@ -130,7 +129,7 @@ export async function createRouter<
|
||||
*/
|
||||
router.get('/facts/latest', async (req, res) => {
|
||||
const { entity } = req.query;
|
||||
const { namespace, kind, name } = parseEntityName(entity as EntityRef);
|
||||
const { namespace, kind, name } = parseEntityRef(entity as string);
|
||||
const ids = req.query.ids as string[];
|
||||
return res.send(
|
||||
await techInsightsStore.getLatestFactsByIds(
|
||||
@@ -145,7 +144,7 @@ export async function createRouter<
|
||||
*/
|
||||
router.get('/facts/range', async (req, res) => {
|
||||
const { entity } = req.query;
|
||||
const { namespace, kind, name } = parseEntityName(entity as EntityRef);
|
||||
const { namespace, kind, name } = parseEntityRef(entity as string);
|
||||
|
||||
const ids = req.query.ids as string[];
|
||||
const startDatetime = DateTime.fromISO(req.query.startDatetime as string);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EntityName, parseEntityName } from '@backstage/catalog-model';
|
||||
import { EntityName, parseEntityRef } from '@backstage/catalog-model';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import express from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
@@ -55,7 +55,7 @@ export async function createRouter(
|
||||
let entity: EntityName | undefined = undefined;
|
||||
if (entityRef) {
|
||||
try {
|
||||
entity = parseEntityName(entityRef);
|
||||
entity = parseEntityRef(entityRef);
|
||||
} catch (error) {
|
||||
throw new InputError(`Invalid entity ref, ${error}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user