This is an automated email from the ASF dual-hosted git repository.

zhongxjian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git


The following commit(s) were added to refs/heads/master by this push:
     new 6c8496d4 [operator] Add validate command logic v2
6c8496d4 is described below

commit 6c8496d403f8982ff410b3ea582444b03bf0e26f
Author: mfordjody <[email protected]>
AuthorDate: Thu Dec 26 10:26:18 2024 +0800

    [operator] Add validate command logic v2
---
 dubboctl/pkg/validate/validate.go         | 114 ++++++++++++++++++++++++++++++
 pkg/config/validation/agent/validation.go |   3 +
 pkg/config/validation/validation.go       |   7 ++
 3 files changed, 124 insertions(+)

diff --git a/dubboctl/pkg/validate/validate.go 
b/dubboctl/pkg/validate/validate.go
index 1c6b4825..48b6536d 100644
--- a/dubboctl/pkg/validate/validate.go
+++ b/dubboctl/pkg/validate/validate.go
@@ -1,10 +1,18 @@
 package validate
 
 import (
+       "bufio"
        "errors"
+       "fmt"
        "github.com/apache/dubbo-kubernetes/dubboctl/pkg/cli"
+       "github.com/apache/dubbo-kubernetes/operator/cmd/validation"
+       operator "github.com/apache/dubbo-kubernetes/operator/pkg/apis"
+       "github.com/apache/dubbo-kubernetes/operator/pkg/config"
+       "github.com/hashicorp/go-multierror"
        "github.com/spf13/cobra"
        "io"
+       "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+       "k8s.io/apimachinery/pkg/util/yaml"
 )
 
 var (
@@ -12,8 +20,90 @@ var (
 Example resource specifications include:
    '-f default.yaml'
    '--filename=default.json'`)
+
+       validFields = map[string]struct{}{
+               "apiVersion": {},
+               "kind":       {},
+               "metadata":   {},
+               "spec":       {},
+               "status":     {},
+       }
 )
 
+type validator struct{}
+
+func (v *validator) validateFile(path string, dubboNamespace *string, 
defaultNamespace string, reader io.Reader, writer io.Writer) 
(validation.Warning, error) {
+       yamlReader := yaml.NewYAMLReader(bufio.NewReader(reader))
+       var errs error
+       var warnings validation.Warnings
+       for {
+               doc, err := yamlReader.Read()
+               if err == io.EOF {
+                       return warnings, errs
+               }
+               if err != nil {
+                       errs = multierror.Append(errs, multierror.Prefix(err, 
fmt.Sprintf("failed to decode file %s: ", path)))
+                       return warnings, errs
+               }
+               if len(doc) == 0 {
+                       continue
+               }
+               out := map[string]any{}
+               if err := yaml.UnmarshalStrict(doc, &out); err != nil {
+                       errs = multierror.Append(errs, multierror.Prefix(err, 
fmt.Sprintf("failed to decode file %s: ", path)))
+                       return warnings, errs
+               }
+               un := unstructured.Unstructured{Object: out}
+               warning, err := v.validateResource(*dubboNamespace, &un, writer)
+               if err != nil {
+                       errs = multierror.Append(errs, multierror.Prefix(err, 
fmt.Sprintf("%s/%s/%s:",
+                               un.GetKind(), un.GetNamespace(), un.GetName())))
+               }
+               if warning != nil {
+                       warnings = multierror.Append(warnings, 
multierror.Prefix(warning, fmt.Sprintf("%s/%s/%s:",
+                               un.GetKind(), un.GetNamespace(), un.GetName())))
+               }
+       }
+}
+
+func (v *validator) validateResource(istioNamespace string, un 
*unstructured.Unstructured, writer io.Writer) (validation.Warnings, error) {
+       g := config.GroupVersionKind{
+               Group:   un.GroupVersionKind().Group,
+               Version: un.GroupVersionKind().Version,
+               Kind:    un.GroupVersionKind().Kind,
+       }
+       var errs error
+       if errs != nil {
+               return nil, errs
+       }
+
+       if un.GetAPIVersion() == 
operator.DubboOperatorGVK.GroupVersion().String() {
+               if un.GetKind() == operator.DubboOperatorGVK.Kind {
+                       if err := checkFields(un); err != nil {
+                               return nil, err
+                       }
+                       warnings, err := 
operatorvalidate.ParseAndValidateIstioOperator(un.Object, nil)
+                       if err != nil {
+                               return nil, err
+                       }
+                       if len(warnings) > 0 {
+                               return validation.Warning(warnings.ToError()), 
nil
+                       }
+               }
+       }
+       return nil, nil
+}
+
+func checkFields(un *unstructured.Unstructured) error {
+       var errs error
+       for key := range un.Object {
+               if _, ok := validFields[key]; !ok {
+                       errs = multierror.Append(errs, fmt.Errorf("unknown 
field %q", key))
+               }
+       }
+       return errs
+}
+
 func NewValidateCommand(ctx cli.Context) *cobra.Command {
        vc := &cobra.Command{
                Use:   "validate -f FILENAME [options]",
@@ -39,6 +129,30 @@ func validateFiles(dubboNamespace *string, files []string, 
writer io.Writer) err
        if len(files) == 0 {
                return errFiles
        }
+       v := &validator{}
+       var errs error
+       var reader io.ReadCloser
 
+       processFile := func(path string) {
+               var err error
+               if path == "-" {
+                       reader = io.NopCloser(os.Stdin)
+               } else {
+                       reader, err = os.Open(path)
+                       if err != nil {
+                               errs = multierror.Append(errs, 
fmt.Errorf("cannot read file %q: %v", path, err))
+                               return
+                       }
+               }
+               warning, err := v.validateFile(path, istioNamespace, 
defaultNamespace, reader, writer)
+               if err != nil {
+                       errs = multierror.Append(errs, err)
+               }
+               err = reader.Close()
+               if err != nil {
+                       log.Infof("file: %s is not closed: %v", path, err)
+               }
+               warningsByFilename[path] = warning
+       }
        return nil
 }
diff --git a/pkg/config/validation/agent/validation.go 
b/pkg/config/validation/agent/validation.go
new file mode 100644
index 00000000..da14d234
--- /dev/null
+++ b/pkg/config/validation/agent/validation.go
@@ -0,0 +1,3 @@
+package agent
+
+type Warning error
diff --git a/pkg/config/validation/validation.go 
b/pkg/config/validation/validation.go
new file mode 100644
index 00000000..2528e02d
--- /dev/null
+++ b/pkg/config/validation/validation.go
@@ -0,0 +1,7 @@
+package validation
+
+import "github.com/apache/dubbo-kubernetes/pkg/config/validation/agent"
+
+type (
+       Warning = agent.Warning
+)

Reply via email to