Skip to content

Setup

Step 1: Install Rafay frontend plugin

Install the Rafay Backstage frontend plugin package using the command below:

yarn --cwd packages/app add @rafaysystems/backstage-plugin-rafay

Step 2: Configure Rafay Org Account in Backstage

Using Backstage with the Rafay Org requires authentication using the Rafay Org API token. Update the Backstage app-config.yaml file with the Rafay Org URL and your API key.

  1. In the Backstage environment, edit the app-config.yaml file. Example path: /my-backstage-app/app-config.yaml.
  2. Implement the changes outlined below:
app:
-  title: Scaffolded Backstage App
+  title: Rafay Backstage Demo App
  baseUrl: http://localhost:3000

organization:
@@ -50,6 +50,10 @@ proxy:
# '/test':
  #     target: 'https://example.com'
  #     changeOrigin: true
+  '/rs-plugin':
+    target: ${RAFAY_CONSOLE_URL}
+    headers:
+      X-RAFAY-API-KEYID: ${RAFAY_API_KEY}

Note

Following HTTP methods needs to be allowed: GET, POST, PUT, DELETE

  1. Enable Rafay page and verify if the credentials are active by navigating to http://localhost:3000/rafay. Project list should be visible

Edit the App.tsx file at packages/app/src/.

@@ -33,6 +33,7 @@ import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
 import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
 import { RequirePermission } from '@backstage/plugin-permission-react';
 import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-
common/alpha';
+import { RafayPage } from '@rafaysystems/backstage-plugin-rafay';

