add support to the new frontend system

Signed-off-by: Nurit Izrailov <nuriti@spotify.com>
This commit is contained in:
Nurit Izrailov
2024-07-23 11:33:26 -04:00
parent 2ab03460d5
commit e6c15cc304
14 changed files with 363 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes': minor
---
Adds support for Backstage's new frontend system
+2
View File
@@ -43,6 +43,8 @@ app:
- entity-card:org/ownership
- entity-card:org/user-profile
- entity-content:kubernetes/kubernetes
# scmAuthExtension: >-
# createScmAuthExtension({
# id: 'apis.scmAuth.addons.ghe',
+2
View File
@@ -48,6 +48,7 @@ import {
} from '@backstage/integration-react';
import { createSignInPageExtension } from '@backstage/frontend-plugin-api';
import { SignInPage } from '@backstage/core-components';
import kubernetesPlugin from '@backstage/plugin-kubernetes/alpha';
/*
@@ -121,6 +122,7 @@ const app = createApp({
userSettingsPlugin,
homePlugin,
appVisualizerPlugin,
kubernetesPlugin,
...collectedLegacyPlugins,
createExtensionOverrides({
extensions: [
+31 -1
View File
@@ -26,8 +26,38 @@ For more information, see the [formal documentation about the Kubernetes feature
## 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 [/kubernetes](http://localhost:3000/kubernetes).
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 [/kubernetes](http://localhost:3000/catalog/default/component/:component-name/kubernetes).
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.
### Integrating with `EntityPage` (New Frontend System)
Follow this section if you are using Backstage's [new frontend system](https://backstage.io/docs/frontend-system/).
1. Import `kubernetesPlugin` in your `App.tsx` and add it to your app's `features` array:
```typescript
import kubernetesPlugin from '@backstage/plugin-kubernetes/alpha';
// ...
export const app = createApp({
features: [
// ...
kubernetesPlugin,
// ...
],
});
```
2. Next, enable your desired extensions in `app-config.yaml`
```yaml
app:
extensions:
- entity-content:kubernetes/kubernetes
```
Now, the extension appears on your entity page as one of the tabs, which is called `KUBERNETES`
+19
View File
@@ -0,0 +1,19 @@
## API Report File for "@backstage/plugin-kubernetes"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { BackstagePlugin } from '@backstage/frontend-plugin-api';
import { RouteRef } from '@backstage/frontend-plugin-api';
// @public (undocumented)
const _default: BackstagePlugin<
{
kubernetes: RouteRef<undefined>;
},
{}
>;
export default _default;
// (No @packageDocumentation comment for this package)
```
+17
View File
@@ -30,8 +30,23 @@
},
"license": "Apache-2.0",
"sideEffects": false,
"exports": {
".": "./src/index.ts",
"./alpha": "./src/alpha.ts",
"./package.json": "./package.json"
},
"main": "src/index.ts",
"types": "src/index.ts",
"typesVersions": {
"*": {
"alpha": [
"src/alpha.ts"
],
"package.json": [
"package.json"
]
}
},
"files": [
"dist"
],
@@ -46,8 +61,10 @@
},
"dependencies": {
"@backstage/catalog-model": "workspace:^",
"@backstage/core-compat-api": "workspace:^",
"@backstage/core-components": "workspace:^",
"@backstage/core-plugin-api": "workspace:^",
"@backstage/frontend-plugin-api": "workspace:^",
"@backstage/plugin-catalog-react": "workspace:^",
"@backstage/plugin-kubernetes-common": "workspace:^",
"@backstage/plugin-kubernetes-react": "workspace:^",
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './alpha/index';
export { default } from './alpha/index';
@@ -0,0 +1,24 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useEntity } from '@backstage/plugin-catalog-react';
import { KubernetesContent } from '../KubernetesContent';
import React from 'react';
export function KubernetesContentPage() {
const { entity } = useEntity();
return <KubernetesContent entity={entity} />;
}
+119
View File
@@ -0,0 +1,119 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createApiExtension,
createApiFactory,
discoveryApiRef,
fetchApiRef,
} from '@backstage/frontend-plugin-api';
import {
KubernetesBackendClient,
kubernetesApiRef,
kubernetesProxyApiRef,
kubernetesAuthProvidersApiRef,
KubernetesAuthProviders,
KubernetesProxyClient,
kubernetesClusterLinkFormatterApiRef,
getDefaultFormatters,
KubernetesClusterLinkFormatter,
DEFAULT_FORMATTER_NAME,
} from '@backstage/plugin-kubernetes-react';
import {
gitlabAuthApiRef,
googleAuthApiRef,
microsoftAuthApiRef,
oktaAuthApiRef,
oneloginAuthApiRef,
} from '@backstage/core-plugin-api';
export const kubernetesApiExtension = createApiExtension({
factory: createApiFactory({
api: kubernetesApiRef,
deps: {
discoveryApi: discoveryApiRef,
fetchApi: fetchApiRef,
kubernetesAuthProvidersApi: kubernetesAuthProvidersApiRef,
},
factory: ({ discoveryApi, fetchApi, kubernetesAuthProvidersApi }) =>
new KubernetesBackendClient({
discoveryApi,
fetchApi,
kubernetesAuthProvidersApi,
}),
}),
});
export const kubernetesProxyApi = createApiExtension({
factory: createApiFactory({
api: kubernetesProxyApiRef,
deps: {
kubernetesApi: kubernetesApiRef,
},
factory: ({ kubernetesApi }) =>
new KubernetesProxyClient({
kubernetesApi,
}),
}),
});
export const kubernetesAuthProvidersApi = createApiExtension({
factory: createApiFactory({
api: kubernetesAuthProvidersApiRef,
deps: {
gitlabAuthApi: gitlabAuthApiRef,
googleAuthApi: googleAuthApiRef,
microsoftAuthApi: microsoftAuthApiRef,
oktaAuthApi: oktaAuthApiRef,
oneloginAuthApi: oneloginAuthApiRef,
},
factory: ({
gitlabAuthApi,
googleAuthApi,
microsoftAuthApi,
oktaAuthApi,
oneloginAuthApi,
}) => {
const oidcProviders = {
gitlab: gitlabAuthApi,
google: googleAuthApi,
microsoft: microsoftAuthApi,
okta: oktaAuthApi,
onelogin: oneloginAuthApi,
};
return new KubernetesAuthProviders({
microsoftAuthApi,
googleAuthApi,
oidcProviders,
});
},
}),
});
export const kubernetesClusterLinkFormatterApi = createApiExtension({
factory: createApiFactory({
api: kubernetesClusterLinkFormatterApiRef,
deps: { googleAuthApi: googleAuthApiRef },
factory: deps => {
const formatters = getDefaultFormatters(deps);
return new KubernetesClusterLinkFormatter({
formatters,
defaultFormatterName: DEFAULT_FORMATTER_NAME,
});
},
}),
});
@@ -0,0 +1,34 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import {
compatWrapper,
convertLegacyRouteRef,
} from '@backstage/core-compat-api';
import { createEntityContentExtension } from '@backstage/plugin-catalog-react/alpha';
import { rootCatalogKubernetesRouteRef } from '../plugin';
export const entityKubernetesContent = createEntityContentExtension({
defaultPath: 'kubernetes',
defaultTitle: 'Kubernetes',
name: 'kubernetes',
routeRef: convertLegacyRouteRef(rootCatalogKubernetesRouteRef),
loader: () =>
import('./KubernetesContentPage').then(m =>
compatWrapper(<m.KubernetesContentPage />),
),
});
+17
View File
@@ -0,0 +1,17 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { default } from './plugin';
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react'; // Add this line to import React
import { createPageExtension } from '@backstage/frontend-plugin-api';
import {
compatWrapper,
convertLegacyRouteRef,
} from '@backstage/core-compat-api';
import { rootCatalogKubernetesRouteRef } from '../plugin';
export const kubernetesPage = createPageExtension({
defaultPath: '/kubernetes',
// you can reuse the existing routeRef
// by wrapping into the convertLegacyRouteRef.
routeRef: convertLegacyRouteRef(rootCatalogKubernetesRouteRef),
// these inputs usually match the props required by the component.
loader: () => import('../Router').then(m => compatWrapper(<m.Router />)),
});
+40
View File
@@ -0,0 +1,40 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { convertLegacyRouteRefs } from '@backstage/core-compat-api';
import { createPlugin } from '@backstage/frontend-plugin-api';
import { kubernetesPage } from './pages';
import { entityKubernetesContent } from './entityContents';
import { rootCatalogKubernetesRouteRef } from '../plugin';
import {
kubernetesApiExtension as kubernetesApi,
kubernetesAuthProvidersApi,
kubernetesClusterLinkFormatterApi,
kubernetesProxyApi,
} from './apis';
export default createPlugin({
id: 'kubernetes',
extensions: [
kubernetesPage,
entityKubernetesContent,
kubernetesApi,
kubernetesProxyApi,
kubernetesAuthProvidersApi,
kubernetesClusterLinkFormatterApi,
],
routes: convertLegacyRouteRefs({ kubernetes: rootCatalogKubernetesRouteRef }),
});
+2
View File
@@ -6307,9 +6307,11 @@ __metadata:
dependencies:
"@backstage/catalog-model": "workspace:^"
"@backstage/cli": "workspace:^"
"@backstage/core-compat-api": "workspace:^"
"@backstage/core-components": "workspace:^"
"@backstage/core-plugin-api": "workspace:^"
"@backstage/dev-utils": "workspace:^"
"@backstage/frontend-plugin-api": "workspace:^"
"@backstage/plugin-catalog-react": "workspace:^"
"@backstage/plugin-kubernetes-common": "workspace:^"
"@backstage/plugin-kubernetes-react": "workspace:^"