Skip to content

Commit

Permalink
feat(aap): support workflow job templates in catalog provider (#674)
Browse files Browse the repository at this point in the history
  • Loading branch information
invincibleJai authored Aug 29, 2023
1 parent c4f4ddd commit c90bc30
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 19 deletions.
2 changes: 1 addition & 1 deletion plugins/aap-backend/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AAP Backstage provider

The AAP Backstage provider plugin synchronizes the AAP content into the [Backstage](https://backstage.io/) catalog.
The AAP Backstage provider plugin synchronizes the AAP job templates and workflow job templates into the [Backstage](https://backstage.io/) catalog.

## For administrators

Expand Down
19 changes: 19 additions & 0 deletions plugins/aap-backend/src/clients/AapResourceConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,22 @@ export function listJobTemplates(
return resData.results as Promise<JobTemplates>;
});
}

export function listWorkflowJobTemplates(
baseUrl: string,
access_token: string,
): Promise<JobTemplates> {
return fetch(`${baseUrl}/api/v2/workflow_job_templates`, {
headers: {
'Content-Type': 'application/json',
Authorization: access_token,
},
method: 'GET',
}).then(async response => {
if (!response.ok) {
throw new Error(response.statusText);
}
const resData = await response.json();
return resData.results as Promise<JobTemplates>;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { TaskRunner } from '@backstage/backend-tasks';
import { ConfigReader } from '@backstage/config';
import { EntityProviderConnection } from '@backstage/plugin-catalog-node';

import { listJobTemplates } from '../clients/AapResourceConnector';
import {
listJobTemplates,
listWorkflowJobTemplates,
} from '../clients/AapResourceConnector';
import { AapResourceEntityProvider } from './AapResourceEntityProvider';

const BASIC_VALID_CONFIG = {
Expand Down Expand Up @@ -39,11 +42,13 @@ const connection = {
jest.mock('../clients/AapResourceConnector', () => ({
...jest.requireActual('../clients/AapResourceConnector'),
listJobTemplates: jest.fn().mockReturnValue({}),
listWorkflowJobTemplates: jest.fn().mockReturnValue({}),
}));

describe('AapResourceEntityProvider', () => {
beforeEach(() => {
(listJobTemplates as jest.Mock).mockClear();
(listWorkflowJobTemplates as jest.Mock).mockClear();
});

it('should return an empty array if no providers are configured', () => {
Expand Down Expand Up @@ -118,14 +123,53 @@ describe('AapResourceEntityProvider', () => {
});

it('should connect and run should resolves', async () => {
(listJobTemplates as jest.Mock).mockReturnValue([
{
url: 'https://aap.com',
name: 'demoJobTemplate',
description: 'test description',
type: 'job_template',
},
]);
(listJobTemplates as jest.Mock).mockReturnValue(
Promise.resolve([
{
url: 'https://aap.com',
name: 'demoJobTemplate',
description: 'test description',
type: 'job_template',
},
]),
);
(listWorkflowJobTemplates as jest.Mock).mockReturnValue(
Promise.resolve([
{
url: 'https://aap.worfkllow.com',
name: 'demoWorkflowJobTemplate',
description: 'test workflow description',
type: 'workflow_job_template',
},
]),
);
const config = new ConfigReader(BASIC_VALID_CONFIG_2);

const aap = AapResourceEntityProvider.fromConfig(config, {
logger: getVoidLogger(),
schedule: { run: jest.fn() } as TaskRunner,
});

for await (const k of aap) {
await k.connect(connection);
await expect(k.run()).resolves.toBeUndefined();
}
});

it('should connect and run should resolves even if one api call fails', async () => {
(listJobTemplates as jest.Mock).mockReturnValue(
Promise.reject(new Error('404')),
);
(listWorkflowJobTemplates as jest.Mock).mockReturnValue(
Promise.resolve([
{
url: 'https://aap.worfkllow.com',
name: 'demoWorkflowJobTemplate',
description: 'test workflow description',
type: 'workflow_job_template',
},
]),
);
const config = new ConfigReader(BASIC_VALID_CONFIG_2);

const aap = AapResourceEntityProvider.fromConfig(config, {
Expand Down
33 changes: 24 additions & 9 deletions plugins/aap-backend/src/providers/AapResourceEntityProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {

import { Logger } from 'winston';

import { listJobTemplates } from '../clients/AapResourceConnector';
import {
listJobTemplates,
listWorkflowJobTemplates,
} from '../clients/AapResourceConnector';
import { JobTemplate } from '../clients/types';
import { readAapApiEntityConfigs } from './config';
import { AapConfig } from './types';
Expand Down Expand Up @@ -111,12 +114,22 @@ export class AapResourceEntityProvider implements EntityProvider {

const entities: Entity[] = [];

const jobTemplates = await listJobTemplates(
this.baseUrl,
this.authorization,
);
const templatesData = await Promise.allSettled([
listJobTemplates(this.baseUrl, this.authorization),
listWorkflowJobTemplates(this.baseUrl, this.authorization),
]);

const templates: JobTemplate[] = [];

templatesData.forEach(results => {
if (results.status === 'fulfilled') {
templates.push(...results.value);
} else if (results.status === 'rejected') {
console.error('Failed to fetch AAP job templates', results.reason);
}
});

for (const template of jobTemplates) {
for (const template of templates) {
const resourceEntity: ResourceEntity =
this.buildApiEntityFromJobTemplate(template);
entities.push(resourceEntity);
Expand All @@ -135,10 +148,12 @@ export class AapResourceEntityProvider implements EntityProvider {
}

private buildApiEntityFromJobTemplate(template: JobTemplate): ResourceEntity {
const templateDetailsUrl = `${this.baseUrl}/#/templates/job_template/${template.id}/details`;
const templateDetailsUrl = `${this.baseUrl}/#/templates/${template.type}/${template.id}/details`;
const jobTemplateTransformedName = `${template.name.replace(/ /g, '_')}-${
template.summary_fields?.organization?.name || template.id
}-${this.env}`;
// format template type i.e job_template to job template
const templateType = template.type.split('_')?.join(' ');

return {
kind: 'Resource',
Expand All @@ -157,12 +172,12 @@ export class AapResourceEntityProvider implements EntityProvider {
},
{
url: `${templateDetailsUrl}`,
title: 'Job Template Details',
title: 'Template Details',
},
],
},
spec: {
type: `${template.type}`,
type: `${templateType}`,
owner: `${this.owner}`,
...(this.system && { system: `${this.system}` }),
},
Expand Down

0 comments on commit c90bc30

Please sign in to comment.