remove unnecessary calls

This commit is contained in:
Manabu Mccloskey 2023-07-24 15:55:48 -07:00
parent 7987c1028f
commit 8f8935b5a3
12 changed files with 1084 additions and 156 deletions

3
.gitignore vendored
View file

@ -49,3 +49,6 @@ site
# vscode database functionality support files
*.session.sql
# JetBrains
.idea

View file

@ -45,10 +45,13 @@
"@backstage/plugin-techdocs-react": "^1.1.6",
"@backstage/plugin-user-settings": "^0.7.3",
"@backstage/theme": "^0.3.0",
"@cnoe-io/plugin-apache-spark": "file:/var/folders/b7/h6wzrfwn6l30pn3fk5j2794dcy0vlz/T/tmp-26390-66rLxROMRq6K",
"@cnoe-io/plugin-argo-workflows": "file:/var/folders/b7/h6wzrfwn6l30pn3fk5j2794dcy0vlz/T/tmp-32426-R2tjIfGLJy55",
"@internal/plugin-workflows": "^0.1.0",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@rjsf/core": "^5.8.1",
"@rjsf/utils": "^5.8.1",
"history": "^5.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",

View file

@ -11,7 +11,7 @@ import {
catalogImportPlugin,
} from '@backstage/plugin-catalog-import';
import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder';
import {ScaffolderFieldExtensions} from '@backstage/plugin-scaffolder-react'
import { ScaffolderFieldExtensions } from '@backstage/plugin-scaffolder-react';
import { orgPlugin } from '@backstage/plugin-org';
import { SearchPage } from '@backstage/plugin-search';
import { TechRadarPage } from '@backstage/plugin-tech-radar';
@ -23,36 +23,39 @@ import {
import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
import { UserSettingsPage } from '@backstage/plugin-user-settings';
import {apis} from './apis';
import {keycloakOIDCAuthApiRef} from "@internal/plugin-workflows"
import { apis, keycloakOIDCAuthApiRef } from './apis';
import { entityPage } from './components/catalog/EntityPage';
import { searchPage } from './components/search/SearchPage';
import { Root } from './components/Root';
import {AlertDisplay, OAuthRequestDialog, SignInPage} from '@backstage/core-components';
import {
AlertDisplay,
OAuthRequestDialog,
SignInPage,
} from '@backstage/core-components';
import { createApp } from '@backstage/app-defaults';
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 {GetK8sOIDCTokenExtension} from "./scaffolder/credentials";
import { GetK8sOIDCTokenExtension } from './scaffolder/credentials';
const app = createApp({
apis,
components: {
// SignInPage: (props) => <ProxiedSignInPage {...props} provider="oauth2Proxy" />,
SignInPage: props => (
<SignInPage
{...props}
auto
provider={{
id: 'keycloak-oidc',
title: 'Keycloak',
message: 'Sign in using Keycloak',
apiRef: keycloakOIDCAuthApiRef,
}}
/>
),
SignInPage: props => (
<SignInPage
{...props}
auto
provider={{
id: 'keycloak-oidc',
title: 'Keycloak',
message: 'Sign in using Keycloak',
apiRef: keycloakOIDCAuthApiRef,
}}
/>
),
},
bindRoutes({ bind }) {
bind(catalogPlugin.externalRoutes, {

View file

@ -4,26 +4,25 @@ import {
ScmAuth,
} from '@backstage/integration-react';
import {
AnyApiFactory,
ApiRef,
BackstageIdentityApi,
configApiRef,
createApiFactory,
createApiRef,
discoveryApiRef,
oauthRequestApiRef,
OpenIdConnectApi,
ProfileInfoApi,
SessionApi,
AnyApiFactory,
ApiRef,
BackstageIdentityApi,
configApiRef,
createApiFactory,
createApiRef,
discoveryApiRef,
oauthRequestApiRef,
OpenIdConnectApi,
ProfileInfoApi,
SessionApi,
} from '@backstage/core-plugin-api';
import {OAuth2} from "@backstage/core-app-api";
import {keycloakOIDCAuthApiRef} from "@internal/plugin-workflows"
import { OAuth2 } from '@backstage/core-app-api';
// export const keycloakOIDCAuthApiRef: ApiRef<
// OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
// > = createApiRef({
// id: 'auth.keycloak-oidc-provider',
// });
export const keycloakOIDCAuthApiRef: ApiRef<
OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
> = createApiRef({
id: 'auth.keycloak-oidc-provider',
});
export const apis: AnyApiFactory[] = [
createApiFactory({
api: scmIntegrationsApiRef,
@ -39,16 +38,16 @@ export const apis: AnyApiFactory[] = [
configApi: configApiRef,
},
factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
OAuth2.create({
discoveryApi,
oauthRequestApi,
provider: {
id: 'keycloak-oidc',
title: 'Keycloak OIDC',
icon: () => null,
},
environment: configApi.getOptionalString('auth.environment'),
defaultScopes: ['openid', 'profile', 'email', 'groups'],
}),
OAuth2.create({
discoveryApi,
oauthRequestApi,
provider: {
id: 'keycloak-oidc',
title: 'Keycloak OIDC',
icon: () => null,
},
environment: configApi.getOptionalString('auth.environment'),
defaultScopes: ['openid', 'profile', 'email', 'groups'],
}),
}),
];

View file

@ -58,7 +58,13 @@ import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
import { EntityKubernetesContent } from '@backstage/plugin-kubernetes';
import {EntityWorkflowsContent} from '@internal/plugin-workflows'
import {
EntityArgoWorkflowsOverviewCard,
EntityArgoWorkflowsTemplateOverviewCard,
isArgoWorkflowsAvailable,
} from '@cnoe-io/plugin-argo-workflows';
import { ApacheSparkPage } from '@cnoe-io/plugin-apache-spark';
const techdocsContent = (
<EntityTechdocsContent>
@ -121,6 +127,16 @@ const overviewContent = (
<Grid item md={6}>
<EntityAboutCard variant="gridItem" />
</Grid>
<EntitySwitch>
<EntitySwitch.Case if={e => isArgoWorkflowsAvailable(e)}>
<Grid item md={6}>
<EntityArgoWorkflowsOverviewCard />
</Grid>
<Grid item md={6}>
<EntityArgoWorkflowsTemplateOverviewCard />
</Grid>
</EntitySwitch.Case>
</EntitySwitch>
<Grid item md={6} xs={12}>
<EntityCatalogGraphCard variant="gridItem" height={400} />
</Grid>
@ -199,6 +215,17 @@ const websiteEntityPage = (
</EntityLayout>
);
const jobEntityPage = (
<EntityLayout>
<EntityLayout.Route path="/" title="Overview">
{overviewContent}
</EntityLayout.Route>
<EntityLayout.Route path="/apache-spark" title="Apache Spark">
<ApacheSparkPage />
</EntityLayout.Route>
</EntityLayout>
);
/**
* NOTE: This page is designed to work on small screens such as mobile devices.
* This is based on Material UI Grid. If breakpoints are used, each grid item must set the `xs` prop to a column size or to `true`,
@ -227,6 +254,9 @@ const componentPage = (
<EntitySwitch.Case if={isComponentType('website')}>
{websiteEntityPage}
</EntitySwitch.Case>
<EntitySwitch.Case if={isComponentType('job')}>
{jobEntityPage}
</EntitySwitch.Case>
<EntitySwitch.Case>{defaultEntityPage}</EntitySwitch.Case>
</EntitySwitch>
@ -349,9 +379,6 @@ const systemPage = (
<EntityLayout.Route path="/kubernetes" title="Kubernetes">
<EntityKubernetesContent refreshIntervalMs={30000} />
</EntityLayout.Route>
<EntityLayout.Route path="/workflows" title="Workflows">
<EntityWorkflowsContent />
</EntityLayout.Route>
</EntityLayout>
);

View file

@ -0,0 +1,163 @@
import React, { useState } from 'react';
import {
createScaffolderLayout,
LayoutTemplate,
} from '@backstage/plugin-scaffolder-react';
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
import { Button, Grid } from '@material-ui/core';
import {
ObjectFieldTemplatePropertyType,
ObjectFieldTemplateProps,
StrictRJSFSchema,
FormContextType,
RJSFSchema,
titleId,
getTemplate,
getUiOptions,
} from '@rjsf/utils';
const TwoColumn: LayoutTemplate = ({ properties, description, title }) => {
const mid = Math.ceil(properties.length / 2);
return (
<>
<h1>{title}</h1>
<h2>In two column layout!!</h2>
<Grid container justifyContent="flex-end">
{properties.slice(0, mid).map(prop => (
<Grid item xs={6} key={prop.content.key}>
{prop.content}
</Grid>
))}
{properties.slice(mid).map(prop => (
<Grid item xs={6} key={prop.content.key}>
{prop.content}
</Grid>
))}
</Grid>
{description}
</>
);
};
function CollapsableFieldTemplate<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any,
>(props: ObjectFieldTemplateProps<T, S, F>) {
const {
registry,
properties,
title,
description,
uiSchema,
required,
schema,
idSchema,
} = props;
const [collapsed, setCollapsed] = useState(false);
const out = (
<div>
{title} hiii{description}
<Button
variant="outlined"
size="small"
style={{
display: 'inline-block',
float: 'right',
fontSize: 'large',
}}
onClick={() => setCollapsed(!collapsed)}
>
Collapse
</Button>
<div>
{collapsed
? null
: properties.map(prop => (
<div key={prop.content.key}>
<Button
variant="outlined"
size="small"
style={{
display: 'inline-block',
float: 'right',
fontSize: 'large',
}}
onClick={() => setCollapsed(!collapsed)}
>
Collapse
</Button>
{prop.content}
</div>
))}
</div>
</div>
);
return out;
// return (
// <>
// {hidden ? null : (
// <div className={classNames}>
// <>
// {!isThisTheTopmostElement() && (
// <Button
// variant="outlined"
// size="small"
// style={{
// display: 'inline-block',
// float: 'right',
// fontSize: 'large',
// }}
// onClick={() => setCollapsed(!collapsed)}
// >
// {collapsed ? (
// <>
// +
// {(errors?.props?.errors ?? []).length ? (
// <span style={{ fontSize: 'small' }}>
// {' '}
// (Contains errors)
// </span>
// ) : null}
// </>
// ) : (
// '-'
// )}
// </Button>
// )}
// {get(schema, 'type', undefined) !== 'object' &&
// get(schema, 'type', undefined) !== 'array' ? (
// <>{label ? `${label}${required ? ' *required' : ''}` : null}</>
// ) : (
// <fieldset className="field field-array field-array-of-object">
// {label ? (
// <legend>{`${label}${required ? '*required' : ''}`}</legend>
// ) : null}
// </fieldset>
// )}
// {!collapsed && (
// <>
// {get(schema, 'type', undefined) !== 'object' &&
// get(schema, 'type', undefined) !== 'array'
// ? description
// : null}
// {children}
// {errors}
// {help}
// </>
// )}
// </>
// </div>
// )}
// </>
// );
}
export const CollapsableField = scaffolderPlugin.provide(
createScaffolderLayout({
name: 'CollapsableField',
component: CollapsableFieldTemplate,
}),
);

View file

@ -36,6 +36,8 @@
"@backstage/plugin-search-backend-module-pg": "^0.5.6",
"@backstage/plugin-search-backend-node": "^1.2.1",
"@backstage/plugin-techdocs-backend": "^1.6.2",
"@backstage/types": "^1.1.0",
"@internal/plugin-argo-workflows-backend-backend": "^0.1.0",
"@kubernetes/client-node": "^0.18.1",
"@roadiehq/scaffolder-backend-module-utils": "^1.8.7",
"app": "link:../app",
@ -44,7 +46,8 @@
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"pg": "^8.3.0",
"winston": "^3.2.1"
"winston": "^3.2.1",
"yaml": "^2.3.1"
},
"devDependencies": {
"@backstage/cli": "^0.22.7",

View file

@ -5,7 +5,11 @@ import {
} from '@backstage/plugin-auth-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import {DEFAULT_NAMESPACE, stringifyEntityRef} from "@backstage/catalog-model";
import {
DEFAULT_NAMESPACE,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { JsonArray } from '@backstage/types';
export default async function createPlugin(
env: PluginEnvironment,
@ -26,83 +30,16 @@ export default async function createPlugin(
name: info.result.userinfo.sub,
namespace: DEFAULT_NAMESPACE,
});
console.log(info.result.userinfo.groups)
return ctx.issueToken({
claims: {
sub: userRef, // The user's own identity
ent: [userRef], // A list of identities that the user claims ownership through
sub: userRef,
ent: [userRef],
groups: (info.result.userinfo.groups as JsonArray) || [],
},
});
},
},
}),
},
// providerFactories: {
// ...defaultAuthProviderFactories,
// oauth2Proxy: providers.oauth2Proxy.create({
// signIn: {
// async resolver({ result }, ctx) {
// console.log(result)
// const name = result.getHeader('x-forwarded-preferred-username');
// if (!name) {
// throw new Error('Request did not contain a user');
// }
//
// try {
// // Attempts to sign in existing user
// const signedInUser = await ctx.signInWithCatalogUser({
// entityRef: { name },
// });
//
// return Promise.resolve(signedInUser);
// } catch (e) {
// // Create stub user
// const userEntityRef = stringifyEntityRef({
// kind: 'User',
// name: name,
// namespace: DEFAULT_NAMESPACE,
// });
// return ctx.issueToken({
// claims: {
// sub: userEntityRef,
// ent: [userEntityRef],
// },
// });
// }
// },
// },
// }),
// // This replaces the default GitHub auth provider with a customized one.
// // The `signIn` option enables sign-in for this provider, using the
// // identity resolution logic that's provided in the `resolver` callback.
// //
// // This particular resolver makes all users share a single "guest" identity.
// // It should only be used for testing and trying out Backstage.
// //
// // If you want to use a production ready resolver you can switch to
// // the one that is commented out below, it looks up a user entity in the
// // catalog using the GitHub username of the authenticated user.
// // That resolver requires you to have user entities populated in the catalog,
// // for example using https://backstage.io/docs/integrations/github/org
// //
// // There are other resolvers to choose from, and you can also create
// // your own, see the auth documentation for more details:
// //
// // https://backstage.io/docs/auth/identity-resolver
// // github: providers.github.create({
// // signIn: {
// // resolver(_, ctx) {
// // const userRef = 'user:default/guest'; // Must be a full entity reference
// // return ctx.issueToken({
// // claims: {
// // sub: userRef, // The user's own identity
// // ent: [userRef], // A list of identities that the user claims ownership through
// // },
// // });
// // },
// // // resolver: providers.github.resolvers.usernameMatchingUserEntityName(),
// // },
// // }),
// },
});
}

View file

@ -64,7 +64,7 @@ export const kubernetesApply = (config: Config) => {
const words = obj.apiVersion.split('/');
const group = words[0];
const version = words[1];
//hack. needs fixing to correctly extract the plurals
// hack. needs fixing to correctly extract the plurals
const plural = `${obj.kind.toLowerCase()}s`;
const targetCluster = getClusterConfig(ctx.input.clusterName!, config);
// hack. needs fixing to get the KubeConfig info from app-config.yaml

View file

@ -1,19 +1,18 @@
import {KubernetesBuilder, OidcKubernetesAuthTranslator} from '@backstage/plugin-kubernetes-backend';
import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import { CatalogClient } from '@backstage/catalog-client';
export default async function createPlugin(
env: PluginEnvironment,
env: PluginEnvironment,
): Promise<Router> {
const catalogApi = new CatalogClient({discoveryApi: env.discovery});
const {router} = await KubernetesBuilder.createBuilder({
logger: env.logger,
config: env.config,
catalogApi,
permissions: env.permissions
}).build();
const catalogApi = new CatalogClient({ discoveryApi: env.discovery });
const { router } = await KubernetesBuilder.createBuilder({
logger: env.logger,
config: env.config,
catalogApi,
permissions: env.permissions,
}).build();
new OidcKubernetesAuthTranslator()
return router;
return router;
}

View file

@ -1,9 +1,12 @@
import { CatalogClient } from '@backstage/catalog-client';
import {createBuiltinActions, createRouter} from '@backstage/plugin-scaffolder-backend';
import {
createBuiltinActions,
createRouter,
} from '@backstage/plugin-scaffolder-backend';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
import { ScmIntegrations } from '@backstage/integration';
import {createInvokeArgoAction} from './workflow-argo'
import { createInvokeArgoAction } from './workflow-argo';
import {
createZipAction,
createSleepAction,
@ -18,6 +21,7 @@ import {
createYamlJSONataTransformAction,
createJsonJSONataTransformAction,
} from '@roadiehq/scaffolder-backend-module-utils';
import { kubernetesApply } from './kubernetes-apply';
export default async function createPlugin(
env: PluginEnvironment,
@ -34,7 +38,7 @@ export default async function createPlugin(
reader: env.reader,
});
const scaffolderBackendModuleUtils = [
const scaffolderBackendModuleUtils = [
createZipAction(),
createSleepAction(),
createWriteFileAction(),
@ -46,10 +50,15 @@ export default async function createPlugin(
createSerializeJsonAction(),
createJSONataAction(),
createYamlJSONataTransformAction(),
createJsonJSONataTransformAction()
]
const actions = [...builtInActions, ...scaffolderBackendModuleUtils, createInvokeArgoAction(env.config, env.logger)];
createJsonJSONataTransformAction(),
];
const actions = [
...builtInActions,
...scaffolderBackendModuleUtils,
createInvokeArgoAction(env.config, env.logger),
kubernetesApply(env.config),
];
return await createRouter({
actions: actions,

812
yarn.lock

File diff suppressed because it is too large Load diff