feat(KubernetesPlugins): make k8s frontend + backend plugins work with our cluster

This commit is contained in:
Sylvain Tremblay 2024-05-30 15:17:03 -04:00
parent b7e9b44ff1
commit b93ed5488e
18 changed files with 747 additions and 515 deletions

View File

@ -136,3 +136,15 @@ notifications:
externalCallerSecret: notifications-secret
iframe:
allowList: [ "sreez.nationtech.io", "www.hyperdx.io", "http://localhost:8080" ]
kubernetes:
serviceLocatorMethod:
type: 'multiTenant'
clusterLocatorMethods:
- type: 'config'
clusters:
- url: 'https://api.oc-med.wk.nt.local:6443'
name: 'WK OKD Cluster'
authProvider: 'serviceAccount'
serviceAccountToken: 'eyJhbGciOiJSUzI1NiIsImtpZCI6IllKQnpxZ19WTWVOcHdvRTZXc2JpN1NJQWlGMEJpa2c1QTZpLUV6UDJGRVEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImJhY2tzdGFnZS1zYS10b2tlbi1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiYmFja3N0YWdlLXNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNzUzYTgzYmItNjgxNy00NzYwLWFlOTYtYzhkMDc3NWQ1NTRhIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6YmFja3N0YWdlLXNhIn0.1iRyZq99AlwM6bdJNXPSbi1z6CKLAU3OvsmGinF1IyogbSKsfgPCNL81wQYhfiJmvgOQOmhHLfk10NxGcA2YR7ijUB4I5_LOBqi3eketpgxYMgvvv31vRX1cVcKZE9F787k2rQcR1OgKnRcKwYAkCHnbSkObTf4wmL9g2lmfLN-vmZTGiQQ_RfzR5aoklqwWZjmMvVa3-9XBEnbg2Cc77rcireMH55xPsaYUDVDF0NYEpGfr94Ys2Ois7wrcXtnG7NOPdmVAbbUzJ1nmm8AHxuQW2IItcea3UGaQCQtVTOVY4jektF81UU-eXHnTC1JHH1kTCr-jeWc8K6-wmuoTgOx5fRUgtC8tVZrwNwIIA-8-gutFDS5ica5IQ26NXeLt5CF7OJ9Dw9wwTyNLmbvchwt1yTwXccOdwBqqE2_tQSLhpkZOFvdZfELxblvvIJ2fBjs425dJ6hfP1vFm82mSBo3YeTm5CM_uj0UHlj8339N55TpKDnY_l1Tr_TTOdvuEpM07Gl_PrJzl9QjzvnW0Db6Php9qjnc6ID24emYI-fF9ITzR1Lgv2dMZA38NOOH4gm75B4ULBw5i_Ek0WOBI2D8-QsZm2T3uZZPkclGGdMFEfsXlOxAvqRT1WJC5g8jGvdixuLqdhZTxp-E4xD4cuKRVYzS1VemNbNo5e8an1nE'
skipTLSVerify: true

View File

@ -0,0 +1,39 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: backstage-clusterrole
rules:
- apiGroups:
- '*'
resources:
- pods
- configmaps
- services
- deployments
- replicasets
- horizontalpodautoscalers
- ingresses
- statefulsets
- limitranges
- resourcequotas
- daemonsets
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- jobs
- cronjobs
verbs:
- get
- list
- watch
- apiGroups:
- metrics.k8s.io
resources:
- pods
verbs:
- get
- list

View File

@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-all-clusterrole-binding
subjects:
- kind: ServiceAccount
name: backstage-sa
namespace: default # Update the namespace if needed
roleRef:
kind: ClusterRole
name: backstage-clusterrole
apiGroup: rbac.authorization.k8s.io

View File

@ -0,0 +1,15 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: backstage-role
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps", "batch", "extensions", "networking.k8s.io", "rbac.authorization.k8s.io", "storage.k8s.io"]
resources: ["*"]
verbs: ["get", "list", "watch"]
- apiGroups: ["autoscaling"]
resources: ["horizontalpodautoscalers"]
verbs: ["get", "list", "watch"]