const app = createApp({
   apis,
@@ -93,6 +94,7 @@ const routes = (
     </Route>
     <Route path="/settings" element={<UserSettingsPage />} />
     <Route path="/catalog-graph" element={<CatalogGraphPage />} />
+    <Route path="/rafay" element={<RafayPage />} />
   </FlatRoutes>
 );

Step 3: GitHub integration

Configure GitHub integration using the instructions outlined here.

Step 4: Install Rafay backend plugin

Install the Rafay Backstage backend plugin package using the command below:

yarn --cwd packages/backend add @rafaysystems/backstage-plugin-rafay-backend

Create a rafay.ts file in the packages/backend/src/plugins folder. Include the following content in the rafay.ts file.

+import { createRouter } from '@rafaysystems/backstage-plugin-rafay-backend'; +import { Router } from 'express';
+import { PluginEnvironment } from '../types';
+
+export default async function createPlugin(
+ env: PluginEnvironment,
+): Promise<Router> {
+ return await createRouter({
+ logger: env.logger,
+ });
+}

Step 5: Register Rafay backend plugin

Edit the index.ts file to register the backend plugin. The index.ts file is located at packages/backend/src/.

@@ -31,6 +31,7 @@ import search from './plugins/search';
 import { PluginEnvironment } from './types';
 import { ServerPermissionClient } from '@backstage/plugin-permission-node';
 import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
+import rafay from './plugins/rafay';
 function makeCreateEnv(config: Config) {
   const root = getRootLogger();
@@ -85,6 +86,7 @@ async function main() {

const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs'));
   const searchEnv = useHotMemoize(module, () => createEnv('search'));
   const appEnv = useHotMemoize(module, () => createEnv('app'));
+  const rafayEnv = useHotMemoize(module, () => createEnv('rafay'));
   const apiRouter = Router();
   apiRouter.use('/catalog', await catalog(catalogEnv));
@@ -93,6 +95,7 @@ async function main() {
   apiRouter.use('/techdocs', await techdocs(techdocsEnv));
   apiRouter.use('/proxy', await proxy(proxyEnv));
   apiRouter.use('/search', await search(searchEnv));
+  apiRouter.use('/rafay-backend', await rafay(rafayEnv));

Verify backend is registered by navigating to http://localhost:7007/api/rafay-backend/health. Response should be {"status":"ok"}.

Step 6: Add/Register templates

Some example templates have been provided for creating resources (environments/clusters/namespaces). These templates can be imported by adding a location to the catalog configuration in the app-config.yaml file. Follow the instructions outlined below:

(a) Add templates

yarn --cwd ppackages/backend add @backstage/integration

(b) Add the template location to the app-config.yaml file

@@ -96,6 +96,12 @@ catalog:
       rules:
         - allow: [User, Group]
+    # Rafay example templates
+ - type: file
+      target: ../../rafay-examples/templates/all.yaml
+ rules:
+        - allow: [Template]
+
     ## Uncomment these lines to add more example data
     # - type: url
     #   target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all.yaml

© Register the Rafay template actions in scaffolder.ts

@@ -3,6 +3,17 @@ import { createRouter } from '@backstage/plugin-scaffolder-backend';
 import { Router } from 'express';
 import type { PluginEnvironment } from '../types';
+import { ScmIntegrations } from '@backstage/integration';

 +import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend';
+import {
+  createNewEKSClusterAction,
+  createNewAKSClusterAction,
+  createNewGKEClusterAction,
+  createNewClusterFromTemplateAction,
+  createNewNamespaceAction,
+  createNewWorkloadAction,
+} from '@rafaysystems/backstage-plugin-rafay-backend';
+
 export default async function createPlugin(
   env: PluginEnvironment,
 ): Promise<Router> {
@@ -10,6 +21,28 @@ export default async function createPlugin(
     discoveryApi: env.discovery,
   });
+  const integrations = ScmIntegrations.fromConfig(env.config);
+
+  const builtInActions = createBuiltinActions({
+    integrations,
+    catalogClient,
+    reader: env.reader,
+    config: env.config,
+  });
+
+  const backendUrl = env.config.getString('backend.baseUrl');
+  const baseUrl = `${backendUrl}/api/proxy/rs-plugin`;
+
+  const actions = [
+    ...builtInActions,
+    createNewEKSClusterAction({ baseUrl }),
+    createNewAKSClusterAction({ baseUrl }),
+    createNewGKEClusterAction({ baseUrl }),
+    createNewClusterFromTemplateAction({ baseUrl }),
+    createNewNamespaceAction({ baseUrl }),
+    createNewWorkloadAction({ baseUrl }),
+  ];
+
   return await createRouter({
     logger: env.logger,
     config: env.config,
@@ -18,5 +51,6 @@ export default async function createPlugin(
     catalogClient,
     identity: env.identity,
     permissions: env.permissions,
+    actions,
}); }

Step 7: Add Entity cards

Edit the EntityPage.tsx file to add the Rafay Org entity cards to the entity page layout. The EntityPage.tsx file is located at packages/app/scr/components/catalog.

@@ -58,6 +58,19 @@ import {
 import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
 import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
+import {
+  EntityClusterInfo,
+  EntityClusterNamespaceList,
+  EntityClusterPodList,
+  EntityNamespaceInfo,
+  EntityNamespacePodList,
+  EntityWorkloadInfo,
+  EntityWorkloadPodList,
+  isRafayPluginEntityTypeWorkload,
+  isRafayPluginEntityTypeNamespace,
+  isRafayPluginEntityTypeCluster,
+} from '@rafaysystems/backstage-plugin-rafay';
+
 const techdocsContent = (
   <EntityTechdocsContent>
     <TechDocsAddons>
@@ -121,13 +134,61 @@ const entityWarningContent = (
</> );
 const overviewContent = (
   <Grid container spacing={3} alignItems="stretch">
     {entityWarningContent}
     <Grid item md={6}>
       <EntityAboutCard variant="gridItem" />
     </Grid>
-    <Grid item md={6} xs={12}>
+    <EntitySwitch>
               +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<EntitySwitch.Case if={isRafayPluginEntityTypeNamespace}>
  <Grid item md={6} xs={12}>
    <EntityNamespaceInfo />
  </Grid>
  <Grid item md={6} xs={12}>
    <EntityNamespacePodList />
  </Grid>
</EntitySwitch.Case>
<EntitySwitch.Case if={isRafayPluginEntityTypeWorkload}>
  <Grid item md={6} xs={12}>
    <EntityWorkloadInfo />
  </Grid>
  <Grid item md={6} xs={12}>
    <EntityWorkloadPodList />
  </Grid>

 +      </EntitySwitch.Case>
+      <EntitySwitch.Case if={isRafayPluginEntityTypeCluster}>
+        <Grid item md={6} xs={12}>
+          <EntityClusterInfo />
+ </Grid>
+        <Grid item md={6} xs={12}>
+          <EntityClusterNamespaceList />
+ </Grid>
+        <Grid item md={6} xs={12}>
+          <EntityClusterPodList />
+ </Grid>
+      </EntitySwitch.Case>
+    </EntitySwitch>
+    {/* <Grid item md={6} xs={12}>
       <EntityCatalogGraphCard variant="gridItem" height={400} />
     </Grid>
@@ -136,7 +197,7 @@ const overviewContent = (
     </Grid>
     <Grid item md={8} xs={12}>
       <EntityHasSubcomponentsCard variant="gridItem" />
-    </Grid>
+    </Grid> */}
</Grid> );