mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Validate ClusterModel before trying to update or create a Cluster (#4515)
* Validate ClusterModel before trying to update or create a Cluster Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests Signed-off-by: Sebastian Malton <sebastian@malton.name> Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
5263d9b5ec
commit
032e6d968c
@ -3,6 +3,8 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import Joi from "joi";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON serializable metadata type
|
* JSON serializable metadata type
|
||||||
*/
|
*/
|
||||||
@ -27,6 +29,37 @@ export type ClusterId = string;
|
|||||||
*/
|
*/
|
||||||
export type UpdateClusterModel = Omit<ClusterModel, "id">;
|
export type UpdateClusterModel = Omit<ClusterModel, "id">;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type validator for `UpdateClusterModel` so that only expected types are present
|
||||||
|
*/
|
||||||
|
export const updateClusterModelChecker = Joi.object<UpdateClusterModel>({
|
||||||
|
kubeConfigPath: Joi.string()
|
||||||
|
.required()
|
||||||
|
.min(1),
|
||||||
|
contextName: Joi.string()
|
||||||
|
.required()
|
||||||
|
.min(1),
|
||||||
|
workspace: Joi.string()
|
||||||
|
.optional(),
|
||||||
|
workspaces: Joi.array()
|
||||||
|
.items(Joi.string()),
|
||||||
|
preferences: Joi.object(),
|
||||||
|
metadata: Joi.object(),
|
||||||
|
accessibleNamespaces: Joi.array()
|
||||||
|
.items(Joi.string()),
|
||||||
|
labels: Joi.object().pattern(Joi.string(), Joi.string()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type validator for just the `id` fields of `ClusterModel`. The rest is
|
||||||
|
* covered by `updateClusterModelChecker`
|
||||||
|
*/
|
||||||
|
export const clusterModelIdChecker = Joi.object<Pick<ClusterModel, "id">>({
|
||||||
|
id: Joi.string()
|
||||||
|
.required()
|
||||||
|
.min(1),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The model for passing cluster data around, including to disk
|
* The model for passing cluster data around, including to disk
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import type { VersionDetector } from "../../main/cluster-detectors/version-detec
|
|||||||
import type { DetectorRegistry } from "../../main/cluster-detectors/detector-registry";
|
import type { DetectorRegistry } from "../../main/cluster-detectors/detector-registry";
|
||||||
import plimit from "p-limit";
|
import plimit from "p-limit";
|
||||||
import type { ClusterState, ClusterRefreshOptions, ClusterMetricsResourceType, ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences, UpdateClusterModel, KubeAuthUpdate, ClusterConfigData } from "../cluster-types";
|
import type { ClusterState, ClusterRefreshOptions, ClusterMetricsResourceType, ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences, UpdateClusterModel, KubeAuthUpdate, ClusterConfigData } from "../cluster-types";
|
||||||
import { ClusterMetadataKey, initialNodeShellImage, ClusterStatus } from "../cluster-types";
|
import { ClusterMetadataKey, initialNodeShellImage, ClusterStatus, clusterModelIdChecker, updateClusterModelChecker } from "../cluster-types";
|
||||||
import { disposer, isDefined, isRequestError, toJS } from "../utils";
|
import { disposer, isDefined, isRequestError, toJS } from "../utils";
|
||||||
import type { Response } from "request";
|
import type { Response } from "request";
|
||||||
import { clusterListNamespaceForbiddenChannel } from "../ipc/cluster";
|
import { clusterListNamespaceForbiddenChannel } from "../ipc/cluster";
|
||||||
@ -237,9 +237,16 @@ export class Cluster implements ClusterModel, ClusterState {
|
|||||||
return this.preferences.defaultNamespace;
|
return this.preferences.defaultNamespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private readonly dependencies: ClusterDependencies, model: ClusterModel, configData: ClusterConfigData) {
|
constructor(private readonly dependencies: ClusterDependencies, { id, ...model }: ClusterModel, configData: ClusterConfigData) {
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
this.id = model.id;
|
|
||||||
|
const { error } = clusterModelIdChecker.validate({ id });
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.id = id;
|
||||||
this.updateModel(model);
|
this.updateModel(model);
|
||||||
this.apiUrl = configData.clusterServerUrl;
|
this.apiUrl = configData.clusterServerUrl;
|
||||||
|
|
||||||
@ -261,6 +268,12 @@ export class Cluster implements ClusterModel, ClusterState {
|
|||||||
@action updateModel(model: UpdateClusterModel) {
|
@action updateModel(model: UpdateClusterModel) {
|
||||||
// Note: do not assign ID as that should never be updated
|
// Note: do not assign ID as that should never be updated
|
||||||
|
|
||||||
|
const { error } = updateClusterModelChecker.validate(model, { allowUnknown: true });
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
this.kubeConfigPath = model.kubeConfigPath;
|
this.kubeConfigPath = model.kubeConfigPath;
|
||||||
this.contextName = model.contextName;
|
this.contextName = model.contextName;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user