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 ( <>
- +