mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
refactor overview statuses to be more DRY
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
0fedba5b66
commit
8edeeb64e7
@ -6,6 +6,32 @@ export type KubeResource =
|
||||
"pods" | "daemonsets" | "deployments" | "statefulsets" | "replicasets" | "jobs" | "cronjobs" |
|
||||
"endpoints" | "customresourcedefinitions" | "horizontalpodautoscalers" | "podsecuritypolicies" | "poddisruptionbudgets"
|
||||
|
||||
export const ResourceNames: Record<KubeResource, string> = {
|
||||
"namespaces": "Namespaces",
|
||||
"nodes": "Nodes",
|
||||
"events": "Events",
|
||||
"resourcequotas": "Resource Quotas",
|
||||
"services": "Services",
|
||||
"secrets": "Secrets",
|
||||
"configmaps": "Config Maps",
|
||||
"ingresses": "Ingresses",
|
||||
"networkpolicies": "Network Policies",
|
||||
"persistentvolumes": "Persistent Volumes",
|
||||
"storageclasses": "Storage Classes",
|
||||
"pods": "Pods",
|
||||
"daemonsets": "Daemon Sets",
|
||||
"deployments": "Deployments",
|
||||
"statefulsets": "Stateful Sets",
|
||||
"replicasets": "Replica Sets",
|
||||
"jobs": "Jobs",
|
||||
"cronjobs": "Cron Jobs",
|
||||
"endpoints": "Endpoints",
|
||||
"customresourcedefinitions": "Custom Resource Definitions",
|
||||
"horizontalpodautoscalers": "Horizontal Pod Autoscalers",
|
||||
"podsecuritypolicies": "Pod Security Policies",
|
||||
"poddisruptionbudgets": "Pod Disruption Budgets",
|
||||
}
|
||||
|
||||
export interface KubeApiResource {
|
||||
resource: KubeResource; // valid resource name
|
||||
group?: string; // api-group
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { StatusKubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { CronJob, cronJobApi } from "../../api/endpoints/cron-job.api";
|
||||
import { jobStore } from "../+workloads-jobs/job.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class CronJobStore extends KubeObjectStore<CronJob> {
|
||||
export class CronJobStore extends StatusKubeObjectStore<CronJob> {
|
||||
api = cronJobApi
|
||||
|
||||
getStatuses(cronJobs?: CronJob[]) {
|
||||
|
||||
@ -1,21 +1,20 @@
|
||||
import { observable } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { StatusKubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { DaemonSet, daemonSetApi, IPodMetrics, Pod, podsApi, PodStatus } from "../../api/endpoints";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class DaemonSetStore extends KubeObjectStore<DaemonSet> {
|
||||
export class DaemonSetStore extends StatusKubeObjectStore<DaemonSet> {
|
||||
api = daemonSetApi
|
||||
|
||||
@observable metrics: IPodMetrics = null;
|
||||
|
||||
loadMetrics(daemonSet: DaemonSet) {
|
||||
async loadMetrics(daemonSet: DaemonSet) {
|
||||
const pods = this.getChildPods(daemonSet);
|
||||
return podsApi.getMetrics(pods, daemonSet.getNs(), "").then(metrics =>
|
||||
this.metrics = metrics
|
||||
);
|
||||
const metrics = await podsApi.getMetrics(pods, daemonSet.getNs(), "");
|
||||
return this.metrics = metrics;
|
||||
}
|
||||
|
||||
getChildPods(daemonSet: DaemonSet): Pod[] {
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { observable } from "mobx";
|
||||
import { Deployment, deploymentApi, IPodMetrics, podsApi, PodStatus } from "../../api/endpoints";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { StatusKubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class DeploymentStore extends KubeObjectStore<Deployment> {
|
||||
export class DeploymentStore extends StatusKubeObjectStore<Deployment> {
|
||||
api = deploymentApi
|
||||
@observable metrics: IPodMetrics = null;
|
||||
|
||||
@ -16,11 +16,10 @@ export class DeploymentStore extends KubeObjectStore<Deployment> {
|
||||
], "desc");
|
||||
}
|
||||
|
||||
loadMetrics(deployment: Deployment) {
|
||||
async loadMetrics(deployment: Deployment) {
|
||||
const pods = this.getChildPods(deployment);
|
||||
return podsApi.getMetrics(pods, deployment.getNs(), "").then(metrics =>
|
||||
this.metrics = metrics
|
||||
);
|
||||
const metrics = await podsApi.getMetrics(pods, deployment.getNs(), "");
|
||||
return this.metrics = metrics;
|
||||
}
|
||||
|
||||
getStatuses(deployments?: Deployment[]) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { StatusKubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { Job, jobApi } from "../../api/endpoints/job.api";
|
||||
import { CronJob, Pod, PodStatus } from "../../api/endpoints";
|
||||
@ -6,7 +6,7 @@ import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class JobStore extends KubeObjectStore<Job> {
|
||||
export class JobStore extends StatusKubeObjectStore<Job> {
|
||||
api = jobApi
|
||||
|
||||
getChildPods(job: Job): Pod[] {
|
||||
|
||||
@ -5,72 +5,54 @@ import { observer } from "mobx-react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { OverviewWorkloadStatus } from "./overview-workload-status";
|
||||
import { Link } from "react-router-dom";
|
||||
import { cronJobsURL, daemonSetsURL, deploymentsURL, jobsURL, podsURL, statefulSetsURL } from "../+workloads";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { deploymentStore } from "../+workloads-deployments/deployments.store";
|
||||
import { daemonSetStore } from "../+workloads-daemonsets/daemonsets.store";
|
||||
import { statefulSetStore } from "../+workloads-statefulsets/statefulset.store";
|
||||
import { jobStore } from "../+workloads-jobs/job.store";
|
||||
import { cronJobStore } from "../+workloads-cronjobs/cronjob.store";
|
||||
import { resourceURL, resourceStores } from "../+workloads";
|
||||
import { namespaceStore } from "../+namespaces/namespace.store";
|
||||
import { PageFiltersList } from "../item-object-list/page-filters-list";
|
||||
import { NamespaceSelectFilter } from "../+namespaces/namespace-select";
|
||||
import { isAllowedResource } from "../../../common/rbac";
|
||||
import { isAllowedResource, KubeResource, ResourceNames } from "../../../common/rbac";
|
||||
import { autobind } from "../../utils";
|
||||
import { _i18n } from "../../i18n";
|
||||
|
||||
const resources: KubeResource[] = [
|
||||
"pods",
|
||||
"deployments",
|
||||
"statefulsets",
|
||||
"daemonsets",
|
||||
"jobs",
|
||||
"cronjobs",
|
||||
]
|
||||
|
||||
@observer
|
||||
export class OverviewStatuses extends React.Component {
|
||||
@autobind()
|
||||
renderWorkload(resource: KubeResource): React.ReactElement | null {
|
||||
const store = resourceStores[resource];
|
||||
const items = store.getAllByNs([...namespaceStore.contextNs])
|
||||
const name = _i18n._(ResourceNames[resource])
|
||||
return (
|
||||
<div className="workload" key={resource}>
|
||||
<div className="title">
|
||||
<Link to={resourceURL[resource]()}>{name} ({items.length})</Link>
|
||||
</div>
|
||||
<OverviewWorkloadStatus status={store.getStatuses(items)} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { contextNs } = namespaceStore;
|
||||
const pods = isAllowedResource("pods") ? podsStore.getAllByNs(contextNs) : [];
|
||||
const deployments = isAllowedResource("deployments") ? deploymentStore.getAllByNs(contextNs) : [];
|
||||
const statefulSets = isAllowedResource("statefulsets") ? statefulSetStore.getAllByNs(contextNs) : [];
|
||||
const daemonSets = isAllowedResource("daemonsets") ? daemonSetStore.getAllByNs(contextNs) : [];
|
||||
const jobs = isAllowedResource("jobs") ? jobStore.getAllByNs(contextNs) : [];
|
||||
const cronJobs = isAllowedResource("cronjobs") ? cronJobStore.getAllByNs(contextNs) : [];
|
||||
const workloads = resources
|
||||
.filter(isAllowedResource)
|
||||
.map(this.renderWorkload);
|
||||
|
||||
return (
|
||||
<div className="OverviewStatuses">
|
||||
<div className="header flex gaps align-center">
|
||||
<h5 className="box grow"><Trans>Overview</Trans></h5>
|
||||
<NamespaceSelectFilter/>
|
||||
<NamespaceSelectFilter />
|
||||
</div>
|
||||
<PageFiltersList/>
|
||||
<PageFiltersList />
|
||||
<div className="workloads">
|
||||
{isAllowedResource("pods") &&
|
||||
<div className="workload">
|
||||
<div className="title"><Link to={podsURL()}><Trans>Pods</Trans> ({pods.length})</Link></div>
|
||||
<OverviewWorkloadStatus status={podsStore.getStatuses(pods)}/>
|
||||
</div>
|
||||
}
|
||||
{isAllowedResource("deployments") &&
|
||||
<div className="workload">
|
||||
<div className="title"><Link to={deploymentsURL()}><Trans>Deployments</Trans> ({deployments.length})</Link></div>
|
||||
<OverviewWorkloadStatus status={deploymentStore.getStatuses(deployments)}/>
|
||||
</div>
|
||||
}
|
||||
{isAllowedResource("statefulsets") &&
|
||||
<div className="workload">
|
||||
<div className="title"><Link to={statefulSetsURL()}><Trans>StatefulSets</Trans> ({statefulSets.length})</Link></div>
|
||||
<OverviewWorkloadStatus status={statefulSetStore.getStatuses(statefulSets)}/>
|
||||
</div>
|
||||
}
|
||||
{isAllowedResource("daemonsets") &&
|
||||
<div className="workload">
|
||||
<div className="title"><Link to={daemonSetsURL()}><Trans>DaemonSets</Trans> ({daemonSets.length})</Link></div>
|
||||
<OverviewWorkloadStatus status={daemonSetStore.getStatuses(daemonSets)}/>
|
||||
</div>
|
||||
}
|
||||
{isAllowedResource("jobs") &&
|
||||
<div className="workload">
|
||||
<div className="title"><Link to={jobsURL()}><Trans>Jobs</Trans> ({jobs.length})</Link></div>
|
||||
<OverviewWorkloadStatus status={jobStore.getStatuses(jobs)}/>
|
||||
</div>
|
||||
}
|
||||
{isAllowedResource("cronjobs") &&
|
||||
<div className="workload">
|
||||
<div className="title"><Link to={cronJobsURL()}><Trans>CronJobs</Trans> ({cronJobs.length})</Link></div>
|
||||
<OverviewWorkloadStatus status={cronJobStore.getStatuses(cronJobs)}/>
|
||||
</div>
|
||||
}
|
||||
{workloads}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import countBy from "lodash/countBy";
|
||||
import { action, observable } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { StatusKubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind, cpuUnitsToNumber, unitsToBytes } from "../../utils";
|
||||
import { IPodMetrics, Pod, PodMetrics, podMetricsApi, podsApi } from "../../api/endpoints";
|
||||
import { WorkloadKubeObject } from "../../api/workload-kube-object";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class PodsStore extends KubeObjectStore<Pod> {
|
||||
export class PodsStore extends StatusKubeObjectStore<Pod> {
|
||||
api = podsApi;
|
||||
|
||||
@observable metrics: IPodMetrics = null;
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
import { observable } from "mobx";
|
||||
import { autobind } from "../../utils";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { StatusKubeObjectStore } from "../../kube-object.store";
|
||||
import { IPodMetrics, podsApi, PodStatus, StatefulSet, statefulSetApi } from "../../api/endpoints";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class StatefulSetStore extends KubeObjectStore<StatefulSet> {
|
||||
export class StatefulSetStore extends StatusKubeObjectStore<StatefulSet> {
|
||||
api = statefulSetApi
|
||||
@observable metrics: IPodMetrics = null;
|
||||
|
||||
loadMetrics(statefulSet: StatefulSet) {
|
||||
async loadMetrics(statefulSet: StatefulSet) {
|
||||
const pods = this.getChildPods(statefulSet);
|
||||
return podsApi.getMetrics(pods, statefulSet.getNs(), "").then(metrics =>
|
||||
this.metrics = metrics
|
||||
);
|
||||
const metrics = await podsApi.getMetrics(pods, statefulSet.getNs(), "");
|
||||
return this.metrics = metrics;
|
||||
}
|
||||
|
||||
getChildPods(statefulSet: StatefulSet) {
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export * from "./workloads.route"
|
||||
export * from "./workloads"
|
||||
|
||||
export * from "./workloads.stores"
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { RouteProps } from "react-router"
|
||||
import { Workloads } from "./workloads";
|
||||
import { buildURL, IURLParams } from "../../navigation";
|
||||
import { KubeResource } from "../../../common/rbac";
|
||||
|
||||
export const workloadsRoute: RouteProps = {
|
||||
get path() {
|
||||
@ -62,3 +63,12 @@ export const daemonSetsURL = buildURL<IDaemonSetsRouteParams>(daemonSetsRoute.pa
|
||||
export const statefulSetsURL = buildURL<IStatefulSetsRouteParams>(statefulSetsRoute.path)
|
||||
export const jobsURL = buildURL<IJobsRouteParams>(jobsRoute.path)
|
||||
export const cronJobsURL = buildURL<ICronJobsRouteParams>(cronJobsRoute.path)
|
||||
|
||||
export const resourceURL: Partial<Record<KubeResource, ReturnType<typeof buildURL>>> = {
|
||||
"pods": podsURL,
|
||||
"deployments": deploymentsURL,
|
||||
"daemonsets": daemonSetsURL,
|
||||
"statefulsets": statefulSetsURL,
|
||||
"jobs": jobsURL,
|
||||
"cronjobs": cronJobsURL,
|
||||
}
|
||||
|
||||
17
src/renderer/components/+workloads/workloads.stores.ts
Normal file
17
src/renderer/components/+workloads/workloads.stores.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { StatusKubeObjectStore } from "../../kube-object.store";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { deploymentStore } from "../+workloads-deployments/deployments.store";
|
||||
import { daemonSetStore } from "../+workloads-daemonsets/daemonsets.store";
|
||||
import { statefulSetStore } from "../+workloads-statefulsets/statefulset.store";
|
||||
import { jobStore } from "../+workloads-jobs/job.store";
|
||||
import { cronJobStore } from "../+workloads-cronjobs/cronjob.store";
|
||||
import { KubeResource } from "../../../common/rbac";
|
||||
|
||||
export const resourceStores: Partial<Record<KubeResource, StatusKubeObjectStore>> = {
|
||||
"pods": podsStore,
|
||||
"deployments": deploymentStore,
|
||||
"daemonsets": daemonSetStore,
|
||||
"statefulsets": statefulSetStore,
|
||||
"jobs": jobStore,
|
||||
"cronjobs": cronJobStore,
|
||||
}
|
||||
@ -198,3 +198,11 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
|
||||
this.items.replace(this.sortItems(items));
|
||||
}
|
||||
}
|
||||
|
||||
export interface Statuses {
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
export abstract class StatusKubeObjectStore<T extends KubeObject = any> extends KubeObjectStore<T> {
|
||||
abstract getStatuses(items: T[]): Statuses;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user