From 626fe1a890fa8b5848f281a71b817d7a32dafbf8 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 11:26:14 +0300 Subject: [PATCH 01/24] Add MutatingWebhookConfiguration api Signed-off-by: Alex Andreev --- .../mutating-webhook-configuration.api.ts | 240 ++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts diff --git a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts new file mode 100644 index 0000000000..18bb5af431 --- /dev/null +++ b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts @@ -0,0 +1,240 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { LabelSelector, NamespaceScopedMetadata } from "../kube-object"; +import { KubeObject } from "../kube-object"; + +interface MutatingWebhookConfigurationStatus { + // The latest generation observed by the webhook. + observedGeneration?: number; + + // Conditions for the MutatingWebhookConfiguration. + conditions?: { + // Type of MutatingWebhookConfiguration condition. + type: string; + + // Status of the condition, one of True, False, Unknown. + status: string; + + // Reason for the current status of the condition. + reason?: string; + + // Message describing the current status of the condition. + message?: string; + }[]; + + // Webhooks that failed to be registered. + failedWebhooks?: { + // Name of the failed webhook. + name: string; + + // Failure type of the webhook. + failureType: string; + + // Reason for the failure. + reason?: string; + + // Message describing the failure. + message?: string; + }[]; + + // Webhooks that are not registered yet. + webhookConfigurations?: { + // Name of the webhook configuration. + name: string; + + // Namespace of the webhook configuration. + namespace: string; + + // API version of the webhook configuration. + apiVersion: string; + + // Kind of the webhook configuration. + kind: string; + + // Object reference to the webhook configuration. + objectReference?: { + // API version of the object reference. + apiVersion?: string; + + // Kind of the object reference. + kind: string; + + // Name of the object reference. + name: string; + + // Namespace of the object reference. + namespace?: string; + + // UID of the object reference. + uid?: string; + }; + }[]; +} + +interface WebhookClientConfig { + // `url` gives the location of the webhook + url?: string; + + // `service` is a reference to the service for this webhook. Either `service` or `url` must be specified. + service?: ServiceReference; + + // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. + // If unspecified, system trust roots on the apiserver are used. + caBundle?: string; +} + +interface RuleWithOperations { + // APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. + apiGroups: string[]; + + // APIVersions is the API versions the resources belong to. '*' is all versions. + apiVersions?: string[]; + + // Resources is a list of resources this rule applies to. + // For example: 'pods' means pods. + // '*' means all resources, but not subresources. + // 'pods/' means all subresources of pods. + // '*/scale' means all scale subresources. Allowed values are "Resource" / "Resource/Scale" / "Resource/Status". + resources: string[]; + + // Operations is a list of operations this rule applies to. + // The valid values are: "CREATE" / "UPDATE" / "DELETE" / "CONNECT". + operations: string[]; + + // Scope specifies the scope of this rule. Valid values are "Cluster" / "Namespace". + // Default is "Cluster". + scope?: string; +} + +interface MutatingWebhook { + // The name of the webhook configuration. + name: string; + + // ClientConfig defines how to communicate with the hook. + clientConfig: WebhookClientConfig; + + // Rules describes what operations on what resources/subresources the webhook cares about. + // The webhook cares about an operation if it matches _any_ Rule. + rules?: RuleWithOperations[]; + + // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions + // the webhook expects. API server will try to use first version in the list which it + // supports. If none of the versions specified in this list supported by API server, + // validation will fail for this object. + admissionReviewVersions?: string[]; + + // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored + // or the API call will fail depending on the failure policy. + timeoutSeconds?: number; + + // FailurePolicy specifies how unrecognized errors from the webhook are handled - allowed values are Ignore or Fail. + // Defaults to Fail. + failurePolicy?: string; + + // matchPolicy defines how the "rules" list is used to match incoming requests. Allowed values are "Exact" or "Equivalent". + // - Exact: match a request only if it exactly matches a specified rule. + // - Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. + // Defaults to "Equivalent". + matchPolicy?: string; + + // NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object + // matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. + // If both the object and the webhook configuration specify namespaceSelector, they must match. + namespaceSelector?: LabelSelector; + + // ObjectSelector decides whether to run the webhook based on if the object has matching labels. + // objectSelector and namespaceSelector are ANDed. An empty objectSelector matches all objects. + // A null objectSelector matches no objects. + objectSelector?: LabelSelector; + + // SideEffects states whether this webhookk should run when no mutating or validating webhook + // needs to run. This should be false when the webhook only applies to resources that have + // the sideEffects field set to None. Defaults to true. + sideEffects?: string; +} + +interface ServiceReference { + // `namespace` is the namespace of the service. + namespace: string; + + // `name` is the name of the service. + name: string; + + // `path` is an optional URL path which will be sent in any request to this service. + path?: string; + + // `port` is an optional service port which will be used when accessing the service. + port?: number | string; +} + +interface MutatingWebhookConfigurationSpec { + // Webhooks to be applied. + webhooks: MutatingWebhook[]; + + // CABundle is a PEM encoded CA bundle which will be used to validate webhook's server certificate. + // If unspecified, system trust roots on the apiserver are used. + caBundle?: string; + + // Determines the admission success of the MutatingWebhook. Allowed values are "Ignore"/"Fail"/"DryRun". + // If Ignore, any webhook failure or timeout will be ignored and the API request will be allowed to continue + // as if the webhook was not configured. You should use this option with caution and only for debugging + // purposes. If Fail, any webhook failure or timeout will cause the API request to fail. If DryRun, + // MutatingWebhook will be executed without really modifying the object. This is useful for testing webhook + // without really modifying objects. + // Defaults to "Fail". + failurePolicy?: string; + + // Indicates whether the webhook should be called on the request before or after the object mutation. + // Allowed values are "None"/"Before"/"After". Mutating admission webhook and validating admission + // webhook can be configured to perform the mutation changes before or after the resource mutation respectively. + // If no phases are specified, the webhook is assumed to support all phases. + sideEffects?: string; + + // ReinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission + // evaluation. Allowed values are "Never"/"IfNeeded". + reinvocationPolicy?: string; +} + +export class MutatingWebhookConfiguration extends KubeObject< + NamespaceScopedMetadata, + MutatingWebhookConfigurationStatus, + MutatingWebhookConfigurationSpec +> { + static kind = "MutatingWebhookConfiguration"; + static namespaced = true; + static apiBase = "/apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations"; + + getWebhooks(): MutatingWebhook[] { + return this.spec?.webhooks ?? []; + } + + getClientConfig(serviceName: string, serviceNamespace: string): WebhookClientConfig | undefined { + const webhooks = this.getWebhooks(); + + for (const webhook of webhooks) { + if (webhook.clientConfig.service?.name === serviceName && webhook.clientConfig.service?.namespace === serviceNamespace) { + return webhook.clientConfig; + } + } + + return undefined; + } + + getCaBundle(): string | undefined { + return this.spec?.caBundle; + } + + getFailurePolicy(): string | undefined { + return this.spec?.failurePolicy; + } + + getSideEffects(): string | undefined { + return this.spec?.sideEffects; + } + + getReinvocationPolicy(): string | undefined { + return this.spec?.reinvocationPolicy; + } +} From 704a642276e1160ff8f84c98a438c765da7b16d6 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 11:39:29 +0300 Subject: [PATCH 02/24] Add mutatingWebhookConfigurationApiInjectable Signed-off-by: Alex Andreev --- ...ng-webhook-configuration-api.injectable.ts | 27 +++++++++++++++++++ .../mutating-webhook-configuration.api.ts | 11 ++++++++ 2 files changed, 38 insertions(+) create mode 100644 packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration-api.injectable.ts diff --git a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration-api.injectable.ts b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration-api.injectable.ts new file mode 100644 index 0000000000..c307f9ddf1 --- /dev/null +++ b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration-api.injectable.ts @@ -0,0 +1,27 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import assert from "assert"; +import { storesAndApisCanBeCreatedInjectionToken } from "../stores-apis-can-be-created.token"; +import { kubeApiInjectionToken } from "../kube-api/kube-api-injection-token"; +import loggerInjectable from "../../logger.injectable"; +import maybeKubeApiInjectable from "../maybe-kube-api.injectable"; +import { MutatingWebhookConfigurationApi } from "./mutating-webhook-configuration.api"; + +const mutatingWebhookConfigurationApiInjectable = getInjectable({ + id: "mutating-webhook-configuration", + instantiate: (di) => { + assert(di.inject(storesAndApisCanBeCreatedInjectionToken), "mutatingWebhookApi is only available in certain environments"); + + return new MutatingWebhookConfigurationApi({ + logger: di.inject(loggerInjectable), + maybeKubeApi: di.inject(maybeKubeApiInjectable), + }); + }, + + injectionToken: kubeApiInjectionToken, +}); + +export default mutatingWebhookConfigurationApiInjectable; diff --git a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts index 18bb5af431..a021e9b8aa 100644 --- a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts +++ b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts @@ -4,6 +4,8 @@ */ import type { LabelSelector, NamespaceScopedMetadata } from "../kube-object"; import { KubeObject } from "../kube-object"; +import type { DerivedKubeApiOptions, KubeApiDependencies } from "../kube-api"; +import { KubeApi } from "../kube-api"; interface MutatingWebhookConfigurationStatus { // The latest generation observed by the webhook. @@ -238,3 +240,12 @@ export class MutatingWebhookConfiguration extends KubeObject< return this.spec?.reinvocationPolicy; } } + +export class MutatingWebhookConfigurationApi extends KubeApi { + constructor(deps: KubeApiDependencies, opts?: DerivedKubeApiOptions) { + super(deps, { + ...opts ?? {}, + objectConstructor: MutatingWebhookConfiguration, + }); + } +} From 34f7b2f6b15ad747db9db8987852bf1940e2a078 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 12:04:31 +0300 Subject: [PATCH 03/24] Adding routes and navigate-to injectables Signed-off-by: Alex Andreev --- ...webhook-configurations-route.injectable.ts | 26 +++++++++++++++++++ ...ating-webhook-configurations.injectable.ts | 20 ++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 packages/core/src/common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable.ts create mode 100644 packages/core/src/common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable.ts diff --git a/packages/core/src/common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable.ts new file mode 100644 index 0000000000..5812f1258d --- /dev/null +++ b/packages/core/src/common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { + shouldShowResourceInjectionToken, +} from "../../../../../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token"; +import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token"; +import { getInjectable } from "@ogre-tools/injectable"; + +const mutatingWebhookConfigurationsRouteInjectable = getInjectable({ + id: "mutatingwebhookconfigurations", + + instantiate: (di) => ({ + path: "/mutatingwebhookconfigurations", + clusterFrame: true, + isEnabled: di.inject(shouldShowResourceInjectionToken, { + apiName: "mutatingwebhookconfigurations", + group: "admissionregistration.k8s.io", + }), + }), + + injectionToken: frontEndRouteInjectionToken, +}); + +export default mutatingWebhookConfigurationsRouteInjectable; diff --git a/packages/core/src/common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable.ts b/packages/core/src/common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable.ts new file mode 100644 index 0000000000..ffb0e4b3d0 --- /dev/null +++ b/packages/core/src/common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import mutatingWebhookConfigurationsRouteInjectable from "./mutating-webhook-configurations-route.injectable"; +import { navigateToRouteInjectionToken } from "../../../../navigate-to-route-injection-token"; + +const navigateToMutatingWebhookConfigurationsInjectable = getInjectable({ + id: "navigate-to-mutating-webhook-configurations", + + instantiate: (di) => { + const navigateToRoute = di.inject(navigateToRouteInjectionToken); + const route = di.inject(mutatingWebhookConfigurationsRouteInjectable); + + return () => navigateToRoute(route); + }, +}); + +export default navigateToMutatingWebhookConfigurationsInjectable; From 1d96760a3a7a942b7bcdf2bd8bd77c1fdce9d5a5 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 12:12:31 +0300 Subject: [PATCH 04/24] Adding mutating-webhook-configuration.api export to endpoints index.ts file Signed-off-by: Alex Andreev --- packages/core/src/common/k8s-api/endpoints/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/common/k8s-api/endpoints/index.ts b/packages/core/src/common/k8s-api/endpoints/index.ts index 8fb6cbdabd..5a83bef417 100644 --- a/packages/core/src/common/k8s-api/endpoints/index.ts +++ b/packages/core/src/common/k8s-api/endpoints/index.ts @@ -22,6 +22,7 @@ export * from "./ingress-class.api"; export * from "./job.api"; export * from "./lease.api"; export * from "./limit-range.api"; +export * from "./mutating-webhook-configuration.api"; export * from "./namespace.api"; export * from "./network-policy.api"; export * from "./node.api"; From 18ea6c2a4fd1bb4378b28f51c188630a8d1cbefe Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 13:12:50 +0300 Subject: [PATCH 05/24] Adding webhook list and store Signed-off-by: Alex Andreev --- ...-webhook-configuration-store.injectable.ts | 26 ++++++ .../mutating-webhook-configuration-store.ts | 22 +++++ .../mutating-webhook-configurations.tsx | 86 +++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configuration-store.injectable.ts create mode 100644 packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configuration-store.ts create mode 100644 packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configuration-store.injectable.ts b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configuration-store.injectable.ts new file mode 100644 index 0000000000..6522360bd0 --- /dev/null +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configuration-store.injectable.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { kubeObjectStoreInjectionToken } from "../../../common/k8s-api/api-manager/kube-object-store-token"; +import { MutatingWebhookConfigurationStore } from "./mutating-webhook-configuration-store"; +import clusterFrameContextForNamespacedResourcesInjectable from "../../cluster-frame-context/for-namespaced-resources.injectable"; +import loggerInjectable from "../../../common/logger.injectable"; +import mutatingWebhookConfigurationApiInjectable + from "../../../common/k8s-api/endpoints/mutating-webhook-configuration-api.injectable"; + +const mutatingWebhookConfigurationStoreInjectable = getInjectable({ + id: "mutating-webhook-configuration-store", + instantiate: (di) => { + const api = di.inject(mutatingWebhookConfigurationApiInjectable); + + return new MutatingWebhookConfigurationStore({ + context: di.inject(clusterFrameContextForNamespacedResourcesInjectable), + logger: di.inject(loggerInjectable), + }, api); + }, + injectionToken: kubeObjectStoreInjectionToken, +}); + +export default mutatingWebhookConfigurationStoreInjectable; diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configuration-store.ts b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configuration-store.ts new file mode 100644 index 0000000000..fbd30b10e3 --- /dev/null +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configuration-store.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { + MutatingWebhookConfiguration, + MutatingWebhookConfigurationApi, +} from "../../../common/k8s-api/endpoints"; +import type { + KubeObjectStoreDependencies, + KubeObjectStoreOptions, +} from "../../../common/k8s-api/kube-object.store"; +import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store"; + +export interface MutatingWebhookConfigurationStoreDependencies extends KubeObjectStoreDependencies { +} + +export class MutatingWebhookConfigurationStore extends KubeObjectStore { + constructor(protected readonly dependencies: MutatingWebhookConfigurationStoreDependencies, api: MutatingWebhookConfigurationApi, opts?: KubeObjectStoreOptions) { + super(dependencies, api, opts); + } +} diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx new file mode 100644 index 0000000000..824743c8d0 --- /dev/null +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx @@ -0,0 +1,86 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import React from "react"; +import { observer } from "mobx-react"; +import { KubeObjectListLayout } from "../kube-object-list-layout"; +import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout"; +import type { MutatingWebhookConfigurationStore } from "./mutating-webhook-configuration-store"; +import { withInjectables } from "@ogre-tools/injectable-react"; +import mutatingWebhookConfigurationsStoreInjectable from "./mutating-webhook-configuration-store.injectable"; +import { NamespaceSelectBadge } from "../+namespaces/namespace-select-badge"; +import { Badge } from "../badge"; +import { KubeObjectAge } from "../kube-object/age"; + +enum columnId { + name = "name", + namespace = "namespace", + webhooks = "webhooks", + selector = "selector", + age = "age", +} + +interface Dependencies { + store: MutatingWebhookConfigurationStore; +} + +const NonInjectedMutatingWebhookConfigurations = observer((props: Dependencies) => { + return ( + + item.getName(), + [columnId.namespace]: item => item.getNs(), + [columnId.selector]: item => item.getLabels(), + [columnId.webhooks]: item => item.getWebhooks().length, + [columnId.age]: item => -item.getCreationTimestamp(), + }} + searchFilters={[ + item => item.getSearchFields(), + item => item.getLabels(), + ]} + renderHeaderTitle="Mutating Webhook Configurations" + renderTableHeader={[ + { title: "Name", className: "name", sortBy: columnId.name, id: columnId.name }, + { + title: "Namespace", + className: "namespace", + sortBy: columnId.namespace, + id: columnId.namespace, + }, + { + title: "Labels", + sortBy: columnId.selector, + id: columnId.selector, + }, + { + title: "Webhooks", + sortBy: columnId.webhooks, + id: columnId.webhooks, + }, + { title: "Age", className: "age", sortBy: columnId.age, id: columnId.age }, + ]} + renderTableContents={item => [ + item.getName(), + , + item.getLabels().map(label => ()), + item.getWebhooks().length, + , + ]} + /> + + ); +}); + +export const MutatingWebhookConfigurations = withInjectables(NonInjectedMutatingWebhookConfigurations, { + getProps: (di, props) => ({ + ...props, + store: di.inject(mutatingWebhookConfigurationsStoreInjectable), + }), +}); From c6b1306d9a001d8fd283a600e739b3755200c93a Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 13:25:13 +0300 Subject: [PATCH 06/24] Adding webhook sidebar items injectable Signed-off-by: Alex Andreev --- ...configurations-sidebar-items.injectable.ts | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-sidebar-items.injectable.ts diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-sidebar-items.injectable.ts b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-sidebar-items.injectable.ts new file mode 100644 index 0000000000..8fde832ca7 --- /dev/null +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-sidebar-items.injectable.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { computed } from "mobx"; +import { workloadsSidebarItemId } from "../+workloads/workloads-sidebar-items.injectable"; +import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; +import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; +import mutatingWebhookConfigurationsRouteInjectable + from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable"; +import navigateToMutatingWebhookConfigurationsInjectable + from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable"; + +const mutatingWebhookConfigurationsSidebarItemsInjectable = getInjectable({ + id: "mutating-webhook-configurations-sidebar-items", + + instantiate: (di) => { + const route = di.inject(mutatingWebhookConfigurationsRouteInjectable); + const navigateToPage = di.inject(navigateToMutatingWebhookConfigurationsInjectable); + const routeIsActive = di.inject(routeIsActiveInjectable, route); + + return computed(() => [ + { + id: "mutating-webhook-configurations", + parentId: workloadsSidebarItemId, + title: "Mutating Webhook Configs", + onClick: navigateToPage, + isActive: routeIsActive, + isVisible: route.isEnabled, + orderNumber: 100, + }, + ]); + }, + + injectionToken: sidebarItemsInjectionToken, +}); + +export default mutatingWebhookConfigurationsSidebarItemsInjectable; From 831c1f1d1e789c45be322f09798fce8231fd66c5 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 14:30:32 +0300 Subject: [PATCH 07/24] Webhook Config initial details page Signed-off-by: Alex Andreev --- ...utating-webhook-configurations-details.tsx | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx new file mode 100644 index 0000000000..8ec1511405 --- /dev/null +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx @@ -0,0 +1,30 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import React from "react"; +import { observer } from "mobx-react"; +import { DrawerItem, DrawerTitle } from "../drawer"; +import type { KubeObjectDetailsProps } from "../kube-object-details"; +import type { MutatingWebhookConfiguration } from "../../../common/k8s-api/endpoints"; + +export interface MutatingWebhookDetailsProps extends KubeObjectDetailsProps { +} + +@observer +export class MutatingWebhookDetails extends React.Component { + render() { + const { object: webhookConfig } = this.props; + + return ( +
+ + {webhookConfig.apiVersion} + + + Webhooks +
+ ); + } +} From 66252f068d9dc5cd7e152749b81405a269c03259 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 16:05:22 +0300 Subject: [PATCH 08/24] Add more fields to details panel Signed-off-by: Alex Andreev --- .../mutating-webhook-configuration.api.ts | 4 ++ ...utating-webhook-configurations-details.tsx | 40 ++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts index a021e9b8aa..6434a31cc0 100644 --- a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts +++ b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts @@ -155,6 +155,10 @@ interface MutatingWebhook { // needs to run. This should be false when the webhook only applies to resources that have // the sideEffects field set to None. Defaults to true. sideEffects?: string; + + // reinvocationPolicy indicates whether this webhook should be called multiple times as part of a + // single admission evaluation. Allowed values are "Never" and "IfNeeded" + reinvocationPolicy?: "Never" | "IfNeeded"; } interface ServiceReference { diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx index 8ec1511405..0d251eb169 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx @@ -22,8 +22,46 @@ export class MutatingWebhookDetails extends React.Component {webhookConfig.apiVersion} - Webhooks + {webhookConfig.getWebhooks()?.map((webhook) => ( + + + {webhook.name} + + + {webhook.clientConfig?.service?.name && ( +
+
+ Name: + {webhook.clientConfig.service.name} +
+
+ Namespace: + {webhook.clientConfig.service.namespace} +
+
+ )} +
+ + {webhook.matchPolicy} + + + {webhook.failurePolicy} + + + {webhook.admissionReviewVersions?.join(", ")} + + + {webhook.reinvocationPolicy} + + + {webhook.sideEffects} + + + {webhook.timeoutSeconds} + +
+ ))} ); } From afd7413849b78a3700ee74f86357f918aa9ecacc Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 16:09:16 +0300 Subject: [PATCH 09/24] Add mutatingWebhookConfigurationsRouteComponentInjectable Signed-off-by: Alex Andreev --- ...nfigurations-route-component.injectable.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-route-component.injectable.ts diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-route-component.injectable.ts b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-route-component.injectable.ts new file mode 100644 index 0000000000..9f16b45cc6 --- /dev/null +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-route-component.injectable.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { + routeSpecificComponentInjectionToken, +} from "../../routes/route-specific-component-injection-token"; +import mutatingWebhookConfigurationsRouteInjectable + from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable"; +import { MutatingWebhookConfigurations } from "./mutating-webhook-configurations"; + +const mutatingWebhookConfigurationsRouteComponentInjectable = getInjectable({ + id: "mutating-webhook-configuration-route-component", + + instantiate: (di) => ({ + route: di.inject(mutatingWebhookConfigurationsRouteInjectable), + Component: MutatingWebhookConfigurations, + }), + + injectionToken: routeSpecificComponentInjectionToken, +}); + +export default mutatingWebhookConfigurationsRouteComponentInjectable; From 849e2b6397528f0255fe5a0672060788f42cab1f Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 16:10:41 +0300 Subject: [PATCH 10/24] Add index.ts for exporting list and details Signed-off-by: Alex Andreev --- .../+config-mutating-webhook-configurations/index.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/core/src/renderer/components/+config-mutating-webhook-configurations/index.ts diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/index.ts b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/index.ts new file mode 100644 index 0000000000..e80e35d4b5 --- /dev/null +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +export * from "./mutating-webhook-configurations"; +export * from "./mutating-webhook-configurations-details"; From 07d5ddfda8af775876d8c12520bece640489303f Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 16:14:22 +0300 Subject: [PATCH 11/24] Add detail item injectable Signed-off-by: Alex Andreev --- ...-configurations-details-item.injectable.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 packages/core/src/renderer/components/kube-object-details/kube-object-detail-items/implementations/mutating-webhook-configurations-details-item.injectable.ts diff --git a/packages/core/src/renderer/components/kube-object-details/kube-object-detail-items/implementations/mutating-webhook-configurations-details-item.injectable.ts b/packages/core/src/renderer/components/kube-object-details/kube-object-detail-items/implementations/mutating-webhook-configurations-details-item.injectable.ts new file mode 100644 index 0000000000..94b5fdac42 --- /dev/null +++ b/packages/core/src/renderer/components/kube-object-details/kube-object-detail-items/implementations/mutating-webhook-configurations-details-item.injectable.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token"; +import { computed } from "mobx"; +import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version"; +import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable"; +import { MutatingWebhookDetails } from "../../../+config-mutating-webhook-configurations"; + +const mutatingWebhookConfigurationDetailItemInjectable = getInjectable({ + id: "mutating-webhook-configuration-detail-item", + + instantiate(di) { + const kubeObject = di.inject(currentKubeObjectInDetailsInjectable); + + return { + Component: MutatingWebhookDetails, + enabled: computed(() => isMutatingWebhookConfiguration(kubeObject.value.get()?.object)), + orderNumber: 10, + }; + }, + + injectionToken: kubeObjectDetailItemInjectionToken, +}); + +export const isMutatingWebhookConfiguration = kubeObjectMatchesToKindAndApiVersion( + "MutatingWebhookConfiguration", + ["v1", "admissionregistration.k8s.io/v1beta1", "admissionregistration.k8s.io/v1"], +); + +export default mutatingWebhookConfigurationDetailItemInjectable; From 78f9c2ec07ba61304eb51b62b2d2a24b57217be1 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 16:19:21 +0300 Subject: [PATCH 12/24] Add rbac rules Signed-off-by: Alex Andreev --- packages/core/src/common/rbac.ts | 7 ++++++- packages/core/src/renderer/utils/rbac.ts | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/core/src/common/rbac.ts b/packages/core/src/common/rbac.ts index 03b4fd1de9..b1a7ceb550 100644 --- a/packages/core/src/common/rbac.ts +++ b/packages/core/src/common/rbac.ts @@ -9,7 +9,7 @@ export type KubeResource = "pods" | "daemonsets" | "deployments" | "statefulsets" | "replicasets" | "replicationcontrollers" | "jobs" | "cronjobs" | "endpoints" | "customresourcedefinitions" | "horizontalpodautoscalers" | "verticalpodautoscalers" | "podsecuritypolicies" | "poddisruptionbudgets" | "priorityclasses" | "runtimeclasses" | - "roles" | "clusterroles" | "rolebindings" | "clusterrolebindings" | "serviceaccounts"; + "roles" | "clusterroles" | "rolebindings" | "clusterrolebindings" | "serviceaccounts" | "mutatingwebhookconfigurations"; export interface KubeApiResource { kind: string; @@ -116,6 +116,11 @@ export const apiResourceRecord: Record = { group: "", namespaced: true, }, + mutatingwebhookconfigurations: { + kind: "MutatingWebhookConfiguration", + group: "admissionregistration.k8s.io/v1", + namespaced: true, + }, networkpolicies: { kind: "NetworkPolicy", group: "networking.k8s.io", diff --git a/packages/core/src/renderer/utils/rbac.ts b/packages/core/src/renderer/utils/rbac.ts index b4aa9a6a81..488a8479bf 100644 --- a/packages/core/src/renderer/utils/rbac.ts +++ b/packages/core/src/renderer/utils/rbac.ts @@ -44,6 +44,7 @@ export const ResourceNames: Record = { "clusterroles": "Cluster Roles", "serviceaccounts": "Service Accounts", "verticalpodautoscalers": "Vertical Pod Autoscalers", + "mutatingwebhookconfigurations": "Mutating Webhook Configurations", }; export const ResourceKindMap = object.fromEntries( From 9c2884a671883b08da466174c55e543c3a9b5088 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Thu, 6 Apr 2023 16:35:36 +0300 Subject: [PATCH 13/24] Change sidebar link parent to Config item Signed-off-by: Alex Andreev --- ...utating-webhook-configurations-sidebar-items.injectable.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-sidebar-items.injectable.ts b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-sidebar-items.injectable.ts index 8fde832ca7..5104c10c92 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-sidebar-items.injectable.ts +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-sidebar-items.injectable.ts @@ -4,13 +4,13 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { computed } from "mobx"; -import { workloadsSidebarItemId } from "../+workloads/workloads-sidebar-items.injectable"; import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; import mutatingWebhookConfigurationsRouteInjectable from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/mutating-webhook-configurations-route.injectable"; import navigateToMutatingWebhookConfigurationsInjectable from "../../../common/front-end-routing/routes/cluster/config/mutating-webhook-configurations/navigate-to-mutating-webhook-configurations.injectable"; +import { configSidebarItemId } from "../+config/config-sidebar-items.injectable"; const mutatingWebhookConfigurationsSidebarItemsInjectable = getInjectable({ id: "mutating-webhook-configurations-sidebar-items", @@ -23,7 +23,7 @@ const mutatingWebhookConfigurationsSidebarItemsInjectable = getInjectable({ return computed(() => [ { id: "mutating-webhook-configurations", - parentId: workloadsSidebarItemId, + parentId: configSidebarItemId, title: "Mutating Webhook Configs", onClick: navigateToPage, isActive: routeIsActive, From 02e24735b850771412a66257f087c7fc3ba77e44 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 10:51:58 +0300 Subject: [PATCH 14/24] Fix webhook field scoping Signed-off-by: Alex Andreev --- .../mutating-webhook-configuration.api.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts index 6434a31cc0..6d33374ba4 100644 --- a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts +++ b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts @@ -2,10 +2,11 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { LabelSelector, NamespaceScopedMetadata } from "../kube-object"; +import type { LabelSelector, NamespaceScopedMetadata, KubeObjectMetadata, KubeObjectScope } from "../kube-object"; import { KubeObject } from "../kube-object"; import type { DerivedKubeApiOptions, KubeApiDependencies } from "../kube-api"; import { KubeApi } from "../kube-api"; +import type { KubeJsonApiData } from "../kube-json-api"; interface MutatingWebhookConfigurationStatus { // The latest generation observed by the webhook. @@ -203,6 +204,10 @@ interface MutatingWebhookConfigurationSpec { reinvocationPolicy?: string; } +interface MutatingWebhookConfigurationData extends KubeJsonApiData, MutatingWebhookConfigurationStatus, MutatingWebhookConfigurationSpec> { + webhooks?: MutatingWebhook[]; +} + export class MutatingWebhookConfiguration extends KubeObject< NamespaceScopedMetadata, MutatingWebhookConfigurationStatus, @@ -212,8 +217,15 @@ export class MutatingWebhookConfiguration extends KubeObject< static namespaced = true; static apiBase = "/apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations"; + webhooks?: MutatingWebhook[]; + + constructor({ webhooks, ...rest }: MutatingWebhookConfigurationData) { + super(rest); + this.webhooks = webhooks; + } + getWebhooks(): MutatingWebhook[] { - return this.spec?.webhooks ?? []; + return this.webhooks ?? []; } getClientConfig(serviceName: string, serviceNamespace: string): WebhookClientConfig | undefined { From a308320dd65593686c83667f66bd98f6eda5ae75 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 10:56:02 +0300 Subject: [PATCH 15/24] Remove namespace and labels columns Signed-off-by: Alex Andreev --- .../mutating-webhook-configurations.tsx | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx index 824743c8d0..d51ec14d4e 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx @@ -10,15 +10,11 @@ import { SiblingsInTabLayout } from "../layout/siblings-in-tab-layout"; import type { MutatingWebhookConfigurationStore } from "./mutating-webhook-configuration-store"; import { withInjectables } from "@ogre-tools/injectable-react"; import mutatingWebhookConfigurationsStoreInjectable from "./mutating-webhook-configuration-store.injectable"; -import { NamespaceSelectBadge } from "../+namespaces/namespace-select-badge"; -import { Badge } from "../badge"; import { KubeObjectAge } from "../kube-object/age"; enum columnId { name = "name", - namespace = "namespace", webhooks = "webhooks", - selector = "selector", age = "age", } @@ -36,8 +32,6 @@ const NonInjectedMutatingWebhookConfigurations = observer((props: Dependencies) store={props.store} sortingCallbacks={{ [columnId.name]: item => item.getName(), - [columnId.namespace]: item => item.getNs(), - [columnId.selector]: item => item.getLabels(), [columnId.webhooks]: item => item.getWebhooks().length, [columnId.age]: item => -item.getCreationTimestamp(), }} @@ -48,17 +42,6 @@ const NonInjectedMutatingWebhookConfigurations = observer((props: Dependencies) renderHeaderTitle="Mutating Webhook Configurations" renderTableHeader={[ { title: "Name", className: "name", sortBy: columnId.name, id: columnId.name }, - { - title: "Namespace", - className: "namespace", - sortBy: columnId.namespace, - id: columnId.namespace, - }, - { - title: "Labels", - sortBy: columnId.selector, - id: columnId.selector, - }, { title: "Webhooks", sortBy: columnId.webhooks, @@ -68,8 +51,6 @@ const NonInjectedMutatingWebhookConfigurations = observer((props: Dependencies) ]} renderTableContents={item => [ item.getName(), - , - item.getLabels().map(label => ()), item.getWebhooks().length, , ]} From f00c6129d71006deb5267a86caaaeb24bdcb6338 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 12:02:21 +0300 Subject: [PATCH 16/24] Add object selector details item Signed-off-by: Alex Andreev --- ...utating-webhook-configurations-details.tsx | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx index 0d251eb169..487bc78962 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx @@ -8,6 +8,7 @@ import { observer } from "mobx-react"; import { DrawerItem, DrawerTitle } from "../drawer"; import type { KubeObjectDetailsProps } from "../kube-object-details"; import type { MutatingWebhookConfiguration } from "../../../common/k8s-api/endpoints"; +import { Badge } from "../badge"; export interface MutatingWebhookDetailsProps extends KubeObjectDetailsProps { } @@ -33,10 +34,12 @@ export class MutatingWebhookDetails extends React.Component
Name: + {" "} {webhook.clientConfig.service.name}
Namespace: + {" "} {webhook.clientConfig.service.namespace}
@@ -60,6 +63,39 @@ export class MutatingWebhookDetails extends React.Component {webhook.timeoutSeconds} + + {webhook.objectSelector && ( +
+
Match Expressions:
+ {webhook.objectSelector.matchExpressions?.map((expression, index) => ( +
+
+ Key: + {expression.key} +
+
+ Operator: + {expression.operator} +
+
+ Values: + {expression.values?.join(", ")} +
+
+ ))} + {webhook.objectSelector.matchLabels && ( +
+
Match Labels:
+
+ {Object.entries(webhook.objectSelector.matchLabels).map(([key, value], index) => ( + + ))} +
+
+ )} +
+ )} +
))} From 86eda1d751d4c06776537c62d6ec5d4d52615666 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 12:04:44 +0300 Subject: [PATCH 17/24] Set mutatingwebhookconfigs as cluster-scoped Signed-off-by: Alex Andreev --- .../k8s-api/endpoints/mutating-webhook-configuration.api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts index 6d33374ba4..29fbc08865 100644 --- a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts +++ b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts @@ -214,7 +214,7 @@ export class MutatingWebhookConfiguration extends KubeObject< MutatingWebhookConfigurationSpec > { static kind = "MutatingWebhookConfiguration"; - static namespaced = true; + static namespaced = false; static apiBase = "/apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations"; webhooks?: MutatingWebhook[]; From a3a16c42c986aea24a8a666fc9d2dfaf6bf870ef Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 13:27:18 +0300 Subject: [PATCH 18/24] Add namespace selector Signed-off-by: Alex Andreev --- ...utating-webhook-configurations-details.tsx | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx index 487bc78962..a613d19aac 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx @@ -24,6 +24,9 @@ export class MutatingWebhookDetails extends React.Component Webhooks + {webhookConfig.getWebhooks()?.length == 0 && ( +
No webhooks set
+ )} {webhookConfig.getWebhooks()?.map((webhook) => ( @@ -63,6 +66,42 @@ export class MutatingWebhookDetails extends React.Component {webhook.timeoutSeconds} + + {webhook.namespaceSelector && ( +
+
Match Expressions:
+ {webhook.namespaceSelector.matchExpressions?.map((expression, index) => ( +
+
+ Key: + {" "} + {expression.key} +
+
+ Operator: + {" "} + {expression.operator} +
+
+ Values: + {" "} + {expression.values?.join(", ")} +
+
+ ))} + {webhook.namespaceSelector.matchLabels && ( +
+
Match Labels:
+
+ {Object.entries(webhook.namespaceSelector.matchLabels).map(([key, value], index) => ( + + ))} +
+
+ )} +
+ )} +
{webhook.objectSelector && (
From dbd480212d8eb2f908b99683a839c0643edd84ba Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 13:30:07 +0300 Subject: [PATCH 19/24] Add Rules details item Signed-off-by: Alex Andreev --- ...utating-webhook-configurations-details.tsx | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx index a613d19aac..d3334d6147 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx @@ -110,15 +110,18 @@ export class MutatingWebhookDetails extends React.Component
Key: - {expression.key} + {" "} + {expression.key}
Operator: - {expression.operator} + {" "} + {expression.operator}
Values: - {expression.values?.join(", ")} + {" "} + {expression.values?.join(", ")}
))} @@ -135,6 +138,41 @@ export class MutatingWebhookDetails extends React.Component )}
+ + {webhook.rules?.map((rule, index) => ( +
+
+ API Groups: + {" "} + {rule.apiGroups.join(", ")} +
+
+ API Versions: + {" "} + {rule.apiVersions?.join(", ")} +
+
+ Operations: + {" "} + {rule.operations.join(", ")} +
+ {rule.resources && ( +
+ Resources: + {" "} + {rule.resources.join(", ")} +
+ )} + {rule.scope && ( +
+ Scope: + {" "} + {rule.scope} +
+ )} +
+ ))} +
))} From 61602d9628529ef4885570360b9df416fa1a86e1 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 13:35:17 +0300 Subject: [PATCH 20/24] Customize search input placeholder Signed-off-by: Alex Andreev --- .../mutating-webhook-configurations.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx index d51ec14d4e..62ac617a5f 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx @@ -27,6 +27,12 @@ const NonInjectedMutatingWebhookConfigurations = observer((props: Dependencies) ({ + searchProps: { + ...searchProps, + placeholder: "Search...", + }, + })} tableId="config_mutating_webhook_configurations" className={"MutatingWebhookConfigurations"} store={props.store} From 6564f89db8fe98e1415508d6ba7406ffd3c302e4 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 13:35:46 +0300 Subject: [PATCH 21/24] Removing tags Signed-off-by: Alex Andreev --- .../mutating-webhook-configurations-details.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx index d3334d6147..2560515c5e 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx @@ -75,17 +75,17 @@ export class MutatingWebhookDetails extends React.Component Key: {" "} - {expression.key} + {expression.key}
Operator: {" "} - {expression.operator} + {expression.operator}
Values: {" "} - {expression.values?.join(", ")} + {expression.values?.join(", ")}
))} @@ -111,17 +111,17 @@ export class MutatingWebhookDetails extends React.Component Key: {" "} - {expression.key} + {expression.key}
Operator: {" "} - {expression.operator} + {expression.operator}
Values: {" "} - {expression.values?.join(", ")} + {expression.values?.join(", ")}
))} From 88f832012d544ab72aedd2ad479959d79369d7b4 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 13:56:52 +0300 Subject: [PATCH 22/24] Add styles for details panel Signed-off-by: Alex Andreev --- .../mutating-webhook-configs-details.module.css | 9 +++++++++ .../mutating-webhook-configurations-details.tsx | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configs-details.module.css diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configs-details.module.css b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configs-details.module.css new file mode 100644 index 0000000000..f4090ece62 --- /dev/null +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configs-details.module.css @@ -0,0 +1,9 @@ +.matchLabels { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; +} + +.lastItem + .firstItem { + margin-top: 1rem; +} diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx index 2560515c5e..d40a00ad81 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations-details.tsx @@ -2,6 +2,7 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ +import styles from "./mutating-webhook-configs-details.module.css"; import React from "react"; import { observer } from "mobx-react"; @@ -29,7 +30,7 @@ export class MutatingWebhookDetails extends React.Component ( - + {webhook.name} @@ -92,7 +93,7 @@ export class MutatingWebhookDetails extends React.Component
Match Labels:
-
+
{Object.entries(webhook.namespaceSelector.matchLabels).map(([key, value], index) => ( ))} @@ -128,7 +129,7 @@ export class MutatingWebhookDetails extends React.Component
Match Labels:
-
+
{Object.entries(webhook.objectSelector.matchLabels).map(([key, value], index) => ( ))} @@ -138,7 +139,7 @@ export class MutatingWebhookDetails extends React.Component )} - + {webhook.rules?.map((rule, index) => (
From 03632626ceb4c5e2145c60f7e51833d86f913426 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 13:57:15 +0300 Subject: [PATCH 23/24] Clean up mutating webhook configs api Signed-off-by: Alex Andreev --- .../mutating-webhook-configuration.api.ts | 118 +----------------- 1 file changed, 3 insertions(+), 115 deletions(-) diff --git a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts index 29fbc08865..bdfde072bf 100644 --- a/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts +++ b/packages/core/src/common/k8s-api/endpoints/mutating-webhook-configuration.api.ts @@ -8,74 +8,6 @@ import type { DerivedKubeApiOptions, KubeApiDependencies } from "../kube-api"; import { KubeApi } from "../kube-api"; import type { KubeJsonApiData } from "../kube-json-api"; -interface MutatingWebhookConfigurationStatus { - // The latest generation observed by the webhook. - observedGeneration?: number; - - // Conditions for the MutatingWebhookConfiguration. - conditions?: { - // Type of MutatingWebhookConfiguration condition. - type: string; - - // Status of the condition, one of True, False, Unknown. - status: string; - - // Reason for the current status of the condition. - reason?: string; - - // Message describing the current status of the condition. - message?: string; - }[]; - - // Webhooks that failed to be registered. - failedWebhooks?: { - // Name of the failed webhook. - name: string; - - // Failure type of the webhook. - failureType: string; - - // Reason for the failure. - reason?: string; - - // Message describing the failure. - message?: string; - }[]; - - // Webhooks that are not registered yet. - webhookConfigurations?: { - // Name of the webhook configuration. - name: string; - - // Namespace of the webhook configuration. - namespace: string; - - // API version of the webhook configuration. - apiVersion: string; - - // Kind of the webhook configuration. - kind: string; - - // Object reference to the webhook configuration. - objectReference?: { - // API version of the object reference. - apiVersion?: string; - - // Kind of the object reference. - kind: string; - - // Name of the object reference. - name: string; - - // Namespace of the object reference. - namespace?: string; - - // UID of the object reference. - uid?: string; - }; - }[]; -} - interface WebhookClientConfig { // `url` gives the location of the webhook url?: string; @@ -176,42 +108,14 @@ interface ServiceReference { port?: number | string; } -interface MutatingWebhookConfigurationSpec { - // Webhooks to be applied. - webhooks: MutatingWebhook[]; - - // CABundle is a PEM encoded CA bundle which will be used to validate webhook's server certificate. - // If unspecified, system trust roots on the apiserver are used. - caBundle?: string; - - // Determines the admission success of the MutatingWebhook. Allowed values are "Ignore"/"Fail"/"DryRun". - // If Ignore, any webhook failure or timeout will be ignored and the API request will be allowed to continue - // as if the webhook was not configured. You should use this option with caution and only for debugging - // purposes. If Fail, any webhook failure or timeout will cause the API request to fail. If DryRun, - // MutatingWebhook will be executed without really modifying the object. This is useful for testing webhook - // without really modifying objects. - // Defaults to "Fail". - failurePolicy?: string; - - // Indicates whether the webhook should be called on the request before or after the object mutation. - // Allowed values are "None"/"Before"/"After". Mutating admission webhook and validating admission - // webhook can be configured to perform the mutation changes before or after the resource mutation respectively. - // If no phases are specified, the webhook is assumed to support all phases. - sideEffects?: string; - - // ReinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission - // evaluation. Allowed values are "Never"/"IfNeeded". - reinvocationPolicy?: string; -} - -interface MutatingWebhookConfigurationData extends KubeJsonApiData, MutatingWebhookConfigurationStatus, MutatingWebhookConfigurationSpec> { +interface MutatingWebhookConfigurationData extends KubeJsonApiData, void, void> { webhooks?: MutatingWebhook[]; } export class MutatingWebhookConfiguration extends KubeObject< NamespaceScopedMetadata, - MutatingWebhookConfigurationStatus, - MutatingWebhookConfigurationSpec + void, + void > { static kind = "MutatingWebhookConfiguration"; static namespaced = false; @@ -239,22 +143,6 @@ export class MutatingWebhookConfiguration extends KubeObject< return undefined; } - - getCaBundle(): string | undefined { - return this.spec?.caBundle; - } - - getFailurePolicy(): string | undefined { - return this.spec?.failurePolicy; - } - - getSideEffects(): string | undefined { - return this.spec?.sideEffects; - } - - getReinvocationPolicy(): string | undefined { - return this.spec?.reinvocationPolicy; - } } export class MutatingWebhookConfigurationApi extends KubeApi { From 2ada8304182be8ce53ff0678c4634a3093547394 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 7 Apr 2023 13:57:28 +0300 Subject: [PATCH 24/24] Fix table header Signed-off-by: Alex Andreev --- .../mutating-webhook-configurations.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx index 62ac617a5f..5d3a4b51a3 100644 --- a/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx +++ b/packages/core/src/renderer/components/+config-mutating-webhook-configurations/mutating-webhook-configurations.tsx @@ -27,7 +27,8 @@ const NonInjectedMutatingWebhookConfigurations = observer((props: Dependencies) ({ + customizeHeader={({ searchProps, ...rest }) => ({ + ...rest, searchProps: { ...searchProps, placeholder: "Search...", @@ -45,7 +46,7 @@ const NonInjectedMutatingWebhookConfigurations = observer((props: Dependencies) item => item.getSearchFields(), item => item.getLabels(), ]} - renderHeaderTitle="Mutating Webhook Configurations" + renderHeaderTitle="Mutating Webhook Configs" renderTableHeader={[ { title: "Name", className: "name", sortBy: columnId.name, id: columnId.name }, {