1
0
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

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2021-12-06 18:22:52 -05:00
parent 0784085bf4
commit 19e87b2972
2 changed files with 49 additions and 3 deletions

View File

@ -3,6 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import Joi from "joi";
/**
* JSON serializable metadata type
*/
@ -27,6 +29,37 @@ export type ClusterId = string;
*/
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
*/

View File

@ -17,7 +17,7 @@ import type { VersionDetector } from "../../main/cluster-detectors/version-detec
import type { DetectorRegistry } from "../../main/cluster-detectors/detector-registry";
import plimit from "p-limit";
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 type { Response } from "request";
import { clusterListNamespaceForbiddenChannel } from "../ipc/cluster";
@ -236,9 +236,16 @@ export class Cluster implements ClusterModel, ClusterState {
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);
this.id = model.id;
const { error } = clusterModelIdChecker.validate({ id });
if (error) {
throw error;
}
this.id = id;
this.updateModel(model);
this.apiUrl = configData.clusterServerUrl;
@ -260,6 +267,12 @@ export class Cluster implements ClusterModel, ClusterState {
@action updateModel(model: UpdateClusterModel) {
// Note: do not assign ID as that should never be updated
const { error } = updateClusterModelChecker.validate(model);
if (error) {
throw error;
}
this.kubeConfigPath = model.kubeConfigPath;
this.contextName = model.contextName;