Files
lens/src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx
T
Roman be4e1aa15c Navigation refactoring, handling extension page params (#1651)
* decentralizing page url-params management -- PoC / tsc 4.1 random fixes

Signed-off-by: Roman <ixrock@gmail.com>

* fixes, tweak example-extension for demo

Signed-off-by: Roman <ixrock@gmail.com>

* lint fixes, revert tests

Signed-off-by: Roman <ixrock@gmail.com>

* removed occasional changes related to typescript 4.1

Signed-off-by: Roman <ixrock@gmail.com>

* updated example with 2 menu-items targeting same page with different params

Signed-off-by: Roman <ixrock@gmail.com>

* fix: merge page url chunks with native URL()-api, simplified default page-params registration

Signed-off-by: Roman <ixrock@gmail.com>

* fix: make lint happy

Signed-off-by: Roman <ixrock@gmail.com>

* fix: unit-tests

Signed-off-by: Roman <ixrock@gmail.com>

* renaming by jim's request: UrlParam => PageParam (type), createUrlParam => createPageParam (helper)

Signed-off-by: Roman <ixrock@gmail.com>

* fix: reverting NamespaceStore public-api breaking changes

Signed-off-by: Roman <ixrock@gmail.com>

* lint fix

Signed-off-by: Roman <ixrock@gmail.com>

* fine-tuning

Signed-off-by: Roman <ixrock@gmail.com>

* yes, lint always unhappy

Signed-off-by: Roman <ixrock@gmail.com>

* fix build

Signed-off-by: Roman <ixrock@gmail.com>

* small fixes

Signed-off-by: Roman <ixrock@gmail.com>

* fix merge-conflicts

Signed-off-by: Roman <ixrock@gmail.com>

* removed `isSystem` page-param's init field exposed to extensions-api

Signed-off-by: Roman <ixrock@gmail.com>
2020-12-22 15:29:25 +02:00

157 lines
4.3 KiB
TypeScript

import "./service-accounts-details.scss";
import React from "react";
import { autorun, observable } from "mobx";
import { Trans } from "@lingui/macro";
import { Spinner } from "../spinner";
import { ServiceAccountsSecret } from "./service-accounts-secret";
import { DrawerItem, DrawerTitle } from "../drawer";
import { disposeOnUnmount, observer } from "mobx-react";
import { secretsStore } from "../+config-secrets/secrets.store";
import { Link } from "react-router-dom";
import { Secret, ServiceAccount } from "../../api/endpoints";
import { KubeEventDetails } from "../+events/kube-event-details";
import { getDetailsUrl, KubeObjectDetailsProps } from "../kube-object";
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
import { Icon } from "../icon";
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
interface Props extends KubeObjectDetailsProps<ServiceAccount> {
}
@observer
export class ServiceAccountsDetails extends React.Component<Props> {
@observable secrets: Secret[];
@observable imagePullSecrets: Secret[];
@disposeOnUnmount
loadSecrets = autorun(async () => {
this.secrets = null;
this.imagePullSecrets = null;
const { object: serviceAccount } = this.props;
if (!serviceAccount) {
return;
}
const namespace = serviceAccount.getNs();
const secrets = serviceAccount.getSecrets().map(({ name }) => {
return secretsStore.load({ name, namespace });
});
this.secrets = await Promise.all(secrets);
const imagePullSecrets = serviceAccount.getImagePullSecrets().map(async({ name }) => {
return secretsStore.load({ name, namespace }).catch(() => this.generateDummySecretObject(name));
});
this.imagePullSecrets = await Promise.all(imagePullSecrets);
});
renderSecrets() {
const { secrets } = this;
if (!secrets) {
return <Spinner center/>;
}
return secrets.map(secret =>
<ServiceAccountsSecret key={secret.getId()} secret={secret}/>
);
}
renderImagePullSecrets() {
const { imagePullSecrets } = this;
if (!imagePullSecrets) {
return <Spinner center/>;
}
return this.renderSecretLinks(imagePullSecrets);
}
renderSecretLinks(secrets: Secret[]) {
return secrets.map((secret) => {
if (secret.getId() === null) {
return (
<div key={secret.getName()}>
{secret.getName()}
<Icon
small material="warning"
tooltip={<Trans>Secret is not found</Trans>}
/>
</div>
);
}
return (
<Link key={secret.getId()} to={getDetailsUrl(secret.selfLink)}>
{secret.getName()}
</Link>
);
});
}
generateDummySecretObject(name: string) {
return new Secret({
apiVersion: "v1",
kind: "Secret",
metadata: {
name,
uid: null,
selfLink: null,
resourceVersion: null
}
});
}
render() {
const { object: serviceAccount } = this.props;
if (!serviceAccount) {
return null;
}
const tokens = secretsStore.items.filter(secret =>
secret.getNs() == serviceAccount.getNs() &&
secret.getAnnotations().some(annot => annot == `kubernetes.io/service-account.name: ${serviceAccount.getName()}`)
);
const imagePullSecrets = serviceAccount.getImagePullSecrets();
return (
<div className="ServiceAccountsDetails">
<KubeObjectMeta object={serviceAccount}/>
{tokens.length > 0 &&
<DrawerItem name={<Trans>Tokens</Trans>} className="links">
{this.renderSecretLinks(tokens)}
</DrawerItem>
}
{imagePullSecrets.length > 0 &&
<DrawerItem name={<Trans>ImagePullSecrets</Trans>} className="links">
{this.renderImagePullSecrets()}
</DrawerItem>
}
<DrawerTitle title={<Trans>Mountable secrets</Trans>}/>
<div className="secrets">
{this.renderSecrets()}
</div>
</div>
);
}
}
kubeObjectDetailRegistry.add({
kind: "ServiceAccount",
apiVersions: ["v1"],
components: {
Details: (props) => <ServiceAccountsDetails {...props} />
}
});
kubeObjectDetailRegistry.add({
kind: "ServiceAccount",
apiVersions: ["v1"],
priority: 5,
components: {
Details: (props) => <KubeEventDetails {...props} />
}
});