mirror of
https://github.com/speatzle/nfsense.git
synced 2025-06-27 23:09:37 +00:00
Add basic jsonschema validation
This commit is contained in:
parent
3fefb7ca7c
commit
6850d134fb
7 changed files with 126 additions and 0 deletions
1
go.mod
1
go.mod
|
@ -27,6 +27,7 @@ require (
|
|||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/pterm/pterm v0.12.61 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.0 // indirect
|
||||
github.com/tredoe/osutil v1.3.6 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -104,6 +104,8 @@ github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJ
|
|||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.0 h1:uIkTLo0AGRc8l7h5l9r+GcYi9qfVPt6lD4/bhmzfiKo=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"nfsense.net/nfsense/internal/definitions/service"
|
||||
"nfsense.net/nfsense/internal/definitions/system"
|
||||
"nfsense.net/nfsense/internal/definitions/vpn"
|
||||
"nfsense.net/nfsense/internal/validation"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
@ -39,6 +40,10 @@ func (c *Config) Clone() *Config {
|
|||
}
|
||||
|
||||
func ValidateConfig(conf *Config) error {
|
||||
err := validation.ValidateConfig(*conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val := validator.New()
|
||||
val.RegisterValidation("test", nilIfOtherNil)
|
||||
return val.Struct(conf)
|
||||
|
|
40
internal/validation/schema.go
Normal file
40
internal/validation/schema.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package validation
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||
)
|
||||
|
||||
//go:embed schemas/*.schema.json
|
||||
var schemasFS embed.FS
|
||||
var schema *jsonschema.Schema
|
||||
|
||||
func init() {
|
||||
all, err := schemasFS.ReadDir("schemas")
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Reading Schemas: %w", err))
|
||||
}
|
||||
|
||||
c := jsonschema.NewCompiler()
|
||||
|
||||
for _, f := range all {
|
||||
data, err := schemasFS.Open(filepath.Join("schemas", f.Name()))
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Reading Schema: %w", err))
|
||||
}
|
||||
err = c.AddResource("https://nfsense.net/"+f.Name(), data)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Adding Schema: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
s, err := c.Compile("https://nfsense.net/config.schema.json")
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Reading Schemas: %w", err))
|
||||
}
|
||||
|
||||
schema = s
|
||||
}
|
30
internal/validation/schemas/config.schema.json
Normal file
30
internal/validation/schemas/config.schema.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$id": "https://nfsense.net/config.schema.json",
|
||||
"title": "Config",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config_version": {
|
||||
"type": "number"
|
||||
},
|
||||
"firewall": {
|
||||
"type": ["number","string","boolean","object","array", "null"]
|
||||
},
|
||||
"object": {
|
||||
"type": ["number","string","boolean","object","array", "null"]
|
||||
},
|
||||
"network": {
|
||||
"type": ["number","string","boolean","object","array", "null"]
|
||||
},
|
||||
"service": {
|
||||
"type": ["number","string","boolean","object","array", "null"]
|
||||
},
|
||||
"vpn": {
|
||||
"type": ["number","string","boolean","object","array", "null"]
|
||||
},
|
||||
"system": {
|
||||
"description": "System Settings",
|
||||
"$ref": "https://nfsense.net/system.schema.json"
|
||||
}
|
||||
},
|
||||
"required": ["config_version", "firewall", "object", "network", "service", "vpn", "system"]
|
||||
}
|
26
internal/validation/schemas/system.schema.json
Normal file
26
internal/validation/schemas/system.schema.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"$id": "https://nfsense.net/system.schema.json",
|
||||
"title": "System",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"users": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"hash": {
|
||||
"type": "string"
|
||||
},
|
||||
"salt": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["hash", "salt"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["users"]
|
||||
}
|
22
internal/validation/validation.go
Normal file
22
internal/validation/validation.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package validation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func ValidateConfig(conf any) error {
|
||||
|
||||
// TODO find a better way validate config since jsonschema only takes a map[string]interface{}
|
||||
data, err := json.Marshal(conf)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Marshal Error: %w", err))
|
||||
}
|
||||
var clone any
|
||||
err = json.Unmarshal(data, &clone)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Unmarshal Error: %w", err))
|
||||
}
|
||||
|
||||
return schema.Validate(clone)
|
||||
}
|
Loading…
Add table
Reference in a new issue