View File

@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: backstage-rolebinding
namespace: default
subjects:
- kind: ServiceAccount
name: backstage-sa
namespace: default
roleRef:
kind: Role
name: backstage-role
apiGroup: rbac.authorization.k8s.io

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: backstage-sa-token-secret
annotations:
kubernetes.io/service-account.name: backstage-sa
type: kubernetes.io/service-account-token

View File

@ -0,0 +1,15 @@
kind: Secret
apiVersion: v1
metadata:
name: devspaces-github-oauth-config
namespace: sreez
labels:
app.kubernetes.io/part-of: che.eclipse.org
app.kubernetes.io/component: oauth-scm-configuration
annotations:
che.eclipse.org/oauth-scm-server: github
che.eclipse.org/scm-server-endpoint: https://github.com
type: Opaque
stringData:
id: Ov23li2sU4W3iLzocZWP
secret: 8e041432352bf0e5f2bbb4bff25c3dea9b391feb

View File

@ -0,0 +1,109 @@
# Creating ServiceAccount for Backstage
## Create the ServiceAccount itself
```
$ kubectl create serviceaccount backstage-sa -n default
```
!!! Role did NOT work (probably a namespace issue), created a clusterRole + binding instead, see below
## Create the role
backstage-role.yaml:
```
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: backstage-role
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
```
```
$ kubectl apply -f backstage-role.yaml
```
## Bind role to service account
backstage-rolebinding.yaml:
```
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: backstage-rolebinding
namespace: default
subjects:
- kind: ServiceAccount
name: backstage-sa
namespace: default
roleRef:
kind: Role
name: backstage-role
apiGroup: rbac.authorization.k8s.io
```
```
$ kubectl apply -f backstage-rolebinding.yaml
```
## Create the ClusterRole
## Create the ClusterRoleBinding
## Create a secret token for the service account
backstage-sa-token-secret.yaml:
```
apiVersion: v1
kind: Secret
metadata:
name: backstage-sa-token-secret
annotations:
kubernetes.io/service-account.name: backstage-sa
type: kubernetes.io/service-account-token
```
```
$ kubectl apply -f backstage-sa-token-secret.yaml -n default
```
## Link the secret with the service account
```
$ oc secrets link backstage-sa backstage-sa-token-secret -n default
```
## Get the service account token
Get the name of the secret (backstage-sa-secret):
```
$ kubectl get serviceaccount backstage-sa -n default -o jsonpath='{.secrets[0].name}'
```
get the secret value (the token):
```
kubectl get secret backstage-sa-secret -n default -o jsonpath='{.data.token}' | base64 --decode
```
## Update app-config
```
kubernetes:
serviceLocatorMethod:
type: 'multiTenant'
clusterLocatorMethods:
- type: 'config'
clusters:
- url: 'https://api.oc-med.wk.nt.local:6443'
name: 'WK OKD Cluster'
authProvider: 'serviceAccount'
serviceAccountToken: '${KUBERNETES_SERVICE_ACCOUNT_TOKEN}'
skipTLSVerify: true
```

View File

@ -0,0 +1,14 @@
create github app
-> authorization callback must contain the IDP name as defined in the OAuth resource
create github secret (okd-github-secret.yaml)
create github OAuth resource (okd-oauth-github)
-> make sure secret name matches and idp name matches auth callback from github app
```
$ oc get user
$ oc adm policy add-role-to-user admin <github-username> -n <project-name>
```

View File

@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: okd-github-secret
namespace: openshift-config
type: Opaque
stringData:
clientSecret: 41dd1d62609725a5a0ecbdccb1fa9805ad55dc93

View File

@ -0,0 +1,16 @@
apiVersion: config.openshift.io/v1
kind: OAuth
metadata:
name: cluster
spec:
identityProviders:
- name: githubidp
mappingMethod: claim
type: GitHub
github:
clientID: Ov23liRSsXqOfUPVerIx
clientSecret:
name: okd-github-secret
organizations:
- Kheops-org

View File

