From ab161e786eb2bab4e058705f52214057ec959eea Mon Sep 17 00:00:00 2001 From: Mani Marothu Date: Mon, 23 Sep 2024 17:26:47 -0700 Subject: [PATCH 1/3] Created http request plugin Signed-off-by: Mani Marothu --- packages/backend/src/plugins/http-request.ts | 142 +++++++++++++++++++ packages/backend/src/plugins/scaffolder.ts | 2 + 2 files changed, 144 insertions(+) create mode 100644 packages/backend/src/plugins/http-request.ts diff --git a/packages/backend/src/plugins/http-request.ts b/packages/backend/src/plugins/http-request.ts new file mode 100644 index 0000000..fc8d8bd --- /dev/null +++ b/packages/backend/src/plugins/http-request.ts @@ -0,0 +1,142 @@ +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; + +export type Methods = + | 'GET' + | 'OPTIONS' + | 'POST' + | 'UPDATE' + | 'DELETE' + | 'PUT' + | 'PATCH'; + +export type Headers = { + [key: string]: string; +}; +export type Params = { + [key: string]: string; +}; +export type Body = string | undefined; + +export interface HttpOptions { + url: string; + method: string; + headers: Headers; + body?: Body; +} + +export const createHttpRequest = () => { + return createTemplateAction<{ + api: string; + method: Methods; + headers?: Headers; + params?: Params; + body?: any; + }>({ + id: 'cnoe:http:request', + description: 'Sends a HTTP request to APIs with headers and payload', + schema: { + input: { + type: 'object', + required: ['api', 'method'], + properties: { + api: { + type: 'string', + title: 'API Url', + description: 'The url path you want to query', + }, + method: { + type: 'string', + title: 'Method', + description: 'The method type of the request', + enum: [ + 'GET', + 'OPTIONS', + 'POST', + 'UPDATE', + 'DELETE', + 'PUT', + 'PATCH', + ], + }, + headers: { + title: 'Request headers', + description: 'The headers you would like to pass to your request', + type: 'object', + }, + params: { + title: 'Request query params', + description: + 'The query parameters you would like to pass to your request', + type: 'object', + }, + body: { + title: 'Request body', + description: 'The body you would like to pass to your request', + type: ['object', 'string', 'array'], + }, + }, + }, + output: { + type: 'object', + properties: { + code: { + title: 'Response Code', + type: 'string', + }, + }, + }, + }, + async handler(ctx) { + let inputBody: Body = undefined; + let response: any; + + if ( + ctx.input.body && + typeof ctx.input.body !== 'string' && + ctx.input.headers && + ctx.input.headers['content-type'] && + ctx.input.headers['content-type'].includes('application/json') + ) { + inputBody = JSON.stringify(ctx.input.body); + } else { + inputBody = ctx.input.body; + } + + const queryParams: string = ctx.input.params + ? new URLSearchParams(ctx.input.params).toString() + : ''; + const url = + queryParams == '' ? `${ctx.input.api}?${queryParams}` : ctx.input.api; + + ctx.logger.info(`Request Url: ${url}`); + + try { + response = await fetch(url, { + method: ctx.input.method, + headers: ctx.input.headers ? (ctx.input.headers as Headers) : {}, + body: inputBody, + }); + if (!response) { + throw new Error(`Request was aborted as it took longer time`); + } + } catch (e) { + throw new Error(`There was an issue with the request: ${e}`); + } + + if (response.status >= 200 && response.status <= 300) { + ctx.logger.info( + `Request was successful. Status code: ${response.status}`, + ); + } else { + ctx.logger.error( + `There was an issue with request. Status code: ${response.status}`, + ); + throw new Error( + `The Url request is failed with ${response.status} code.`, + ); + } + + ctx.output('code', response.status); + }, + }); +}; \ No newline at end of file diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts index 0b6fb2f..d3d98c1 100644 --- a/packages/backend/src/plugins/scaffolder.ts +++ b/packages/backend/src/plugins/scaffolder.ts @@ -11,6 +11,7 @@ import { getRootLogger } from '@backstage/backend-common'; import { createKubernetesApply } from './k8s-apply'; import { createSanitizeResource } from './sanitize'; import { createVerifyDependency } from './verify'; +import { createHttpRequest } from './http-request' export const cnoeScaffolderActions = createBackendModule({ pluginId: 'scaffolder', @@ -37,6 +38,7 @@ export const cnoeScaffolderActions = createBackendModule({ createKubernetesApply(config), createSanitizeResource(), createVerifyDependency(), + createHttpRequest(), ); }, }); From ff86dd49c2fc56f4dbad16a5c2756952671a13c5 Mon Sep 17 00:00:00 2001 From: Mani Marothu Date: Mon, 23 Sep 2024 17:33:24 -0700 Subject: [PATCH 2/3] fixed typo Signed-off-by: Mani Marothu --- packages/backend/src/plugins/scaffolder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts index d3d98c1..6778934 100644 --- a/packages/backend/src/plugins/scaffolder.ts +++ b/packages/backend/src/plugins/scaffolder.ts @@ -11,7 +11,7 @@ import { getRootLogger } from '@backstage/backend-common'; import { createKubernetesApply } from './k8s-apply'; import { createSanitizeResource } from './sanitize'; import { createVerifyDependency } from './verify'; -import { createHttpRequest } from './http-request' +import { createHttpRequest } from './http-request'; export const cnoeScaffolderActions = createBackendModule({ pluginId: 'scaffolder', From 94e4984cd820d816ec3b8827399f3b2521f53e3b Mon Sep 17 00:00:00 2001 From: Mani Marothu Date: Tue, 24 Sep 2024 10:40:48 -0700 Subject: [PATCH 3/3] Fixed query string issue Signed-off-by: Mani Marothu --- packages/backend/src/plugins/http-request.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/plugins/http-request.ts b/packages/backend/src/plugins/http-request.ts index fc8d8bd..b7ba2da 100644 --- a/packages/backend/src/plugins/http-request.ts +++ b/packages/backend/src/plugins/http-request.ts @@ -106,7 +106,7 @@ export const createHttpRequest = () => { ? new URLSearchParams(ctx.input.params).toString() : ''; const url = - queryParams == '' ? `${ctx.input.api}?${queryParams}` : ctx.input.api; + queryParams ? `${ctx.input.api}?${queryParams}` : ctx.input.api; ctx.logger.info(`Request Url: ${url}`);