Dynamic dashboard UI based on RBAC rules (#366)

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen authored and GitHub committed 2020-06-05 08:38:56 +03:00
1 parent 65900e728d
commit a7cb8d2d04
16 files changed
+213 -97

No files matched your search

@@ -16,10 +16,11 @@
.workloads {
display: grid;
grid-template-columns: repeat(auto-fit, 155px);
justify-content: space-between;
justify-content: space-evenly;
grid-gap: $margin;
padding: $padding * 2;
.workload {
margin-bottom: $margin * 2;
@@ -32,4 +33,4 @@
}
}
}
}
}
@@ -15,17 +15,20 @@ import { cronJobStore } from "../+workloads-cronjobs/cronjob.store";
import { namespaceStore } from "../+namespaces/namespace.store";
import { PageFiltersList } from "../item-object-list/page-filters-list";
import { NamespaceSelectFilter } from "../+namespaces/namespace-select";
import { configStore } from "../../config.store";
import { isAllowedResource } from "../../api/rbac";
@observer
export class OverviewStatuses extends React.Component {
render() {
const { allowedResources } = configStore;
const { contextNs } = namespaceStore;
const pods = podsStore.getAllByNs(contextNs);
const deployments = deploymentStore.getAllByNs(contextNs);
const statefulSets = statefulSetStore.getAllByNs(contextNs);
const daemonSets = daemonSetStore.getAllByNs(contextNs);
const jobs = jobStore.getAllByNs(contextNs);
const cronJobs = cronJobStore.getAllByNs(contextNs);
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) : [];
return (
<div className="OverviewStatuses">
<div className="header flex gaps align-center">
@@ -34,30 +37,42 @@ export class OverviewStatuses extends React.Component {
</div>
<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>
}
</div>
</div>
)
@@ -16,6 +16,8 @@ import { jobStore } from "../+workloads-jobs/job.store";
import { cronJobStore } from "../+workloads-cronjobs/cronjob.store";
import { Spinner } from "../spinner";
import { Events } from "../+events";
import { KubeObjectStore } from "../../kube-object.store";
import { isAllowedResource } from "../../api/rbac"
interface Props extends RouteComponentProps<IWorkloadsOverviewRouteParams> {
}
@@ -26,16 +28,31 @@ export class WorkloadsOverview extends React.Component<Props> {
@observable isUnmounting = false;
async componentDidMount() {
const stores = [
podsStore,
deploymentStore,
daemonSetStore,
statefulSetStore,
replicaSetStore,
jobStore,
cronJobStore,
eventStore,
];
const stores: KubeObjectStore[] = [];
if (isAllowedResource("pods")) {
stores.push(podsStore);
}
if (isAllowedResource("deployments")) {
stores.push(deploymentStore);
}
if (isAllowedResource("daemonsets")) {
stores.push(daemonSetStore);
}
if (isAllowedResource("statefulsets")) {
stores.push(statefulSetStore);
}
if (isAllowedResource("replicasets")) {
stores.push(replicaSetStore);
}
if (isAllowedResource("jobs")) {
stores.push(jobStore);
}
if (isAllowedResource("cronjobs")) {
stores.push(cronJobStore);
}
if (isAllowedResource("events")) {
stores.push(eventStore);
}
this.isReady = stores.every(store => store.isLoaded);
await Promise.all(stores.map(store => store.loadAll()));
this.isReady = true;
@@ -55,11 +72,11 @@ export class WorkloadsOverview extends React.Component<Props> {
return (
<>
<OverviewStatuses/>
<Events
{ isAllowedResource("events") && <Events
compact
hideFilters
className="box grow"
/>
/> }
</>
)
}
@@ -71,4 +88,4 @@ export class WorkloadsOverview extends React.Component<Props> {
</div>
)
}
}
}