@ -29,6 +29,7 @@
"@backstage/plugin-catalog-import": "^0.11.0",
"@backstage/plugin-catalog-react": "^1.12.0",
"@backstage/plugin-devtools": "^0.1.13",
"@backstage/plugin-kubernetes": "^0.11.10",
"@backstage/plugin-org": "^0.6.25",
"@backstage/plugin-permission-react": "^0.4.22",
"@backstage/plugin-scaffolder": "^1.20.0",
@ -41,10 +42,10 @@
"@backstage/plugin-user-settings": "^0.8.6",
"@backstage/theme": "^0.5.5",
"@bestsellerit/backstage-plugin-harbor": "^0.3.1",
"@mui/material": "next",
"@internal/backstage-plugin-devspaces-plugin": "^0.1.0",
"@janus-idp/plugin-notifications": "^1.3.1",
"@material-ui/icons": "^4.11.3",
"@mui/material": "next",
"@roadiehq/backstage-plugin-argo-cd": "^2.6.5",
"@roadiehq/backstage-plugin-github-insights": "^2.3.29",
"@roadiehq/backstage-plugin-github-pull-requests": "^2.5.26",

View File

@ -8,6 +8,7 @@ import {overviewContent} from "../tabs/OverviewContent";
import {buildsContent} from "../tabs/BuildsContent";
import {workflowsContent} from "../tabs/WorkflowsContent";
import {techdocsContent} from "../tabs/TechdocsContent";
import {kubernetesContent} from "../tabs/KubernetesContent";
export const serviceEntityPage = (
<EntityLayout>
@ -67,5 +68,10 @@ export const serviceEntityPage = (
<EntityLayout.Route path="/docs" title="Docs">
{techdocsContent}
</EntityLayout.Route>
<EntityLayout.Route path="/kubernetes" title="Kubernetes">
{kubernetesContent}
</EntityLayout.Route>
</EntityLayout>
);

View File

@ -0,0 +1,6 @@
import { EntityKubernetesContent } from '@backstage/plugin-kubernetes';
import React from "react";
export const kubernetesContent = (
<EntityKubernetesContent refreshIntervalMs={30000} />
);

View File

@ -8,6 +8,7 @@ import {EntityGithubInsightsReadmeCard} from "@roadiehq/backstage-plugin-github-
import {EntityArgoCDOverviewCard} from "@roadiehq/backstage-plugin-argo-cd";
import {EntityGithubPullRequestsOverviewCard} from "@roadiehq/backstage-plugin-github-pull-requests";
import {EntityCatalogGraphCard} from "@backstage/plugin-catalog-graph";
import { DevspacesPluginPage } from "@internal/backstage-plugin-devspaces-plugin";
export const overviewContent = (
<Grid container spacing={1} alignItems={'stretch'} justifyContent={'flex-start'}>
@ -18,7 +19,7 @@ export const overviewContent = (
<Grid item xs={4}>
<EntityAboutCard variant={'flex'}/>
<EntityLinksCard variant="flex"/>
{/*<DevspacesPluginPage/>*/}
<DevspacesPluginPage/>
</Grid>
<Grid item xs={8}>
<Grid container>

View File

@ -34,6 +34,7 @@
"@backstage/plugin-catalog-node": "^1.11.1",
"@backstage/plugin-devtools-backend": "^0.3.3",
"@backstage/plugin-events-backend-module-github": "^0.2.3",
"@backstage/plugin-kubernetes-backend": "^0.17.1",
"@backstage/plugin-permission-backend": "^0.5.41",
"@backstage/plugin-permission-backend-module-allow-all-policy": "^0.1.14",
"@backstage/plugin-permission-common": "^0.7.13",

View File

@ -56,6 +56,9 @@ backend.add(import('@backstage/plugin-search-backend/alpha'));
backend.add(import('@backstage/plugin-devtools-backend'));
// Kubernetes backend plugin
backend.add(import('@backstage/plugin-kubernetes-backend/alpha'));
const scaffolderModuleCustomExtensions = createBackendModule({
pluginId: 'scaffolder', // name of the plugin that the module is targeting
moduleId: 'custom-extensions',

File diff suppressed because it is too large Load Diff