diff --git a/packages/app/src/scaffolder/credentials/extensions.ts b/packages/app/src/scaffolder/credentials/extensions.ts
index 02808e1..8313c7b 100644
--- a/packages/app/src/scaffolder/credentials/extensions.ts
+++ b/packages/app/src/scaffolder/credentials/extensions.ts
@@ -8,7 +8,7 @@ export const GetK8sOIDCTokenExtension = scaffolderPlugin.provide(
{
name: 'GetK8sOIDCToken',
component: GetK8sOIDCToken,
- schema: ClusterPickerSchema
+ schema: ClusterPickerSchema,
}
)
)
diff --git a/packages/app/src/scaffolder/credentials/getOIDCToken.tsx b/packages/app/src/scaffolder/credentials/getOIDCToken.tsx
index e03b04d..9614852 100644
--- a/packages/app/src/scaffolder/credentials/getOIDCToken.tsx
+++ b/packages/app/src/scaffolder/credentials/getOIDCToken.tsx
@@ -1,40 +1,78 @@
-import React from 'react';
+import React, {useCallback, useEffect} from 'react';
import FormControl from '@material-ui/core/FormControl';
-import {useApi} from "@backstage/core-plugin-api";
-import {kubernetesApiRef, kubernetesAuthProvidersApiRef} from "@backstage/plugin-kubernetes";
-import {FormHelperText} from "@material-ui/core";
+import {
+ useApi, configApiRef, discoveryApiRef, oauthRequestApiRef
+} from "@backstage/core-plugin-api";
+import { kubernetesApiRef } from "@backstage/plugin-kubernetes";
+import { FormHelperText } from "@material-ui/core";
import {Progress, Select} from "@backstage/core-components";
import useAsync from "react-use/lib/useAsync";
import {useTemplateSecrets} from "@backstage/plugin-scaffolder-react";
import {ClusterPickerProps} from "./schema";
+import {OAuth2} from "@backstage/core-app-api";
+
export const GetK8sOIDCToken = (props: ClusterPickerProps) => {
const k8sApi = useApi(kubernetesApiRef)
- const k8sAuthProviderApi = useApi(kubernetesAuthProvidersApiRef)
- const { setSecrets } = useTemplateSecrets();
+ const { setSecrets, secrets } = useTemplateSecrets();
- const {uiSchema, onChange, rawErrors, formData, required} = props
- const getToken = async () => {
- const {requestUserCredentials} = uiSchema?.['ui:options'] ?? {}
- if (!requestUserCredentials) {
- return;
- }
-
- const clusters = await k8sApi.getClusters()
- const cluster = clusters.find(c => {
- return c.name === formData
- })
- const creds = await k8sAuthProviderApi.getCredentials(cluster!.oidcTokenProvider!)
- setSecrets({ [requestUserCredentials.secretKey]: creds.token! })
- }
+ const discoveryApi = useApi(discoveryApiRef)
+ const oauthRequestApi = useApi(oauthRequestApiRef)
+ const configApi = useApi(configApiRef)
+ const {uiSchema, required} = props
+ let {rawErrors} = props
const {value: {clusters} = {clusters: []}, loading } = useAsync(
async () => {
const c = await k8sApi.getClusters()
return {clusters: c.map(i => ({ label: i.name, value: i.name}))}
}
)
+ if (!rawErrors) {
+ rawErrors = []
+ }
+
+ const getToken = useCallback( async (clusterName: string) => {
+ const {requestUserCredentials} = uiSchema?.['ui:options'] ?? {}
+ if (!requestUserCredentials) {
+ return;
+ }
+ const cs = await k8sApi.getClusters()
+ const cluster = cs.find(c => {
+ return c.name === clusterName
+ })
+ if (cluster?.oidcTokenProvider === undefined) {
+ throw new Error("no oidc provider defined for this cluster")
+ }
+
+ const oidc = OAuth2.create({
+ discoveryApi,
+ oauthRequestApi,
+ provider: {
+ id: cluster.oidcTokenProvider,
+ title: 'OIDC',
+ icon: () => null,
+ },
+ environment: configApi.getOptionalString('auth.environment'),
+ defaultScopes: ['openid', 'profile', 'email', 'groups'],
+ })
+ const token = await oidc.getIdToken()
+
+ setSecrets({ [requestUserCredentials.secretKey]: token })
+ }, [configApi, discoveryApi, k8sApi, oauthRequestApi, setSecrets, uiSchema]
+ )
+
+ useEffect(() => {
+ const {requestUserCredentials} = uiSchema?.['ui:options'] ?? {}
+ if (!requestUserCredentials?.secretKey || secrets[requestUserCredentials?.secretKey!]) {
+ return
+ }
+
+ if (clusters.length) {
+ getToken(clusters[0].value).catch(console.error)
+ }
+ }, [clusters, getToken, secrets, uiSchema])
if (loading) {
return ;
@@ -44,13 +82,14 @@ export const GetK8sOIDCToken = (props: ClusterPickerProps) => {
0 && !formData}
+ error={rawErrors?.length > 0}
>