@terasky/backstage-plugin-vcf-automation 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,257 @@
1
+ # vcf-automation
2
+
3
+ Welcome to the vcf-automation plugin!
4
+
5
+ [![npm latest version](https://img.shields.io/npm/v/@terasky/backstage-plugin-vcf-automation/latest.svg)](https://www.npmjs.com/package/@terasky/backstage-plugin-vcf-automation)
6
+
7
+ ## Description
8
+
9
+ The `vcf-automation` plugin for Backstage provides visibility into VCF deployments, resources, and projects. It offers detailed views of deployment operations, resource states, and project configurations. The plugin integrates with Backstage's permission framework to ensure secure access control.
10
+
11
+ ## Prerequisites
12
+
13
+ Before installing this plugin, ensure you have:
14
+
15
+ 1. [VCF Automation Backend Plugin](../vcf-automation-backend/README.md) - Required for API integration
16
+ 2. [VCF Ingestor Plugin](../vcf-ingestor/README.md) - Required for entity synchronization
17
+
18
+ ## Installation
19
+
20
+ ### 1. Install the Plugin
21
+
22
+ Add the plugin to your Backstage project:
23
+
24
+ ```bash
25
+ # From your Backstage root directory
26
+ yarn --cwd packages/app add @terasky/backstage-plugin-vcf-automation
27
+ ```
28
+
29
+ ### 2. Register the Plugin
30
+
31
+ Add the plugin to your app's APIs in `packages/app/src/apis.ts`:
32
+
33
+ ```typescript
34
+ import {
35
+ vcfAutomationApiRef,
36
+ VcfAutomationClient,
37
+ } from '@terasky/backstage-plugin-vcf-automation';
38
+
39
+ export const apis: AnyApiFactory[] = [
40
+ // ... other API factories
41
+ createApiFactory({
42
+ api: vcfAutomationApiRef,
43
+ deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },
44
+ factory: ({ discoveryApi, identityApi }) =>
45
+ new VcfAutomationClient({ discoveryApi, identityApi }),
46
+ }),
47
+ ];
48
+ ```
49
+ ### 3. Add to your App.tsx file
50
+
51
+ ```typescript
52
+ import { vcfAutomationPlugin } from '@terasky/backstage-plugin-vcf-automation';
53
+
54
+ const app = createApp({
55
+ apis,
56
+ bindRoutes({ bind }) {
57
+
58
+ ...
59
+
60
+ bind(vcfAutomationPlugin.externalRoutes, {
61
+ catalogIndex: catalogPlugin.routes.catalogIndex,
62
+ });
63
+
64
+ ...
65
+
66
+ },
67
+
68
+ ```
69
+ ### 4. Add Components to Entity Pages
70
+
71
+ Add the VCF Automation components to your entity pages in `packages/app/src/components/catalog/EntityPage.tsx`:
72
+
73
+ ```typescript
74
+ import {
75
+ VCFAutomationDeploymentOverview,
76
+ VCFAutomationDeploymentDetails,
77
+ VCFAutomationVSphereVMOverview,
78
+ VCFAutomationVSphereVMDetails,
79
+ VCFAutomationGenericResourceOverview,
80
+ VCFAutomationGenericResourceDetails,
81
+ VCFAutomationProjectOverview,
82
+ VCFAutomationProjectDetails,
83
+ } from '@terasky/backstage-plugin-vcf-automation';
84
+ import { Entity } from '@backstage/catalog-model';
85
+
86
+ // For VSphere VMs
87
+ const vcfAutomationVSphereVMPage = (
88
+ <EntityLayout>
89
+ <EntityLayout.Route path="/" title="Overview">
90
+ <Grid container spacing={3} alignItems="stretch">
91
+ <Grid item md={6}>
92
+ <EntityAboutCard variant="gridItem" />
93
+ </Grid>
94
+ <Grid item md={6}>
95
+ <VCFAutomationVSphereVMOverview />
96
+ </Grid>
97
+ </Grid>
98
+ </EntityLayout.Route>
99
+ <EntityLayout.Route path="/vcf-automation" title="VCF Automation">
100
+ <VCFAutomationVSphereVMDetails />
101
+ </EntityLayout.Route>
102
+ </EntityLayout>
103
+ );
104
+
105
+ // Add to your component page switch
106
+ const componentPage = (
107
+ <EntitySwitch>
108
+ <EntitySwitch.Case if={isComponentType('Cloud.vSphere.Machine')}>
109
+ {vcfAutomationVSphereVMPage}
110
+ </EntitySwitch.Case>
111
+ // ... other cases
112
+ </EntitySwitch>
113
+ );
114
+
115
+ // For VCF Deployments
116
+ const hasVcfAutomationDeploymentStatus = (entity: Entity): boolean =>
117
+ Boolean(entity.metadata?.annotations?.['terasky.backstage.io/vcf-automation-deployment-status']);
118
+
119
+ const vcfAutomationDeploymentPage = (
120
+ <EntityLayout>
121
+ <EntityLayout.Route path="/" title="Overview">
122
+ <Grid container spacing={3} alignItems="stretch">
123
+ <Grid item md={6}>
124
+ <VCFAutomationDeploymentOverview />
125
+ </Grid>
126
+ </Grid>
127
+ </EntityLayout.Route>
128
+ <EntityLayout.Route path="/vcf-automation" title="VCF Automation">
129
+ <VCFAutomationDeploymentDetails />
130
+ </EntityLayout.Route>
131
+ </EntityLayout>
132
+ );
133
+
134
+ // For Generic Resources
135
+ const hasVcfAutomationResourceType = (entity: Entity): boolean =>
136
+ Boolean(entity.metadata?.annotations?.['terasky.backstage.io/vcf-automation-resource-type']);
137
+
138
+ const vcfAutomationGenericResourcePage = (
139
+ <EntityLayout>
140
+ <EntityLayout.Route path="/" title="Overview">
141
+ <Grid container spacing={3} alignItems="stretch">
142
+ <Grid item md={6}>
143
+ <VCFAutomationGenericResourceOverview />
144
+ </Grid>
145
+ </Grid>
146
+ </EntityLayout.Route>
147
+ <EntityLayout.Route path="/vcf-automation" title="VCF Automation">
148
+ <VCFAutomationGenericResourceDetails />
149
+ </EntityLayout.Route>
150
+ </EntityLayout>
151
+ );
152
+
153
+ // For Projects (in Domain page)
154
+ const domainPage = (
155
+ <EntityLayout>
156
+ <EntityLayout.Route path="/" title="Overview">
157
+ <Grid container spacing={3} alignItems="stretch">
158
+ <Grid item md={6}>
159
+ <VCFAutomationProjectOverview />
160
+ </Grid>
161
+ </Grid>
162
+ </EntityLayout.Route>
163
+ <EntityLayout.Route path="/vcf-automation" title="VCF Automation">
164
+ <VCFAutomationProjectDetails />
165
+ </EntityLayout.Route>
166
+ </EntityLayout>
167
+ );
168
+
169
+ // Add a Resources Page
170
+ const resourcePage = (
171
+ <EntitySwitch>
172
+ <EntitySwitch.Case if={hasVcfAutomationResourceType}>
173
+ {vcfAutomationGenericResourcePage}
174
+ </EntitySwitch.Case>
175
+ <EntitySwitch.Case>
176
+ {defaultEntityPage}
177
+ </EntitySwitch.Case>
178
+ </EntitySwitch>
179
+ );
180
+
181
+ // Update the entityPage constant to include the resource page
182
+ export const entityPage = (
183
+ <EntitySwitch>
184
+ ...
185
+ <EntitySwitch.Case if={isKind('resource')} children={resourcePage} />
186
+ ...
187
+ </EntitySwitch>
188
+ );
189
+ ```
190
+
191
+ ### 5. Configure Backend Integration
192
+
193
+ Add the following to your `app-config.yaml`:
194
+
195
+ ```yaml
196
+ vcfAutomation:
197
+ baseUrl: http://your-vcf-automation-service
198
+ ```
199
+
200
+ ## Entity Integration
201
+
202
+ The plugin integrates with different entity types:
203
+
204
+ ### VSphere VM Component
205
+ ```yaml
206
+ apiVersion: backstage.io/v1alpha1
207
+ kind: Component
208
+ metadata:
209
+ name: my-vm
210
+ spec:
211
+ type: Cloud.vSphere.Machine
212
+ system: my-deployment # References parent deployment
213
+ ```
214
+
215
+ ### VCF Deployment
216
+ ```yaml
217
+ apiVersion: backstage.io/v1alpha1
218
+ kind: System
219
+ metadata:
220
+ name: my-deployment
221
+ annotations:
222
+ terasky.backstage.io/vcf-automation-deployment-status: 'true'
223
+ ```
224
+
225
+ ### Generic Resource
226
+ ```yaml
227
+ apiVersion: backstage.io/v1alpha1
228
+ kind: Resource
229
+ metadata:
230
+ name: my-resource
231
+ annotations:
232
+ terasky.backstage.io/vcf-automation-resource-type: 'network'
233
+ ```
234
+
235
+ ### Project (Domain)
236
+ ```yaml
237
+ apiVersion: backstage.io/v1alpha1
238
+ kind: Domain
239
+ metadata:
240
+ name: my-project
241
+ ```
242
+
243
+ ## Features
244
+
245
+ - **VSphere VM Management**: Detailed view of VM configurations and status
246
+ - **Deployment Operations**: Track deployment status and history
247
+ - **Resource Management**: Monitor various VCF resource types
248
+ - **Project Administration**: Manage VCF project settings and resources
249
+ - **Permission Integration**: Built-in support for Backstage's permission framework
250
+
251
+ ## Contributing
252
+
253
+ Contributions are welcome! Please open an issue or submit a pull request on GitHub.
254
+
255
+ ## License
256
+
257
+ This project is licensed under the Apache-2.0 License.
package/config.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export interface Config {
2
+ /**
3
+ * VCF Automation root URL
4
+ * NOTE: Visibility applies to only this field
5
+ * @visibility frontend
6
+ */
7
+ vcfAutomation?: {
8
+ /**
9
+ * VCF Automation root URL
10
+ * NOTE: Visibility applies to only this field
11
+ * @visibility frontend
12
+ */
13
+ baseUrl: string;
14
+ }
15
+ }
@@ -0,0 +1,331 @@
1
+ /// <reference types="react" />
2
+ import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
+ import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
4
+ import react from 'react';
5
+
6
+ declare const vcfAutomationPlugin: _backstage_core_plugin_api.BackstagePlugin<{
7
+ root: _backstage_core_plugin_api.RouteRef<undefined>;
8
+ }, {
9
+ catalogIndex: _backstage_core_plugin_api.ExternalRouteRef<undefined, false>;
10
+ }, {}>;
11
+
12
+ declare const VCFAutomationVSphereVMOverview: () => react.JSX.Element;
13
+
14
+ declare const VCFAutomationProjectOverview: () => react.JSX.Element;
15
+
16
+ declare const VCFAutomationProjectDetails: () => react.JSX.Element;
17
+
18
+ declare const VCFAutomationDeploymentDetails: () => react.JSX.Element;
19
+
20
+ declare const VCFAutomationVSphereVMDetails: () => react.JSX.Element;
21
+
22
+ declare const VCFAutomationGenericResourceDetails: () => react.JSX.Element;
23
+
24
+ declare const VCFAutomationGenericResourceOverview: () => react.JSX.Element;
25
+
26
+ declare const VCFAutomationDeploymentOverview: () => react.JSX.Element;
27
+
28
+ interface VcfPageable {
29
+ pageNumber: number;
30
+ pageSize: number;
31
+ sort: {
32
+ empty: boolean;
33
+ sorted: boolean;
34
+ unsorted: boolean;
35
+ };
36
+ offset: number;
37
+ paged: boolean;
38
+ unpaged: boolean;
39
+ }
40
+ interface VcfPageResponse<T> {
41
+ content: T[];
42
+ pageable: VcfPageable;
43
+ totalElements: number;
44
+ totalPages: number;
45
+ last: boolean;
46
+ size: number;
47
+ number: number;
48
+ sort: {
49
+ empty: boolean;
50
+ sorted: boolean;
51
+ unsorted: boolean;
52
+ };
53
+ numberOfElements: number;
54
+ first: boolean;
55
+ empty: boolean;
56
+ }
57
+ interface VcfDeploymentHistory {
58
+ id: string;
59
+ name: string;
60
+ requestedBy: string;
61
+ actionId: string;
62
+ deploymentId: string;
63
+ resourceIds: string[];
64
+ status: string;
65
+ details: string;
66
+ createdAt: string;
67
+ updatedAt: string;
68
+ totalTasks: number;
69
+ completedTasks: number;
70
+ }
71
+ interface VcfDeploymentEvent$1 {
72
+ id: string;
73
+ requestId: string;
74
+ requestedBy: string;
75
+ resourceIds: string[];
76
+ name: string;
77
+ details: string;
78
+ status: string;
79
+ createdAt: string;
80
+ updatedAt: string;
81
+ }
82
+ interface VcfResourceDisk {
83
+ vm: string;
84
+ name: string;
85
+ type: string;
86
+ shares?: string;
87
+ vcUuid: string;
88
+ diskFile?: string;
89
+ bootOrder?: number;
90
+ encrypted: boolean;
91
+ limitIops?: string;
92
+ capacityGb: number;
93
+ persistent: boolean;
94
+ independent?: string;
95
+ sharesLevel?: string;
96
+ endpointType: string;
97
+ resourceLink: string;
98
+ vmFolderPath?: string;
99
+ controllerKey: string;
100
+ diskPlacementRef?: string;
101
+ existingResource: string;
102
+ provisioningType?: string;
103
+ controllerUnitNumber: string;
104
+ }
105
+ interface VcfResourceNetwork {
106
+ id: string;
107
+ name: string;
108
+ address: string;
109
+ network: string;
110
+ assignment: string;
111
+ deviceIndex: number;
112
+ external_id: string;
113
+ mac_address: string;
114
+ resourceName: string;
115
+ ipv6Addresses?: string[];
116
+ }
117
+ interface VcfResourceExpense {
118
+ totalExpense: number;
119
+ computeExpense: number;
120
+ storageExpense: number;
121
+ additionalExpense: number;
122
+ unit: string;
123
+ lastUpdatedTime: string;
124
+ }
125
+ interface VcfResource {
126
+ id: string;
127
+ name: string;
128
+ type: string;
129
+ properties: {
130
+ [key: string]: any;
131
+ storage?: {
132
+ disks: VcfResourceDisk[];
133
+ };
134
+ networks?: VcfResourceNetwork[];
135
+ };
136
+ createdAt: string;
137
+ syncStatus: string;
138
+ expense: VcfResourceExpense;
139
+ origin: string;
140
+ dependsOn: string[];
141
+ state: string;
142
+ }
143
+ interface VcfProjectZone {
144
+ zoneId: string;
145
+ priority: number;
146
+ maxNumberInstances: number;
147
+ allocatedInstancesCount: number;
148
+ memoryLimitMB: number;
149
+ allocatedMemoryMB: number;
150
+ cpuLimit: number;
151
+ allocatedCpu: number;
152
+ storageLimitGB: number;
153
+ allocatedStorageGB: number;
154
+ id: string;
155
+ }
156
+ interface VcfProject$1 {
157
+ machineNamingTemplate: string;
158
+ administrators: Array<{
159
+ email: string;
160
+ type: string;
161
+ }>;
162
+ members: Array<{
163
+ email: string;
164
+ type: string;
165
+ }>;
166
+ viewers: Array<{
167
+ email: string;
168
+ type: string;
169
+ }>;
170
+ supervisors: Array<{
171
+ email: string;
172
+ type: string;
173
+ }>;
174
+ zones: VcfProjectZone[];
175
+ constraints: Record<string, unknown>;
176
+ operationTimeout: number;
177
+ sharedResources: boolean;
178
+ placementPolicy: string;
179
+ customProperties: Record<string, unknown>;
180
+ name: string;
181
+ description: string;
182
+ id: string;
183
+ organizationId: string;
184
+ orgId: string;
185
+ _links: {
186
+ self: {
187
+ href: string;
188
+ };
189
+ };
190
+ }
191
+
192
+ interface VcfDeploymentEvent {
193
+ timestamp: string;
194
+ status: string;
195
+ operation: string;
196
+ user: string;
197
+ details: string;
198
+ }
199
+ interface VcfDeploymentConfig {
200
+ key: string;
201
+ value: string;
202
+ }
203
+ interface VcfDeploymentResponse {
204
+ content: any;
205
+ pageable: any;
206
+ config: VcfDeploymentConfig[];
207
+ history: VcfDeploymentEvent[];
208
+ }
209
+ interface VcfVSphereVM {
210
+ id: string;
211
+ name: string;
212
+ type: string;
213
+ properties: {
214
+ resourceId: string;
215
+ moref: string;
216
+ resourceDescLink: string;
217
+ powerState: string;
218
+ zone: string;
219
+ environmentName: string;
220
+ hasSnapshots: string;
221
+ computeHostType: string;
222
+ id: string;
223
+ memoryGB: string;
224
+ cpuCount: number;
225
+ image: string;
226
+ totalMemoryMB: number;
227
+ endpointType: string;
228
+ resourceName: string;
229
+ tags: string[];
230
+ softwareName: string;
231
+ name: string;
232
+ resourceLink: string;
233
+ region: string;
234
+ hostName: string;
235
+ storage: {
236
+ disks: Array<{
237
+ vm: string;
238
+ name: string;
239
+ type: string;
240
+ shares?: string;
241
+ vcUuid: string;
242
+ diskFile?: string;
243
+ bootOrder?: number;
244
+ encrypted: boolean;
245
+ limitIops?: string;
246
+ capacityGb: number;
247
+ persistent: boolean;
248
+ independent?: string;
249
+ sharesLevel?: string;
250
+ endpointType: string;
251
+ resourceLink: string;
252
+ vmFolderPath?: string;
253
+ controllerKey: string;
254
+ diskPlacementRef?: string;
255
+ existingResource: string;
256
+ provisioningType?: string;
257
+ controllerUnitNumber: string;
258
+ }>;
259
+ };
260
+ networks: Array<{
261
+ id: string;
262
+ name: string;
263
+ address: string;
264
+ network: string;
265
+ assignment: string;
266
+ deviceIndex: number;
267
+ external_id: string;
268
+ mac_address: string;
269
+ resourceName: string;
270
+ ipv6Addresses?: string[];
271
+ }>;
272
+ areVMActionsDisabled: string;
273
+ providerId: string;
274
+ osType: string;
275
+ instanceUUID: string;
276
+ componentType: string;
277
+ address: string;
278
+ endpointId: string;
279
+ externalId: string;
280
+ datacenter: string;
281
+ datastoreName: string;
282
+ coreCount: string;
283
+ primaryMAC: string;
284
+ computeHostRef: string;
285
+ snapshotCount: string;
286
+ accounts: string[];
287
+ vmFolderPath: string;
288
+ account: string;
289
+ vcUuid: string;
290
+ };
291
+ createdAt: string;
292
+ syncStatus: string;
293
+ expense: {
294
+ totalExpense: number;
295
+ computeExpense: number;
296
+ storageExpense: number;
297
+ additionalExpense: number;
298
+ unit: string;
299
+ lastUpdatedTime: string;
300
+ };
301
+ origin: string;
302
+ dependsOn: string[];
303
+ state: string;
304
+ }
305
+ type VcfProject = VcfProject$1;
306
+ interface VcfAutomationApi {
307
+ getDeploymentEvents(deploymentId: string): Promise<VcfDeploymentResponse>;
308
+ getVSphereVMDetails(deploymentId: string, resourceId: string): Promise<VcfVSphereVM>;
309
+ getProjectDetails(projectId: string): Promise<VcfProject>;
310
+ getGenericResourceDetails(deploymentId: string, resourceId: string): Promise<any>;
311
+ getDeploymentDetails(deploymentId: string): Promise<any>;
312
+ }
313
+ declare const vcfAutomationApiRef: _backstage_core_plugin_api.ApiRef<VcfAutomationApi>;
314
+ declare class VcfAutomationClient implements VcfAutomationApi {
315
+ private readonly discoveryApi;
316
+ private readonly identityApi;
317
+ constructor(options: {
318
+ discoveryApi: DiscoveryApi;
319
+ identityApi: IdentityApi;
320
+ });
321
+ private getAuthHeaders;
322
+ getDeploymentEvents(deploymentId: string): Promise<VcfDeploymentResponse>;
323
+ getVSphereVMDetails(deploymentId: string, resourceId: string): Promise<VcfVSphereVM>;
324
+ getGenericResourceDetails(deploymentId: string, resourceId: string): Promise<any>;
325
+ getDeploymentDetails(deploymentId: string): Promise<any>;
326
+ getProjectDetails(projectId: string): Promise<VcfProject>;
327
+ }
328
+
329
+ declare const rootRouteRef: _backstage_core_plugin_api.RouteRef<undefined>;
330
+
331
+ export { VCFAutomationDeploymentDetails, VCFAutomationDeploymentOverview, VCFAutomationGenericResourceDetails, VCFAutomationGenericResourceOverview, VCFAutomationProjectDetails, VCFAutomationProjectOverview, VCFAutomationVSphereVMDetails, VCFAutomationVSphereVMOverview, VcfAutomationApi, VcfAutomationClient, VcfDeploymentEvent$1 as VcfDeploymentEvent, VcfDeploymentHistory, VcfPageResponse, VcfPageable, VcfProject$1 as VcfProject, VcfProjectZone, VcfResource, VcfResourceDisk, VcfResourceExpense, VcfResourceNetwork, rootRouteRef, vcfAutomationApiRef, vcfAutomationPlugin };