Skip to content

Mle action plugin mft #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions build_and_push_custom_image_to_dockerhub.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
echo "Building and push The TIBCO DeveloperHub custom docker image to DockerHub"

# ---- Configuration ---
# Local AWS profile to use
AWS_PROFILE="mleijdek"
# AWS Region of ECR
AWS_REGION="local"
# AWS Account number
AWS_ACCOUNT_NR="mleijdek"
# Name of the container image repository (in ECR)
CONTAINER_NAME="custdevhub"


# Do the build & push to ECR
cd ./platform-scripts
./local_build_and_push_devhub_container_to_docker.sh "$AWS_PROFILE" "$AWS_REGION" "$AWS_ACCOUNT_NR" "$CONTAINER_NAME"
1 change: 1 addition & 0 deletions packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ const routes = (
{settingsPage}
</Route>
<Route path="/catalog-graph" element={<CatalogGraphPage />} />

</FlatRoutes>
);
export default app.createRoot(
Expand Down
6 changes: 6 additions & 0 deletions packages/app/src/components/Root/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,15 @@ const SidebarCustom = () => {
to="import-flow"
text="Import..."
/>
<SidebarItem
icon={() => <TibcoIcon iconName="pl-icon-upload" />}
to="catalog-import"
text="Register..."
/>
{/* End global nav */}
</SidebarGroup>
<SidebarDivider className={classes.divider} />

<SidebarGroup
icon={<TibcoIcon iconName="pl-icon-settings" />}
to="/settings"
Expand Down
1 change: 1 addition & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@internal/backstage-plugin-scaffolder-backend-module-import-flow": "^1.3.0",
"@octokit/request-error": "^3.0.3",
"app": "link:../app",
"@internal/backstage-plugin-scaffolder-backend-module-mft-actions-backend": "^0.1.0",
"better-sqlite3": "^9.0.0",
"dockerode": "^3.3.1",
"express": "^4.19.2",
Expand Down
9 changes: 7 additions & 2 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { createBackend } from '@backstage/backend-defaults';
import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';
import { createBackendModule } from '@backstage/backend-plugin-api';
import {coreServices, createBackendModule} from '@backstage/backend-plugin-api';
import {
ExtractParametersAction,
createYamlAction,
} from '@internal/backstage-plugin-scaffolder-backend-module-import-flow';
import { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter';
import { NextFunction, Request, Response, Router } from 'express';

import {callMftApi} from '@internal/backstage-plugin-scaffolder-backend-module-mft-actions-backend'

const backend = createBackend();

backend.add(
Expand Down Expand Up @@ -44,10 +46,12 @@ const scaffolderModuleCustomExtensions = createBackendModule({
env.registerInit({
deps: {
scaffolder: scaffolderActionsExtensionPoint,
config: coreServices.rootConfig,
},
async init({ scaffolder }) {
async init({ scaffolder, config }) {
scaffolder.addActions(new (ExtractParametersAction as any)());
scaffolder.addActions(new (createYamlAction as any)());
scaffolder.addActions(new (callMftApi as any)(config));
},
});
},
Expand Down Expand Up @@ -82,4 +86,5 @@ backend.add(import('@backstage/plugin-search-backend/alpha'));
backend.add(import('@backstage/plugin-search-backend-module-catalog/alpha'));
backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha'));

// backend.add(import('backstage-plugin-scaffolder-backend-module-mft-actions-backend'));
backend.start();
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash
set -e
echo "----------------------- Build & push TIBCO Developer Hub container To DockerHub------------------------------";
start_deploy=$(date +%s)
version=v$(date +%s)
# version=v1679073350
# https://hub.docker.com/repository/docker/mleijdek/tibco-dh-custom

# Get Other variables
aws_profile=${1}
aws_region=${2}
aws_account_nr=${3}
container_name=${4}

echo " aws_account_nr: |$aws_account_nr|";
echo " aws_profile: |$aws_profile|";
echo " aws_region: |$aws_region|";
echo "container image repository: |$container_name|"
echo " version: |$version|"

# Step 1] Build the code
cd ./../

#Step 2] Login to docker:
docker login -u mleijdek -p Tcoa4b4b*oct docker.io
#Step 3] Build container
echo "Building container: |mleijdek/$container_name:$version|"
docker build -f ./Dockerfile -t "mleijdek/$container_name:$version" .
cd ./platform-scripts
#Step 4] Tag container
echo " Tag container: |$version|"
docker tag "mleijdek/$container_name:$version" "mleijdek/$container_name:latest"

#Step 5] Push container
##docker push "mleijdek/tibco-dh-custom/$container_name:$version"
echo " Push container: |$version|"
docker push "docker.io/mleijdek/$container_name:$version"

# Command to SSH into the pod
# kubectl exec -n <namespace> --stdin --tty <pod-name> -- /bin/bash

# Command to tail the logs of the pod
# kubectl logs <pod-name> -n <namespace>


# Timing
end_deploy=$(date +%s)
runtime_deploy=$((end_deploy-start_deploy))

convertsecs() {
((h=${1}/3600))
((m=(${1}%3600)/60))
((s=${1}%60))
printf "%02d Hour(s), %02d Minute(s) and %02d Second(s)\n" $h $m $s
}
# Calculate minutes
echo "-------------------------------------------------------------------------";
echo " ------ DOCKER CONTAINER IMAGE UPLOADED !! ------";
echo "-------------------------------------------------------------------------";
echo "-- It took $(convertsecs $runtime_deploy) for the building of the TIBCO Developer Hub custom docker image and pushing it to ECR..."
echo "-------------------------------------------------------------------------";
echo "Now install the custom version of the TIBCO Developer Hub in the control plane, using the following container URL..."
echo "Container Image URL: |$aws_account_nr.dkr.ecr.$aws_region.docker.com/$container_name:$version|"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
14 changes: 14 additions & 0 deletions plugins/scaffolder-backend-module-mft-actions-backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# scaffolder-backend-module-mft-actions

Welcome to the scaffolder-backend-module-mft-actions backend plugin!

_This plugin was created through the Backstage CLI_

## Getting started

Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn
start` in the root directory, and then navigating to [/scaffolder-backend-module-mft-actions/health](http://localhost:7007/api/scaffolder-backend-module-mft-actions/health).

You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

backend.add(import('@backstage/plugin-auth-backend'));
backend.add(import('@backstage/plugin-auth-backend-module-guest-provider'));

backend.start();
49 changes: 49 additions & 0 deletions plugins/scaffolder-backend-module-mft-actions-backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@internal/backstage-plugin-scaffolder-backend-module-mft-actions-backend",
"version": "0.1.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": true,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin"
},
"scripts": {
"start": "backstage-cli package start",
"build": "backstage-cli package build",
"lint": "backstage-cli package lint",
"test": "backstage-cli package test",
"clean": "backstage-cli package clean",
"prepack": "backstage-cli package prepack",
"postpack": "backstage-cli package postpack"
},
"dependencies": {
"@backstage/backend-common": "^0.23.3",
"@backstage/backend-defaults": "^0.4.0",
"@backstage/backend-plugin-api": "^0.7.0",
"@backstage/config": "^1.2.0",
"@backstage/plugin-scaffolder-node": "^0.6.2",
"axios": "^1.7.9",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"node-fetch": "^2.6.7"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.4.4",
"@backstage/cli": "^0.26.10",
"@backstage/plugin-auth-backend": "^0.22.8",
"@backstage/plugin-auth-backend-module-guest-provider": "^0.1.7",
"@types/express": "*",
"@types/supertest": "^2.0.12",
"msw": "^2.3.1",
"supertest": "^6.2.4"
},
"files": [
"dist"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
import axios from 'axios';
import { Config } from '@backstage/config';
import https from "node:https";

const DIV = '-------------------------------------------------------------------------------------------'

export interface MFTConfig {
logger: any;
baseUrl: string;
username: string;
password: string;
}

export async function callMFT(config: MFTConfig, endpoint: string, method = 'get', data?: any) {
let mRes;

try {
mRes = await axios({
method,
url: config.baseUrl + endpoint,
data,
httpsAgent: new https.Agent({
// This is because they use a self-signed certificate TODO: Remove this in production
rejectUnauthorized: false
}),
auth: {
username: config.username,
password: config.password
}
})
} catch (error: any) {
config.logger.error('Error calling MFT API...');
config.logger.error(`Status: ${ error.status}`);
if(error.response?.data) {
let eMes = error.response.data
if(typeof error.response.data === 'object'){
eMes = JSON.stringify(error.response.data, null, 2);
config.logger.error(`Error Data: ${ JSON.stringify(error.response.data, null, 2)}`);
}
config.logger.error(`Error Data: ${ eMes}`);
throw new Error(eMes);
}

// config.logger.error('Error:' , error);
throw error;
}

// if(mRes.data) {
return mRes.data;
// } else {
// return
// }

}


export function callMftApi(config: Config) {
// Get from config
const mftBaseUrl = config.getString('mft.baseUrl');
const mftUser = config.getString('mft.username');
const mftPass = config.getString('mft.password');

if (
!(
mftBaseUrl &&
mftUser &&
mftPass
)
) {
throw new Error(
'Invalid configuration in app-config, missing one of the following property in mft object, baseUrl, username or password',
);
}

return createTemplateAction<{
endpoint: string;
method?: string;
mftInput?: any;
}>({
id: 'tibco:call-mft-api',
schema: {
input: {
required: ['endpoint'],
type: 'object',
properties: {
endpoint: {
type: 'string',
title: 'endpoint',
description: 'The MFT endpoint to call',
},
method: {
type: 'string',
title: 'method',
description: 'method (GET, POST, PUT, DELETE) to use; default is GET',
},
mftInput: {
type: 'object',
title: 'mftInput',
description: 'If method is POST or PUT, this is the data to send',
},

},
},
output: {
required: ['mftResult'],
type: 'object',
properties: {
name: {
type: 'object',
title: 'mftResult',
description: 'The result from MFT',
},
},
},
},
async handler(ctx) {

ctx.logger.info(DIV);
ctx.logger.info('--- CALLING MFT API');
ctx.logger.info(DIV);


ctx.logger.info(`--- MFT Username: ${mftUser}`);
ctx.logger.info(`--- MFT BASE URL: ${mftBaseUrl}`);
ctx.logger.info(`--- MFT Endpoint: ${ctx.input.endpoint}`);
// TODO: Add method and input data
ctx.logger.info(`--- MFT Method: ${ctx.input.method}`);
ctx.logger.info(`--- MFT Input: \n${ JSON.stringify(ctx.input.mftInput, null, 2)}`);

ctx.logger.info(DIV);
ctx.logger.info('--- Calling MFT API...');
const mftResult = await callMFT({
logger: ctx.logger,
baseUrl: mftBaseUrl,
username: mftUser,
password: mftPass
}, ctx.input.endpoint, ctx.input.method, ctx.input.mftInput);
ctx.logger.info(DIV);
ctx.logger.info('--- MFT API Result:');
ctx.logger.info(JSON.stringify(mftResult, null, 2));
ctx.logger.info(DIV);

ctx.output('mftResult', mftResult);
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { callMftApi } from './call-mft-api';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './actions/mft';
9 changes: 9 additions & 0 deletions tibco-developer-hub-fork.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"folders": [
{
"name": "tibco-developer-hub-fork",
"path": "."
}
],
"settings": {}
}
Loading