Allow extensions to define cluster features (#1125)

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen authored and GitHub committed 2020-10-26 08:21:22 +02:00
1 parent f3a0059355
commit 62ae7771df
81 files changed
+4069 -510

No files matched your search

@@ -1,72 +1,87 @@
import React from "react";
import { observable, reaction, comparer } from "mobx";
import { observer, disposeOnUnmount } from "mobx-react";
import { clusterIpc } from "../../../../common/cluster-ipc";
import { Cluster } from "../../../../main/cluster";
import { Button } from "../../button";
import { Notifications } from "../../notifications";
import { Spinner } from "../../spinner";
import { ClusterFeature } from "../../../../extensions/cluster-feature";
import { interval } from "../../../utils";
interface Props {
cluster: Cluster
feature: string
feature: ClusterFeature
}
@observer
export class InstallFeature extends React.Component<Props> {
@observable loading = false;
@observable message = "";
componentDidMount() {
const feature = this.props.feature
const cluster = this.props.cluster
const statusUpdate = interval(20, () => {
feature.updateStatus(cluster)
})
statusUpdate.start(true)
disposeOnUnmount(this, () => {
statusUpdate.stop()
})
disposeOnUnmount(this,
reaction(() => this.props.cluster.features[this.props.feature], () => {
reaction(() => feature.status.installed, () => {
this.loading = false;
this.message = ""
}, { equals: comparer.structural })
);
}
getActionButtons() {
const { cluster, feature } = this.props;
const features = cluster.features[feature];
const disabled = !cluster.isAdmin || this.loading;
const loadingIcon = this.loading ? <Spinner/> : null;
if (!features) return null;
return (
<div className="flex gaps align-center">
{features.canUpgrade &&
{feature.status.canUpgrade &&
<Button
primary
disabled={disabled}
onClick={this.runAction(() =>
clusterIpc.upgradeFeature.invokeFromRenderer(cluster.id, feature))
}
feature.upgrade(cluster)
)}
>
Upgrade
</Button>
}
{features.installed &&
{feature.status.installed &&
<Button
accent
disabled={disabled}
onClick={this.runAction(() =>
clusterIpc.uninstallFeature.invokeFromRenderer(cluster.id, feature))
}
onClick={this.runAction(async () => {
this.message = "Uninstalling feature ..."
feature.uninstall(cluster)
})}
>
Uninstall
</Button>
}
{!features.installed && !features.canUpgrade &&
{!feature.status.installed && !feature.status.canUpgrade &&
<Button
primary
disabled={disabled}
onClick={this.runAction(() =>
clusterIpc.installFeature.invokeFromRenderer(cluster.id, feature))
}
onClick={this.runAction(async () =>{
this.message = "Installing feature ..."
feature.install(cluster)
})}
>
Install
</Button>
}
{loadingIcon}
{!cluster.isAdmin && <span className='admin-note'>Actions can only be performed by admins.</span>}
{cluster.isAdmin && this.loading && this.message !== "" && <span className='admin-note'>{this.message}</span>}
</div>
);
}
@@ -90,4 +105,4 @@ export class InstallFeature extends React.Component<Props> {
</>
);
}
}
}
@@ -2,8 +2,7 @@ import React from "react";
import { Cluster } from "../../../main/cluster";
import { InstallFeature } from "./components/install-feature";
import { SubTitle } from "../layout/sub-title";
import { MetricsFeature } from "../../../features/metrics";
import { UserModeFeature } from "../../../features/user-mode";
import { clusterFeatureRegistry } from "../../../extensions/registries/cluster-feature-registry";
interface Props {
cluster: Cluster;
@@ -12,31 +11,20 @@ interface Props {
export class Features extends React.Component<Props> {
render() {
const { cluster } = this.props;
return (
<div>
<h2>Features</h2>
<InstallFeature cluster={cluster} feature={MetricsFeature.id}>
<>
<SubTitle title="Metrics"/>
<p>
Enable timeseries data visualization (Prometheus stack) for your cluster.
Install this only if you don't have existing Prometheus stack installed.
You can see preview of manifests{" "}
<a href="https://github.com/lensapp/lens/tree/master/src/features/metrics" target="_blank">here</a>.
</p>
</>
</InstallFeature>
<InstallFeature cluster={cluster} feature={UserModeFeature.id}>
<>
<SubTitle title="User Mode"/>
<p>
User Mode feature enables non-admin users to see namespaces they have access to.{" "}
This is achieved by configuring RBAC rules so that every authenticated user is granted to list namespaces.
</p>
</>
</InstallFeature>
{ clusterFeatureRegistry.getItems().map((f) => {
return (
<InstallFeature cluster={cluster} feature={f.feature}>
<>
<SubTitle title={f.title}/>
<p><f.components.Description /></p>
</>
</InstallFeature>
)
})}
</div>
);
}
}
}