diff --git a/docs/extensions/capabilities/common-capabilities.md b/docs/extensions/capabilities/common-capabilities.md
index a399a7bc03..4993e94181 100644
--- a/docs/extensions/capabilities/common-capabilities.md
+++ b/docs/extensions/capabilities/common-capabilities.md
@@ -189,36 +189,6 @@ export default class ExampleExtension extends Renderer.LensExtension {
```
-### Cluster Features
-
-This extension can register installable features for a cluster.
-These features are visible in the "Cluster Settings" page.
-
-```typescript
-import React from "react"
-import { Renderer } from "@k8slens/extensions"
-import { MyCustomFeature } from "./src/my-custom-feature"
-
-export default class ExampleExtension extends Renderer.LensExtension {
- clusterFeatures = [
- {
- title: "My Custom Feature",
- components: {
- Description: () => {
- return (
-
- Just an example.
-
- )
- }
- },
- feature: new MyCustomFeature()
- }
- ]
-}
-
-```
-
### Top Bar Items
This extension can register custom components to a top bar area.
diff --git a/docs/extensions/guides/images/clusterfeature.png b/docs/extensions/guides/images/clusterfeature.png
new file mode 100644
index 0000000000..ada8beba6f
Binary files /dev/null and b/docs/extensions/guides/images/clusterfeature.png differ
diff --git a/docs/extensions/guides/resource-stack.md b/docs/extensions/guides/resource-stack.md
index dc22858413..8d36bb6495 100644
--- a/docs/extensions/guides/resource-stack.md
+++ b/docs/extensions/guides/resource-stack.md
@@ -1,14 +1,31 @@
-# Resource Stack (Cluster Feature) (WIP)
+# Resource Stack (Cluster Feature)
-Cluster features are Kubernetes resources that can be applied to and managed within the active cluster.
+A cluster feature is a set of Kubernetes resources that can be applied to and managed within the active cluster.
The `Renderer.K8sApi.ResourceStack` class provides the functionality to input and apply kubernetes resources to a cluster.
-It is up to the extension developer to manage the lifecycle of the resource stack.
-It could be applied automatically to a cluster by the extension or the end-user could be required to install it, etc. from the cluster **Settings** page.
+It is up to the extension developer to manage the life cycle of the resource stack.
+It could be applied automatically to a cluster by the extension, or the end-user could be required to install it.
+
+The code examples in this section show how to create a resource stack, and define a cluster feature that is configurable from the cluster **Settings** page.
!!! info
To access the cluster **Settings** page, right-click the relevant cluster in the left side menu and click **Settings**.
-The following example shows how to add a cluster feature using a resource stack as part of a `Renderer.LensExtension`:
+The resource stack in this example consists of a single kubernetes resource:
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: example-pod
+spec:
+ containers:
+ - name: example-pod
+ image: nginx
+```
+
+It is simply a pod named `example-pod`, running nginx. Assume this content is in the file `../resources/example-pod.yml`.
+
+The following code sample shows how to use the `Renderer.K8sApi.ResourceStack` to manage installing and uninstalling this resource stack:
```typescript
import { Renderer, Common } from "@k8slens/extensions";
@@ -26,7 +43,7 @@ type ResourceStack = Renderer.K8sApi.ResourceStack;
type Pod = Renderer.K8sApi.Pod;
type KubernetesCluster = Common.Catalog.KubernetesCluster;
-export class ExampleResourceStack {
+export class ExampleClusterFeature {
protected stack: ResourceStack;
constructor(protected cluster: KubernetesCluster) {
@@ -66,19 +83,27 @@ export class ExampleResourceStack {
}
```
-The `ExampleResourceStack` cluster feature can be managed by the end-user on the cluster **Settings** page via a `Renderer.LensExtension.entitySettings` entry.
+The `ExampleClusterFeature` class constructor takes a `Common.Catalog.KubernetesCluster` argument.
+This is the cluster that the resource stack will be applied to, and the constructor instantiates a `Renderer.K8sApi.ResourceStack` as such.
+`ExampleClusterFeature` implements an `install()` method which simply invokes the `kubectlApplyFolder()` method of the `Renderer.K8sApi.ResourceStack` class.
+`kubectlApplyFolder()` applies to the cluster all kubernetes resources found in the folder passed to it, in this case `../resources`.
+Similarly, `ExampleClusterFeature` implements an `uninstall()` method which simply invokes the `kubectlDeleteFolder()` method of the `Renderer.K8sApi.ResourceStack` class.
+`kubectlDeleteFolder()` tries to delete from the cluster all kubernetes resources found in the folder passed to it, again in this case `../resources`.
+
+`ExampleClusterFeature` also implements an `isInstalled()` method, which demonstrates how you can utiliize the kubernetes api to inspect the resource stack status.
+`isInstalled()` simply tries to find a pod named `example-pod`, as a way to determine if the pod is already installed.
+This method can be useful in creating a context-sensitive UI for installing/uninstalling the feature, as demonstrated in the next sample code.
+
+To allow the end-user to control the life cycle of this cluster feature the following code sample shows how to implement a user interface based on React and custom Lens UI components:
```typescript
import React from "react";
import { Common, Renderer } from "@k8slens/extensions";
import { observer } from "mobx-react";
import { computed, observable, makeObservable } from "mobx";
- import { ExampleResourceStack } from "./example-resource-stack";
+ import { ExampleClusterFeature } from "./example-cluster-feature";
const {
- K8sApi: {
- forCluster, StatefulSet, DaemonSet, Deployment,
- },
Component: {
SubTitle, Button,
}
@@ -89,7 +114,7 @@ The `ExampleResourceStack` cluster feature can be managed by the end-user on the
}
@observer
- export class ExampleResourceStackSettings extends React.Component {
+ export class ExampleClusterFeatureSettings extends React.Component {
constructor(props: Props) {
super(props);
makeObservable(this);
@@ -98,10 +123,10 @@ The `ExampleResourceStack` cluster feature can be managed by the end-user on the
@observable installed = false;
@observable inProgress = false;
- feature: ExampleResourceStack;
+ feature: ExampleClusterFeature;
async componentDidMount() {
- this.feature = new ExampleResourceStack(this.props.cluster);
+ this.feature = new ExampleClusterFeature(this.props.cluster);
await this.updateFeatureState();
}
@@ -141,7 +166,7 @@ The `ExampleResourceStack` cluster feature can be managed by the end-user on the
return (
<>
-
+