mirror of https://github.com/kubernetes/kops.git
kube-scheduler: MVP configuration validation
We check that users haven't specified the kubeconfig file path, as this file is created / managed by kOps. We don't try to reuse the upstream configuration validation, as this allows the user to specify a partial configuration, and this means that we don't have to pull in the upstream libraries. We could in future accept the "correct" value or just treat providing a value as a signal that kOps should not manage the file; for now we are starting with the most restrictive configuration, as we can then relax it in future if needed.
This commit is contained in:
parent
c82c30d8aa
commit
e4d8dff835
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func ValidateAdditionalObject(ctx context.Context, fieldPath *field.Path, u *unstructured.Unstructured) field.ErrorList {
|
||||
var errors field.ErrorList
|
||||
|
||||
gvk := u.GroupVersionKind()
|
||||
|
||||
// Note: we use unstructured because:
|
||||
// 1) it means we don't have to depend on types / validation code from multiple projects
|
||||
// 2) we can more easily differentiate whether a field is set.
|
||||
// 3) we can support partial configuration specification - just the fields we care about.
|
||||
//
|
||||
// It would be nice to be able to consume validation code e.g. via a container,
|
||||
// so we could be more extensible.
|
||||
errors = append(errors, validateAdditionalObjectKubescheduler(ctx, fieldPath, gvk, u)...)
|
||||
return errors
|
||||
}
|
||||
|
||||
func validateAdditionalObjectKubescheduler(ctx context.Context, fieldPath *field.Path, gvk schema.GroupVersionKind, u *unstructured.Unstructured) field.ErrorList {
|
||||
var errors field.ErrorList
|
||||
|
||||
if gvk.Kind == "KubeSchedulerConfiguration" && gvk.Group == "kubescheduler.config.k8s.io" {
|
||||
kubeconfig, found, err := unstructured.NestedString(u.Object, "clientConnection", "kubeconfig")
|
||||
if err != nil {
|
||||
errors = append(errors, field.Invalid(fieldPath.Child("clientConnection", "kubeconfig"), u, fmt.Sprintf("error reading field: %v", err)))
|
||||
}
|
||||
if found && kubeconfig != "" {
|
||||
errors = append(errors, field.Invalid(fieldPath.Child("clientConnection", "kubeconfig"), kubeconfig, "value is controlled by kOps and should not be set"))
|
||||
}
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
|
@ -18,12 +18,15 @@ package vfsclientset
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kops/pkg/acls"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/validation"
|
||||
"k8s.io/kops/pkg/client/simple"
|
||||
"k8s.io/kops/pkg/kubemanifest"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
|
@ -56,6 +59,23 @@ func newAddonsVFS(c *VFSClientset, cluster *kops.Cluster) *vfsAddonsClient {
|
|||
|
||||
// TODO: Offer partial replacement?
|
||||
func (c *vfsAddonsClient) Replace(addons kubemanifest.ObjectList) error {
|
||||
ctx := context.TODO()
|
||||
|
||||
for _, addon := range addons {
|
||||
fieldPath := field.NewPath("addons")
|
||||
if kind := addon.Kind(); kind != "" {
|
||||
fieldPath = fieldPath.Child("kind=" + kind)
|
||||
}
|
||||
if name := addon.GetName(); name != "" {
|
||||
fieldPath = fieldPath.Child("name=" + name)
|
||||
}
|
||||
|
||||
errors := validation.ValidateAdditionalObject(ctx, fieldPath, addon.ToUnstructured())
|
||||
if len(errors) != 0 {
|
||||
return errors.ToAggregate()
|
||||
}
|
||||
}
|
||||
|
||||
b, err := addons.ToYAML()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue