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
+)