-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Icinga DB Migration Script: Inform user about wrong/missing YAML entries #574
Comments
TODO
|
Do you mean calling Lines 22 to 23 in a57f0cb
So is that one an item just for the migration tool while the rest affects both that one and the daemon? |
No, I thought of hooking our validators into https://pkg.go.dev/github.com/go-playground/validator/v10#Validate.Struct |
What would this do better than the existing |
E.g. diff --git a/pkg/config/config.go b/pkg/config/config.go
index 1388ba93..ca1e5cd5 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -4,6 +4,7 @@ import (
"crypto/tls"
"crypto/x509"
"github.com/creasty/defaults"
+ "github.com/go-playground/validator/v10"
"github.com/goccy/go-yaml"
"github.com/jessevdk/go-flags"
"github.com/pkg/errors"
@@ -54,7 +55,7 @@ func FromYAMLFile(name string) (*Config, error) {
defer f.Close()
c := &Config{}
- d := yaml.NewDecoder(f)
+ d := yaml.NewDecoder(f, yaml.Validator(validator.New()))
if err := defaults.Set(c); err != nil {
return nil, errors.Wrap(err, "can't set config defaults")
diff --git a/pkg/config/database.go b/pkg/config/database.go
index b42ff8e1..560fe2e6 100644
--- a/pkg/config/database.go
+++ b/pkg/config/database.go
@@ -22,7 +22,7 @@ var registerDriverOnce sync.Once
// Database defines database client configuration.
type Database struct {
- Type string `yaml:"type" default:"mysql"`
+ Type string `yaml:"type" default:"mysql" validate:"eq=mysql|eq=pgsql"`
Host string `yaml:"host"`
Port int `yaml:"port"`
Database string `yaml:"database"` would replace
with
Just the location display is awesome and the message is probably customisable. |
I didn't know that this was integrated in the YAML parser. So that actually looks useful. |
What about instead writing the possible options as struct fields? So they're noted somewhere AND re-use #605. Mappifying that struct automatically should be easy. IMAO we could also let it as is. This point is really not super critical.
The errors have one hardcoded pattern: So, nope:
I'll have to create and register tags with speaking names like greater_zero, so the error at least: - validation for '%s' failed on the 'gte' tag
+ validation for '%s' failed on the 'greater_zero' tag Or I'll register an additional tag making a note somewhere my wrapper of this validator will pick up. |
There's an even better solution. How do you like
(especially for migration which has two databases) at the cost of the following? - Type string `yaml:"type" default:"mysql"`
+ Type string `yaml:"type" default:"mysql" validate:"eq=mysql|eq=pgsql" errmsg:"must be one of: mysql, pgsql"` - if err := yaml.NewDecoder(cf).Decode(c); err != nil {
+ if err := yaml.NewDecoder(cf, Validator{}).Decode(c); err != nil { package config
import (
"github.com/go-playground/validator/v10"
"github.com/goccy/go-yaml"
"reflect"
"strings"
)
var upstream = validator.New()
type Validator struct{}
func (Validator) Struct(s any) error {
err := upstream.Struct(s)
if err != nil {
if ve, ok := err.(validator.ValidationErrors); ok {
t := reflect.TypeOf(s)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() == reflect.Struct {
overridden := make(validationErrors, 0, len(ve))
changed := false
for _, e := range ve {
if f, ok := t.FieldByName(e.StructField()); ok {
if errmsg := f.Tag.Get("errmsg"); errmsg != "" {
e = &fieldError{e, errmsg}
changed = true
}
}
overridden = append(overridden, e)
}
if changed {
return overridden
}
}
}
}
return err
}
type validationErrors []validator.FieldError
func (ve validationErrors) Error() string {
var sb strings.Builder
for _, e := range ve {
sb.WriteString(e.Error())
sb.WriteByte('\n')
}
return sb.String()
}
type fieldError struct {
validator.FieldError
err string
}
func (fe *fieldError) Error() string {
return fe.err
}
Of course to override just the error message, I need fieldError. Finally, validator.ValidationErrors are picky about what they contain ( |
I just ran into a problem on which the migration script for IDO to Icinga DB threw the following error:
The reason for that was the missing environment Id, which was set inside the YAML. However, two issues occurred on my side (full user error on my side):
Icinga2
instead oficinga2
env
entry was added without indentation of two spacesIt would be great if the script would check the YAML before the execution and validate that the section
icinga2
(or any other section mandatory) is present as well as theenv
entry is set on the correct indentation.This would help a lot with troubleshooting.
The text was updated successfully, but these errors were encountered: