Skip to content

Commit

Permalink
Merge pull request #1223 from mugioka/feat/support-app-in-any-namespa…
Browse files Browse the repository at this point in the history
…ce-with-backstage-plugin-argo-cd-backend

feat(backstage-plugin-argo-cd-backend): support application in any namespace.
  • Loading branch information
Xantier authored Jan 16, 2024
2 parents 58cd632 + cb1faac commit a150cc4
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/lemon-peaches-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@roadiehq/backstage-plugin-argo-cd-backend': minor
---

Support application in any namespace.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import {
} from './types';
import { getArgoConfigByInstanceName } from '../utils/getArgoConfig';

const APP_NAMESPACE_QUERY_PARAM = 'appNamespace';

export class ArgoService implements ArgoServiceApi {
instanceConfigs: InstanceConfig[];

Expand Down Expand Up @@ -83,15 +85,12 @@ export class ArgoService implements ArgoServiceApi {
async getRevisionData(
baseUrl: string,
options: {
name?: string;
selector?: string;
name: string;
namespace?: string;
},
argoToken: string,
revisionID: string,
): Promise<getRevisionDataResp> {
const urlSuffix = options.name
? `/${options.name}`
: `?selector=${options.selector}`;
const requestOptions: RequestInit = {
method: 'GET',
headers: {
Expand All @@ -100,10 +99,12 @@ export class ArgoService implements ArgoServiceApi {
},
};

const resp = await fetch(
`${baseUrl}/api/v1/applications${urlSuffix}/revisions/${revisionID}/metadata`,
requestOptions,
);
let url = `${baseUrl}/api/v1/applications/${options.name}/revisions/${revisionID}/metadata`;
if (options.namespace) {
url = `${url}?${APP_NAMESPACE_QUERY_PARAM}=${options.namespace}`;
}

const resp = await fetch(url, requestOptions);

if (!resp.ok) {
throw new Error(`Request failed with ${resp.status} Error`);
Expand All @@ -116,16 +117,25 @@ export class ArgoService implements ArgoServiceApi {
async findArgoApp(options: {
name?: string;
selector?: string;
namespace?: string;
}): Promise<findArgoAppResp[]> {
if (!options.name && !options.selector) {
throw new Error('name or selector is required');
}
const resp = await Promise.all(
this.instanceConfigs.map(async (argoInstance: any) => {
let getArgoAppDataResp: any;
let token: string;
try {
token = argoInstance.token || (await this.getArgoToken(argoInstance));
} catch (error: any) {
this.logger.error(
`Error getting token from Argo Instance ${argoInstance.name}: ${error.message}`,
);
return null;
}

try {
const token =
argoInstance.token || (await this.getArgoToken(argoInstance));
getArgoAppDataResp = await this.getArgoAppData(
argoInstance.url,
argoInstance.name,
Expand All @@ -134,7 +144,7 @@ export class ArgoService implements ArgoServiceApi {
);
} catch (error: any) {
this.logger.error(
`Error getting token from Argo Instance ${argoInstance.name}: ${error.message}`,
`Error getting Argo App Data from Argo Instance ${argoInstance.name}: ${error.message}`,
);
return null;
}
Expand Down Expand Up @@ -219,15 +229,26 @@ export class ArgoService implements ArgoServiceApi {
options?: {
name?: string;
selector?: string;
namespace?: string;
},
): Promise<any> {
let urlSuffix = '';

if (options?.name) {
urlSuffix = `/${options.name}`;
if (options?.namespace) {
urlSuffix = `${urlSuffix}?${APP_NAMESPACE_QUERY_PARAM}=${options.namespace}`;
}
}

if (options?.selector) {
urlSuffix = `?selector=${options.selector}`;
// add query param for namespace if it exists
if (options?.namespace) {
urlSuffix = `${urlSuffix}&${APP_NAMESPACE_QUERY_PARAM}=${options.namespace}`;
}
}

const requestOptions: RequestInit = {
method: 'GET',
headers: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,13 @@ export function createRouter({

router.get('/find/name/:argoAppName', async (request, response) => {
const argoAppName = request.params.argoAppName;
response.send(await argoSvc.findArgoApp({ name: argoAppName }));
const argoAppNamespace = request.query?.appNamespace;
response.send(
await argoSvc.findArgoApp({
name: argoAppName as string,
namespace: argoAppNamespace as string,
}),
);
});

router.get(
Expand All @@ -111,6 +117,7 @@ export function createRouter({
const revisionID: string = request.params.revisionID;
const argoInstanceName: string = request.params.argoInstanceName;
const argoAppName = request.params.argoAppName;
const argoAppNamespace = request.query?.appNamespace;
logger.info(`Getting info on ${argoAppName}`);
logger.info(`Getting app ${argoAppName} on ${argoInstanceName}`);
const matchedArgoInstance = getArgoConfigByInstanceName({
Expand All @@ -129,7 +136,10 @@ export function createRouter({

const resp = await argoSvc.getRevisionData(
matchedArgoInstance.url,
{ name: argoAppName },
{
name: argoAppName,
namespace: argoAppNamespace as string,
},
token,
revisionID,
);
Expand All @@ -142,6 +152,7 @@ export function createRouter({
async (request, response) => {
const argoInstanceName: string = request.params.argoInstanceName;
const argoAppName = request.params.argoAppName;
const argoAppNamespace = request.query?.appNamespace;
logger.info(`Getting info on ${argoAppName}`);
logger.info(`Getting app ${argoAppName} on ${argoInstanceName}`);
const matchedArgoInstance = getArgoConfigByInstanceName({
Expand All @@ -162,20 +173,28 @@ export function createRouter({
matchedArgoInstance.url,
matchedArgoInstance.name,
token,
{ name: argoAppName },
{ name: argoAppName, namespace: argoAppNamespace as string },
);
return response.send(resp);
},
);
router.get('/find/selector/:argoAppSelector', async (request, response) => {
const argoAppSelector = request.params.argoAppSelector;
response.send(await argoSvc.findArgoApp({ selector: argoAppSelector }));
const argoAppNamespace = request.query?.appNamespace;
logger.info(`Getting apps for selector ${argoAppSelector}`);
response.send(
await argoSvc.findArgoApp({
selector: argoAppSelector,
namespace: argoAppNamespace as string,
}),
);
});
router.get(
'/argoInstance/:argoInstanceName/applications/selector/:argoAppSelector',
async (request, response) => {
const argoInstanceName = request.params.argoInstanceName;
const argoAppSelector = request.params.argoAppSelector;
const argoAppNamespace = request.query?.appNamespace;
logger.info(
`Getting apps for selector ${argoAppSelector} on ${argoInstanceName}`,
);
Expand All @@ -197,7 +216,10 @@ export function createRouter({
matchedArgoInstance.url,
matchedArgoInstance.name,
token,
{ selector: argoAppSelector },
{
selector: argoAppSelector,
namespace: argoAppNamespace as string,
},
);
return response.send(resp);
},
Expand Down

0 comments on commit a150cc4

Please sign in to comment.