diff --git a/pkg/envoy/yaml/applications.go b/pkg/envoy/yaml/applications.go index 70a48d690..cad68a4bd 100644 --- a/pkg/envoy/yaml/applications.go +++ b/pkg/envoy/yaml/applications.go @@ -3,6 +3,7 @@ package yaml import ( "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "github.com/cortezaproject/corteza-server/system/types" "gopkg.in/yaml.v3" ) @@ -25,13 +26,13 @@ type ( // When resolving map, key is used as handle // Also supporting { handle: name } definitions func (wset *applicationSet) UnmarshalYAML(n *yaml.Node) error { - return eachSeq(n, func(v *yaml.Node) (err error) { + return EachSeq(n, func(v *yaml.Node) (err error) { var ( wrap = &application{} ) if v == nil { - return nodeErr(n, "malformed application definition") + return NodeErr(n, "malformed application definition") } wrap.res = &types.Application{ @@ -40,7 +41,7 @@ func (wset *applicationSet) UnmarshalYAML(n *yaml.Node) error { switch v.Kind { case yaml.ScalarNode: - if err = decodeScalar(v, "application name", &wrap.res.Name); err != nil { + if err = DecodeScalar(v, "application name", &wrap.res.Name); err != nil { return } @@ -72,8 +73,8 @@ func (wset applicationSet) MarshalEnvoy() ([]resource.Interface, error) { } func (wrap *application) UnmarshalYAML(n *yaml.Node) (err error) { - if !isKind(n, yaml.MappingNode) { - return nodeErr(n, "application definition must be a map") + if !IsKind(n, yaml.MappingNode) { + return NodeErr(n, "application definition must be a map") } if wrap.res == nil { diff --git a/pkg/envoy/yaml/compose.go b/pkg/envoy/yaml/compose.go index 5e941fd95..f38784f93 100644 --- a/pkg/envoy/yaml/compose.go +++ b/pkg/envoy/yaml/compose.go @@ -1,6 +1,7 @@ package yaml import ( + . "github.com/cortezaproject/corteza-server/pkg/y7s" "reflect" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" @@ -24,11 +25,11 @@ func (c *compose) UnmarshalYAML(n *yaml.Node) error { ) // 1st pass: handle doc-level references - err = eachMap(n, func(k, v *yaml.Node) error { + err = EachMap(n, func(k, v *yaml.Node) error { switch k.Value { case "namespace": - if def := findKeyNode(n, "namespaces"); def != nil { - return nodeErr(def, "cannot combine namespace reference and namespaces definition") + if def := FindKeyNode(n, "namespaces"); def != nil { + return NodeErr(def, "cannot combine namespace reference and namespaces definition") } if err := decodeRef(v, "namespace", &nsRef); err != nil { @@ -44,7 +45,7 @@ func (c *compose) UnmarshalYAML(n *yaml.Node) error { } // 2nd pass: handle definitions - return eachMap(n, func(k, v *yaml.Node) error { + return EachMap(n, func(k, v *yaml.Node) error { switch k.Value { case "namespaces": err = v.Decode(&c.Namespaces) diff --git a/pkg/envoy/yaml/compose_chart.go b/pkg/envoy/yaml/compose_chart.go index 820dc1414..2c5520ec3 100644 --- a/pkg/envoy/yaml/compose_chart.go +++ b/pkg/envoy/yaml/compose_chart.go @@ -2,6 +2,7 @@ package yaml import ( "fmt" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "github.com/cortezaproject/corteza-server/compose/types" "github.com/cortezaproject/corteza-server/pkg/envoy" @@ -36,13 +37,13 @@ type ( ) func (wset *composeChartSet) UnmarshalYAML(n *yaml.Node) error { - return eachMap(n, func(k, v *yaml.Node) (err error) { + return EachMap(n, func(k, v *yaml.Node) (err error) { var ( wrap = &composeChart{} ) if v == nil { - return nodeErr(n, "malformed chart definition") + return NodeErr(n, "malformed chart definition") } if err = v.Decode(&wrap); err != nil { @@ -108,13 +109,13 @@ func (wrap *composeChart) UnmarshalYAML(n *yaml.Node) (err error) { return } - return eachMap(n, func(k, v *yaml.Node) (err error) { + return EachMap(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "handle": - return decodeScalar(v, "chart handle", &wrap.res.Handle) + return DecodeScalar(v, "chart handle", &wrap.res.Handle) case "name": - return decodeScalar(v, "chart name", &wrap.res.Name) + return DecodeScalar(v, "chart name", &wrap.res.Name) case "config": cfg := composeChartConfig{ @@ -149,12 +150,12 @@ func (wrap composeChart) MarshalEnvoy() ([]resource.Interface, error) { } func (wrap *composeChartConfig) UnmarshalYAML(n *yaml.Node) error { - return eachMap(n, func(k, v *yaml.Node) (err error) { + return EachMap(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "reports": reports := make([]composeChartConfigReport, 0) if err = v.Decode(&reports); err != nil { - return nodeErr(v, "could not decode reports: %w", err) + return NodeErr(v, "could not decode reports: %w", err) } // collect reports and referenced modules from wrapped type @@ -169,7 +170,7 @@ func (wrap *composeChartConfig) UnmarshalYAML(n *yaml.Node) error { case "colorScheme": if err = v.Decode(&wrap.config.ColorScheme); err != nil { - return nodeErr(v, "could not decode color scheme: %w", err) + return NodeErr(v, "could not decode color scheme: %w", err) } } @@ -183,7 +184,7 @@ func (wrap *composeChartConfigReport) UnmarshalYAML(n *yaml.Node) error { return err } - return eachMap(n, func(k, v *yaml.Node) (err error) { + return EachMap(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "module": // custom decoder for referenced module diff --git a/pkg/envoy/yaml/compose_module.go b/pkg/envoy/yaml/compose_module.go index 5a6cdecf6..df20481c7 100644 --- a/pkg/envoy/yaml/compose_module.go +++ b/pkg/envoy/yaml/compose_module.go @@ -2,11 +2,11 @@ package yaml import ( "fmt" - "github.com/cortezaproject/corteza-server/compose/types" "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" "github.com/cortezaproject/corteza-server/pkg/handle" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "gopkg.in/yaml.v3" ) @@ -46,13 +46,13 @@ type ( ) func (wset *composeModuleSet) UnmarshalYAML(n *yaml.Node) error { - return each(n, func(k, v *yaml.Node) (err error) { + return Each(n, func(k, v *yaml.Node) (err error) { var ( wrap = &composeModule{} ) if v == nil { - return nodeErr(n, "malformed module definition") + return NodeErr(n, "malformed module definition") } if err = v.Decode(&wrap); err != nil { @@ -60,7 +60,7 @@ func (wset *composeModuleSet) UnmarshalYAML(n *yaml.Node) error { } if err = decodeRef(k, "module", &wrap.res.Handle); err != nil { - return nodeErr(n, "Chart reference must be a valid handle") + return NodeErr(n, "Chart reference must be a valid handle") } if wrap.res.Name == "" { @@ -118,17 +118,17 @@ func (wrap *composeModule) UnmarshalYAML(n *yaml.Node) (err error) { return } - return eachMap(n, func(k, v *yaml.Node) (err error) { + return EachMap(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "name": - return decodeScalar(v, "module name", &wrap.res.Name) + return DecodeScalar(v, "module name", &wrap.res.Name) case "handle": - return decodeScalar(v, "module handle", &wrap.res.Handle) + return DecodeScalar(v, "module handle", &wrap.res.Handle) case "fields": - if !isKind(v, yaml.MappingNode) { - return nodeErr(n, "field definition must be a map") + if !IsKind(v, yaml.MappingNode) { + return NodeErr(n, "field definition must be a map") } var ( @@ -143,10 +143,10 @@ func (wrap *composeModule) UnmarshalYAML(n *yaml.Node) (err error) { return nil case "records": - if isKind(v, yaml.MappingNode) { + if IsKind(v, yaml.MappingNode) { return v.Decode(&wrap.recTpl) } else { - return nodeErr(n, "records definition must be a map") + return NodeErr(n, "records definition must be a map") } } @@ -179,17 +179,17 @@ func (wrap composeModule) MarshalEnvoy() ([]resource.Interface, error) { } func (rt *composeRecordTpl) UnmarshalYAML(n *yaml.Node) error { - return eachMap(n, func(k, v *yaml.Node) (err error) { + return EachMap(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "source", "origin", "from": rt.Source = v.Value case "key", "index", "pk": - if !isKind(v, yaml.SequenceNode) { + if !IsKind(v, yaml.SequenceNode) { rt.Key = []string{v.Value} } else { rt.Key = make([]string, 0, 3) - eachSeq(v, func(v *yaml.Node) error { + EachSeq(v, func(v *yaml.Node) error { rt.Key = append(rt.Key, v.Value) return nil }) @@ -200,9 +200,9 @@ func (rt *composeRecordTpl) UnmarshalYAML(n *yaml.Node) error { // When provided as a sequence node, map the fields based on the index. // first cell is mapped to the first sequence value, second cell to the second, and so on. // Omit cells with empty, /, or - value. - if isKind(v, yaml.SequenceNode) { + if IsKind(v, yaml.SequenceNode) { i := uint(0) - eachSeq(v, func(v *yaml.Node) error { + EachSeq(v, func(v *yaml.Node) error { defer func() { i++ }() if v.Value == "" || v.Value == "/" || v.Value == "-" { @@ -217,13 +217,13 @@ func (rt *composeRecordTpl) UnmarshalYAML(n *yaml.Node) error { }) return nil }) - } else if isKind(v, yaml.MappingNode) { + } else if IsKind(v, yaml.MappingNode) { // When provided as a mapping node, it can be a simple cell: field map // or a more complex underlying structure. - eachMap(v, func(k, v *yaml.Node) error { + EachMap(v, func(k, v *yaml.Node) error { m := &mappingTpl{} - if isKind(v, yaml.MappingNode) { + if IsKind(v, yaml.MappingNode) { v.Decode(m) } else { m.Field = v.Value @@ -241,13 +241,13 @@ func (rt *composeRecordTpl) UnmarshalYAML(n *yaml.Node) error { } func (set *composeModuleFieldSet) UnmarshalYAML(n *yaml.Node) error { - return each(n, func(k, v *yaml.Node) (err error) { + return Each(n, func(k, v *yaml.Node) (err error) { var ( wrap = &composeModuleField{} ) if v == nil { - return nodeErr(n, "malformed module field definition") + return NodeErr(n, "malformed module field definition") } if err = v.Decode(&wrap); err != nil { @@ -256,7 +256,7 @@ func (set *composeModuleFieldSet) UnmarshalYAML(n *yaml.Node) error { if k != nil { if !handle.IsValid(k.Value) { - return nodeErr(n, "field name must be a valid handle") + return NodeErr(n, "field name must be a valid handle") } wrap.res.Name = k.Value @@ -288,31 +288,31 @@ func (wrap *composeModuleField) UnmarshalYAML(n *yaml.Node) (err error) { return } - return eachMap(n, func(k, v *yaml.Node) (err error) { + return EachMap(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "name": return fmt.Errorf("name should be encoded as field definition key") case "place": - return decodeScalar(v, "module place", &wrap.res.Place) + return DecodeScalar(v, "module place", &wrap.res.Place) case "kind": - return decodeScalar(v, "module kind", &wrap.res.Kind) + return DecodeScalar(v, "module kind", &wrap.res.Kind) case "label": - return decodeScalar(v, "module label", &wrap.res.Label) + return DecodeScalar(v, "module label", &wrap.res.Label) case "private": - return decodeScalar(v, "module private", &wrap.res.Private) + return DecodeScalar(v, "module private", &wrap.res.Private) case "required": - return decodeScalar(v, "module required", &wrap.res.Required) + return DecodeScalar(v, "module required", &wrap.res.Required) case "visible": - return decodeScalar(v, "module visible", &wrap.res.Visible) + return DecodeScalar(v, "module visible", &wrap.res.Visible) case "multi": - return decodeScalar(v, "module multi", &wrap.res.Multi) + return DecodeScalar(v, "module multi", &wrap.res.Multi) case "options": if err = v.Decode(&wrap.res.Options); err != nil { @@ -333,7 +333,7 @@ func (wrap *composeModuleField) UnmarshalYAML(n *yaml.Node) (err error) { rvs = rvs.Set(&types.RecordValue{Value: v.Value}) case yaml.SequenceNode: - _ = eachSeq(v, func(v *yaml.Node) error { + _ = EachSeq(v, func(v *yaml.Node) error { rvs = rvs.Set(&types.RecordValue{Value: v.Value, Place: uint(len(rvs))}) return nil }) @@ -347,7 +347,7 @@ func (wrap *composeModuleField) UnmarshalYAML(n *yaml.Node) (err error) { } func (aux *composeModuleFieldExprAux) UnmarshalYAML(n *yaml.Node) (err error) { - return eachMap(n, func(k *yaml.Node, v *yaml.Node) error { + return EachMap(n, func(k *yaml.Node, v *yaml.Node) error { switch k.Value { case "valueExpr", "value": aux.ValueExpr = v.Value @@ -356,14 +356,14 @@ func (aux *composeModuleFieldExprAux) UnmarshalYAML(n *yaml.Node) (err error) { aux.Sanitizers = []string{v.Value} return nil case "sanitizers": - return eachSeq(v, func(san *yaml.Node) error { + return EachSeq(v, func(san *yaml.Node) error { aux.Sanitizers = append(aux.Sanitizers, san.Value) return nil }) case "validator", "validators": - return each(v, func(k *yaml.Node, v *yaml.Node) error { + return Each(v, func(k *yaml.Node, v *yaml.Node) error { vld := &types.ModuleFieldValidator{} - if isKind(v, yaml.MappingNode) { + if IsKind(v, yaml.MappingNode) { if err := v.Decode(vld); err != nil { return err } @@ -381,7 +381,7 @@ func (aux *composeModuleFieldExprAux) UnmarshalYAML(n *yaml.Node) (err error) { aux.Formatters = []string{v.Value} return nil case "formatters": - return eachSeq(v, func(fmt *yaml.Node) error { + return EachSeq(v, func(fmt *yaml.Node) error { aux.Formatters = append(aux.Formatters, fmt.Value) return nil }) diff --git a/pkg/envoy/yaml/compose_namespace.go b/pkg/envoy/yaml/compose_namespace.go index 691419053..828af969d 100644 --- a/pkg/envoy/yaml/compose_namespace.go +++ b/pkg/envoy/yaml/compose_namespace.go @@ -5,6 +5,7 @@ import ( "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" "github.com/cortezaproject/corteza-server/pkg/handle" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "gopkg.in/yaml.v3" ) @@ -39,13 +40,13 @@ type ( // // func (wset *composeNamespaceSet) UnmarshalYAML(n *yaml.Node) error { - return each(n, func(k, v *yaml.Node) (err error) { + return Each(n, func(k, v *yaml.Node) (err error) { var ( wrap = &composeNamespace{} ) if v == nil { - return nodeErr(n, "malformed namespace definition") + return NodeErr(n, "malformed namespace definition") } if err = v.Decode(&wrap); err != nil { @@ -54,11 +55,11 @@ func (wset *composeNamespaceSet) UnmarshalYAML(n *yaml.Node) error { if k != nil { if wrap.res.Slug != "" { - return nodeErr(k, "cannot define slug in mapped namespace definition") + return NodeErr(k, "cannot define slug in mapped namespace definition") } if !handle.IsValid(k.Value) { - return nodeErr(n, "namespace reference must be a valid handle") + return NodeErr(n, "namespace reference must be a valid handle") } // set namespace slug from map key value @@ -86,8 +87,8 @@ func (wset composeNamespaceSet) MarshalEnvoy() ([]resource.Interface, error) { } func (wrap *composeNamespace) UnmarshalYAML(n *yaml.Node) (err error) { - if !isKind(n, yaml.MappingNode) { - return nodeErr(n, "namespace definition must be a map or scalar") + if !IsKind(n, yaml.MappingNode) { + return NodeErr(n, "namespace definition must be a map or scalar") } if wrap.res == nil { @@ -113,7 +114,7 @@ func (wrap *composeNamespace) UnmarshalYAML(n *yaml.Node) (err error) { return } - return each(n, func(k, v *yaml.Node) (err error) { + return Each(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "modules": return v.Decode(&wrap.modules) diff --git a/pkg/envoy/yaml/compose_page.go b/pkg/envoy/yaml/compose_page.go index f85680012..031f96af1 100644 --- a/pkg/envoy/yaml/compose_page.go +++ b/pkg/envoy/yaml/compose_page.go @@ -2,6 +2,7 @@ package yaml import ( "fmt" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "github.com/cortezaproject/corteza-server/compose/types" "github.com/cortezaproject/corteza-server/pkg/envoy" @@ -32,7 +33,7 @@ type ( func (wset *composePageSet) UnmarshalYAML(n *yaml.Node) error { wx := make(map[uint64]int) - return each(n, func(k, v *yaml.Node) (err error) { + return Each(n, func(k, v *yaml.Node) (err error) { var ( wrap = &composePage{ // Set this to something negative so we have an easier time determining @@ -42,7 +43,7 @@ func (wset *composePageSet) UnmarshalYAML(n *yaml.Node) error { ) if v == nil { - return nodeErr(n, "malformed page definition") + return NodeErr(n, "malformed page definition") } if err = v.Decode(&wrap); err != nil { @@ -120,22 +121,22 @@ func (wrap *composePage) UnmarshalYAML(n *yaml.Node) (err error) { return } - return eachMap(n, func(k, v *yaml.Node) (err error) { + return EachMap(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "title": - return decodeScalar(v, "page title", &wrap.res.Title) + return DecodeScalar(v, "page title", &wrap.res.Title) case "handle": - return decodeScalar(v, "page handle", &wrap.res.Handle) + return DecodeScalar(v, "page handle", &wrap.res.Handle) case "module": return decodeRef(v, "page module", &wrap.refModule) case "visible": - return decodeScalar(v, "page visible", &wrap.res.Visible) + return DecodeScalar(v, "page visible", &wrap.res.Visible) case "description": - return decodeScalar(v, "page description", &wrap.res.Description) + return DecodeScalar(v, "page description", &wrap.res.Description) case "blocks": var cpb = make([]composePageBlock, 0) diff --git a/pkg/envoy/yaml/compose_record.go b/pkg/envoy/yaml/compose_record.go index 7ba695080..5611f4306 100644 --- a/pkg/envoy/yaml/compose_record.go +++ b/pkg/envoy/yaml/compose_record.go @@ -5,6 +5,7 @@ import ( "github.com/cortezaproject/corteza-server/compose/types" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "gopkg.in/yaml.v3" ) @@ -29,22 +30,22 @@ type ( // // When resolving map, key is used as module handle func (wset *composeRecordSet) UnmarshalYAML(n *yaml.Node) error { - return each(n, func(k, v *yaml.Node) (err error) { + return Each(n, func(k, v *yaml.Node) (err error) { var ( moduleRef string ) if v == nil { - return nodeErr(n, "malformed record definition") + return NodeErr(n, "malformed record definition") } if err = decodeRef(k, "module", &moduleRef); err != nil { return } - if isKind(v, yaml.SequenceNode) { + if IsKind(v, yaml.SequenceNode) { // multiple records defined - return eachSeq(v, func(r *yaml.Node) error { + return EachSeq(v, func(r *yaml.Node) error { var wrap = &composeRecord{refModule: moduleRef} if err = r.Decode(&wrap); err != nil { return err @@ -55,7 +56,7 @@ func (wset *composeRecordSet) UnmarshalYAML(n *yaml.Node) error { }) } - if isKind(v, yaml.MappingNode) { + if IsKind(v, yaml.MappingNode) { // one record defined var wrap = &composeRecord{refModule: moduleRef} if err = v.Decode(&wrap); err != nil { @@ -177,7 +178,7 @@ func (wrap *composeRecord) UnmarshalYAML(n *yaml.Node) (err error) { return } - return eachMap(n, func(k, v *yaml.Node) error { + return EachMap(n, func(k, v *yaml.Node) error { switch k.Value { case "module": return decodeRef(v, "module", &wrap.refModule) diff --git a/pkg/envoy/yaml/decoder.go b/pkg/envoy/yaml/decoder.go index 47365eb4e..842af4302 100644 --- a/pkg/envoy/yaml/decoder.go +++ b/pkg/envoy/yaml/decoder.go @@ -2,6 +2,8 @@ package yaml import ( "context" + "github.com/cortezaproject/corteza-server/pkg/handle" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "io" "strings" @@ -50,3 +52,21 @@ func (y *decoder) Decode(ctx context.Context, r io.Reader, dctx *envoy.DecoderOp return doc.Decode(ctx) } + +// Checks validity of ref node and sets the value to given arg ptr +func decodeRef(n *yaml.Node, refType string, ref *string) error { + if n == nil { + return nil + } + + if !IsKind(n, yaml.ScalarNode) { + return NodeErr(n, "%s reference must be scalar", refType) + } + + if !handle.IsValid(n.Value) { + return NodeErr(n, "%s reference must be a valid handle", refType) + } + + *ref = n.Value + return nil +} diff --git a/pkg/envoy/yaml/document.go b/pkg/envoy/yaml/document.go index 25dd1973f..85ef4645c 100644 --- a/pkg/envoy/yaml/document.go +++ b/pkg/envoy/yaml/document.go @@ -4,6 +4,7 @@ import ( "context" "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "gopkg.in/yaml.v3" ) @@ -33,7 +34,7 @@ func (doc *Document) UnmarshalYAML(n *yaml.Node) (err error) { return } - return eachMap(n, func(k, v *yaml.Node) error { + return EachMap(n, func(k, v *yaml.Node) error { switch k.Value { case "roles": return v.Decode(&doc.roles) diff --git a/pkg/envoy/yaml/messaging_channel.go b/pkg/envoy/yaml/messaging_channel.go index b054efc11..cceff6fa8 100644 --- a/pkg/envoy/yaml/messaging_channel.go +++ b/pkg/envoy/yaml/messaging_channel.go @@ -4,6 +4,7 @@ import ( "github.com/cortezaproject/corteza-server/messaging/types" "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "gopkg.in/yaml.v3" ) @@ -28,13 +29,13 @@ type ( // Also supporting { handle: name } definitions // func (wset *messagingChannelSet) UnmarshalYAML(n *yaml.Node) error { - return eachSeq(n, func(v *yaml.Node) (err error) { + return EachSeq(n, func(v *yaml.Node) (err error) { var ( wrap = &messagingChannel{} ) - if v == nil || !isKind(v, yaml.MappingNode) { - return nodeErr(n, "malformed messagingChannel definition") + if v == nil || !IsKind(v, yaml.MappingNode) { + return NodeErr(n, "malformed messagingChannel definition") } wrap.res = &types.Channel{} @@ -63,8 +64,8 @@ func (wset messagingChannelSet) MarshalEnvoy() ([]resource.Interface, error) { } func (wrap *messagingChannel) UnmarshalYAML(n *yaml.Node) (err error) { - if !isKind(n, yaml.MappingNode) { - return nodeErr(n, "messagingChannel definition must be a map") + if !IsKind(n, yaml.MappingNode) { + return NodeErr(n, "messagingChannel definition must be a map") } if wrap.res == nil { diff --git a/pkg/envoy/yaml/rbac_rules.go b/pkg/envoy/yaml/rbac_rules.go index b040bfbc8..cf408cd85 100644 --- a/pkg/envoy/yaml/rbac_rules.go +++ b/pkg/envoy/yaml/rbac_rules.go @@ -6,6 +6,7 @@ import ( "github.com/cortezaproject/corteza-server/pkg/envoy/resource" "github.com/cortezaproject/corteza-server/pkg/rbac" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "gopkg.in/yaml.v3" ) @@ -29,7 +30,7 @@ func decodeRbac(n *yaml.Node) (rbacRuleSet, error) { rr = make(rbacRuleSet, 0, 20) ) - return rr, eachMap(n, func(k, v *yaml.Node) (err error) { + return rr, EachMap(n, func(k, v *yaml.Node) (err error) { switch k.Value { case "allow": rr, err = rr.decodeRbac(rbac.Allow, v) @@ -55,7 +56,7 @@ func (rr rbacRuleSet) decodeRbac(a rbac.Access, rules *yaml.Node) (rbacRuleSet, var err error parseOps := func(ops *yaml.Node, roleRef, res string) error { - return eachSeq(ops, func(op *yaml.Node) error { + return EachSeq(ops, func(op *yaml.Node) error { rule := &rbacRule{ res: &rbac.Rule{ Access: a, @@ -69,10 +70,10 @@ func (rr rbacRuleSet) decodeRbac(a rbac.Access, rules *yaml.Node) (rbacRuleSet, }) } - err = eachMap(rules, func(role, ops *yaml.Node) error { + err = EachMap(rules, func(role, ops *yaml.Node) error { // If its a mapping node, keys represent resources if ops.Kind == yaml.MappingNode { - err = eachMap(ops, func(res, ops *yaml.Node) error { + err = EachMap(ops, func(res, ops *yaml.Node) error { return parseOps(ops, role.Value, res.Value) }) } else { diff --git a/pkg/envoy/yaml/resource.go b/pkg/envoy/yaml/resource.go index 7c8e31299..dae35c2c2 100644 --- a/pkg/envoy/yaml/resource.go +++ b/pkg/envoy/yaml/resource.go @@ -1,6 +1,7 @@ package yaml import ( + . "github.com/cortezaproject/corteza-server/pkg/y7s" "strings" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" @@ -22,10 +23,10 @@ func decodeEnvoyConfig(n *yaml.Node) (*resource.EnvoyConfig, error) { return nil, nil } - return ec, eachMap(ecNode, func(k, v *yaml.Node) (err error) { + return ec, EachMap(ecNode, func(k, v *yaml.Node) (err error) { switch k.Value { case "skipIf", "skip": - return decodeScalar(v, "decode skip if", &ec.SkipIf) + return DecodeScalar(v, "decode skip if", &ec.SkipIf) case "onExisting", "mergeAlg": return decodeMergeAlg(v, "decode merge alg", &ec.OnExisting) } @@ -39,8 +40,8 @@ func decodeMergeAlg(n *yaml.Node, refType string, val *resource.MergeAlg) error return nil } - if !isKind(n, yaml.ScalarNode) { - return nodeErr(n, "%s reference must be scalar", refType) + if !IsKind(n, yaml.ScalarNode) { + return NodeErr(n, "%s reference must be scalar", refType) } switch strings.ToLower(n.Value) { @@ -59,7 +60,7 @@ func decodeMergeAlg(n *yaml.Node, refType string, val *resource.MergeAlg) error "mr": *val = resource.MergeRight default: - return nodeErr(n, "%s unknown algorithm", refType) + return NodeErr(n, "%s unknown algorithm", refType) } return nil diff --git a/pkg/envoy/yaml/role.go b/pkg/envoy/yaml/role.go index 34efd088f..fec27a8bc 100644 --- a/pkg/envoy/yaml/role.go +++ b/pkg/envoy/yaml/role.go @@ -3,6 +3,7 @@ package yaml import ( "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "github.com/cortezaproject/corteza-server/system/types" "gopkg.in/yaml.v3" ) @@ -29,13 +30,13 @@ type ( // Also supporting { handle: name } definitions // func (wset *roleSet) UnmarshalYAML(n *yaml.Node) error { - return each(n, func(k, v *yaml.Node) (err error) { + return Each(n, func(k, v *yaml.Node) (err error) { var ( wrap = &role{} ) if v == nil { - return nodeErr(n, "malformed role definition") + return NodeErr(n, "malformed role definition") } wrap.res = &types.Role{ @@ -44,7 +45,7 @@ func (wset *roleSet) UnmarshalYAML(n *yaml.Node) error { switch v.Kind { case yaml.ScalarNode: - if err = decodeScalar(v, "role name", &wrap.res.Name); err != nil { + if err = DecodeScalar(v, "role name", &wrap.res.Name); err != nil { return } @@ -79,8 +80,8 @@ func (wset roleSet) MarshalEnvoy() ([]resource.Interface, error) { } func (wrap *role) UnmarshalYAML(n *yaml.Node) (err error) { - if !isKind(n, yaml.MappingNode) { - return nodeErr(n, "role definition must be a map") + if !IsKind(n, yaml.MappingNode) { + return NodeErr(n, "role definition must be a map") } if wrap.res == nil { diff --git a/pkg/envoy/yaml/settings.go b/pkg/envoy/yaml/settings.go index c17dbb0b7..a88ecfde1 100644 --- a/pkg/envoy/yaml/settings.go +++ b/pkg/envoy/yaml/settings.go @@ -2,6 +2,7 @@ package yaml import ( "github.com/cortezaproject/corteza-server/pkg/envoy/resource" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "gopkg.in/yaml.v3" ) @@ -16,8 +17,8 @@ type ( ) func (wrap *settings) UnmarshalYAML(n *yaml.Node) (err error) { - if !isKind(n, yaml.MappingNode) { - return nodeErr(n, "role definition must be a map") + if !IsKind(n, yaml.MappingNode) { + return NodeErr(n, "role definition must be a map") } if wrap.res == nil { diff --git a/pkg/envoy/yaml/stamps.go b/pkg/envoy/yaml/stamps.go index 828bb486a..4cbadadab 100644 --- a/pkg/envoy/yaml/stamps.go +++ b/pkg/envoy/yaml/stamps.go @@ -1,6 +1,7 @@ package yaml import ( + . "github.com/cortezaproject/corteza-server/pkg/y7s" "strings" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" @@ -12,18 +13,18 @@ func decodeTimestamps(n *yaml.Node) (*resource.Timestamps, error) { st = &resource.Timestamps{} ) - return st, eachMap(n, func(k, v *yaml.Node) (err error) { + return st, EachMap(n, func(k, v *yaml.Node) (err error) { switch strings.ToLower(k.Value) { case "createdat": - return decodeScalar(v, "created at", &st.CreatedAt) + return DecodeScalar(v, "created at", &st.CreatedAt) case "updatedat": - return decodeScalar(v, "updated at", &st.UpdatedAt) + return DecodeScalar(v, "updated at", &st.UpdatedAt) case "deletedat": - return decodeScalar(v, "deleted at", &st.DeletedAt) + return DecodeScalar(v, "deleted at", &st.DeletedAt) case "suspendedat": - return decodeScalar(v, "suspended at", &st.SuspendedAt) + return DecodeScalar(v, "suspended at", &st.SuspendedAt) case "archivedat": - return decodeScalar(v, "archived at", &st.ArchivedAt) + return DecodeScalar(v, "archived at", &st.ArchivedAt) } return nil }) @@ -34,17 +35,17 @@ func decodeUserstamps(n *yaml.Node) (*resource.Userstamps, error) { us = &resource.Userstamps{} ) - return us, eachMap(n, func(k, v *yaml.Node) (err error) { + return us, EachMap(n, func(k, v *yaml.Node) (err error) { switch strings.ToLower(k.Value) { case "createdby", "creatorid": - return decodeScalar(v, "created by", &us.CreatedBy) + return DecodeScalar(v, "created by", &us.CreatedBy) case "updatedby": - return decodeScalar(v, "updated by", &us.UpdatedBy) + return DecodeScalar(v, "updated by", &us.UpdatedBy) case "deletedby": - return decodeScalar(v, "deleted by", &us.DeletedBy) + return DecodeScalar(v, "deleted by", &us.DeletedBy) case "ownedby": - return decodeScalar(v, "owned by", &us.OwnedBy) + return DecodeScalar(v, "owned by", &us.OwnedBy) } return nil }) diff --git a/pkg/envoy/yaml/user.go b/pkg/envoy/yaml/user.go index d2f6b465e..eb5521137 100644 --- a/pkg/envoy/yaml/user.go +++ b/pkg/envoy/yaml/user.go @@ -3,6 +3,7 @@ package yaml import ( "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" + . "github.com/cortezaproject/corteza-server/pkg/y7s" "github.com/cortezaproject/corteza-server/system/types" "gopkg.in/yaml.v3" ) @@ -26,13 +27,13 @@ type ( // Also supporting { handle: name } definitions // func (wset *userSet) UnmarshalYAML(n *yaml.Node) error { - return each(n, func(k, v *yaml.Node) (err error) { + return Each(n, func(k, v *yaml.Node) (err error) { var ( wrap = &user{} ) if v == nil { - return nodeErr(n, "malformed user definition") + return NodeErr(n, "malformed user definition") } wrap.res = &types.User{ @@ -41,7 +42,7 @@ func (wset *userSet) UnmarshalYAML(n *yaml.Node) error { switch v.Kind { case yaml.ScalarNode: - if err = decodeScalar(v, "user email", &wrap.res.Email); err != nil { + if err = DecodeScalar(v, "user email", &wrap.res.Email); err != nil { return } @@ -51,7 +52,7 @@ func (wset *userSet) UnmarshalYAML(n *yaml.Node) error { } default: - return nodeErr(n, "expecting scalar or map with user definitions") + return NodeErr(n, "expecting scalar or map with user definitions") } @@ -80,8 +81,8 @@ func (wset userSet) MarshalEnvoy() ([]resource.Interface, error) { } func (wrap *user) UnmarshalYAML(n *yaml.Node) (err error) { - if !isKind(n, yaml.MappingNode) { - return nodeErr(n, "user definition must be a map") + if !IsKind(n, yaml.MappingNode) { + return NodeErr(n, "user definition must be a map") } if wrap.res == nil { diff --git a/pkg/envoy/yaml/yaml.go b/pkg/envoy/yaml/yaml.go deleted file mode 100644 index c0498f9a9..000000000 --- a/pkg/envoy/yaml/yaml.go +++ /dev/null @@ -1,117 +0,0 @@ -package yaml - -import ( - "fmt" - "github.com/cortezaproject/corteza-server/pkg/handle" - "gopkg.in/yaml.v3" -) - -func nodeErr(n *yaml.Node, format string, aa ...interface{}) error { - format += " (%d:%d)" - aa = append(aa, n.Line, n.Column) - return fmt.Errorf(format, aa...) -} - -// eachKV iterates over map node -func eachMap(n *yaml.Node, fn func(*yaml.Node, *yaml.Node) error) error { - if !isKind(n, yaml.MappingNode) { - // root node kind be mapping - return nodeErr(n, "expecting mapping node") - } - - for i := 0; i < len(n.Content); i += 2 { - if err := fn(n.Content[i], n.Content[i+1]); err != nil { - return err - } - } - - return nil -} - -// eachKV iterates over sequence node -func eachSeq(n *yaml.Node, fn func(*yaml.Node) error) error { - if !isKind(n, yaml.SequenceNode) { - // root node kind be mapping - return nodeErr(n, "expecting sequence node") - } - - for i := 0; i < len(n.Content); i++ { - if err := fn(n.Content[i]); err != nil { - return err - } - } - - return nil -} - -// each helps iterate over mapping and sequence nodes fairly trivially -func each(n *yaml.Node, fn func(*yaml.Node, *yaml.Node) error) error { - if isKind(n, yaml.MappingNode) { - return eachMap(n, fn) - } - - if isKind(n, yaml.SequenceNode) { - var placeholder *yaml.Node - for i := 0; i < len(n.Content); i++ { - if err := fn(placeholder, n.Content[i]); err != nil { - return err - } - } - - return nil - } - - return nodeErr(n, "expecting mapping or sequence node") -} - -func isKind(n *yaml.Node, tt ...yaml.Kind) bool { - if n != nil { - for _, t := range tt { - if t == n.Kind { - return true - } - } - } - - return false -} - -// findKeyNode returns key node from mapping -// key value checked in lower case -func findKeyNode(n *yaml.Node, key string) *yaml.Node { - // compare it with lowercase values - for i := 0; i < len(n.Content); i += 2 { - if key == n.Content[i].Value { - return n.Content[i+1] - } - } - - return nil -} - -// Checks validity of ref node and sets the value to given arg ptr -func decodeScalar(n *yaml.Node, name string, val interface{}) error { - if !isKind(n, yaml.ScalarNode) { - return nodeErr(n, "expecting scalar value for %s", name) - } - - return n.Decode(val) -} - -// Checks validity of ref node and sets the value to given arg ptr -func decodeRef(n *yaml.Node, refType string, ref *string) error { - if n == nil { - return nil - } - - if !isKind(n, yaml.ScalarNode) { - return nodeErr(n, "%s reference must be scalar", refType) - } - - if !handle.IsValid(n.Value) { - return nodeErr(n, "%s reference must be a valid handle", refType) - } - - *ref = n.Value - return nil -} diff --git a/pkg/y7s/decoders.go b/pkg/y7s/decoders.go new file mode 100644 index 000000000..99af506ce --- /dev/null +++ b/pkg/y7s/decoders.go @@ -0,0 +1,29 @@ +package y7s + +// y7s (YAML Utils) + +import ( + "gopkg.in/yaml.v3" +) + +// findKeyNode returns key node from mapping +// key value checked in lower case +func FindKeyNode(n *yaml.Node, key string) *yaml.Node { + // compare it with lowercase values + for i := 0; i < len(n.Content); i += 2 { + if key == n.Content[i].Value { + return n.Content[i+1] + } + } + + return nil +} + +// Checks validity of ref node and sets the value to given arg ptr +func DecodeScalar(n *yaml.Node, name string, val interface{}) error { + if !IsKind(n, yaml.ScalarNode) { + return NodeErr(n, "expecting scalar value for %s", name) + } + + return n.Decode(val) +} diff --git a/pkg/y7s/each.go b/pkg/y7s/each.go new file mode 100644 index 000000000..bae5845f3 --- /dev/null +++ b/pkg/y7s/each.go @@ -0,0 +1,59 @@ +package y7s + +// y7s (YAML Utils) + +import ( + "gopkg.in/yaml.v3" +) + +// eachKV iterates over map node +func EachMap(n *yaml.Node, fn func(*yaml.Node, *yaml.Node) error) error { + if !IsKind(n, yaml.MappingNode) { + // root node kind be mapping + return NodeErr(n, "expecting mapping node") + } + + for i := 0; i < len(n.Content); i += 2 { + if err := fn(n.Content[i], n.Content[i+1]); err != nil { + return err + } + } + + return nil +} + +// eachKV iterates over sequence node +func EachSeq(n *yaml.Node, fn func(*yaml.Node) error) error { + if !IsKind(n, yaml.SequenceNode) { + // root node kind be mapping + return NodeErr(n, "expecting sequence node") + } + + for i := 0; i < len(n.Content); i++ { + if err := fn(n.Content[i]); err != nil { + return err + } + } + + return nil +} + +// each helps iterate over mapping and sequence nodes fairly trivially +func Each(n *yaml.Node, fn func(*yaml.Node, *yaml.Node) error) error { + if IsKind(n, yaml.MappingNode) { + return EachMap(n, fn) + } + + if IsKind(n, yaml.SequenceNode) { + var placeholder *yaml.Node + for i := 0; i < len(n.Content); i++ { + if err := fn(placeholder, n.Content[i]); err != nil { + return err + } + } + + return nil + } + + return NodeErr(n, "expecting mapping or sequence node") +} diff --git a/pkg/y7s/error.go b/pkg/y7s/error.go new file mode 100644 index 000000000..1366366fe --- /dev/null +++ b/pkg/y7s/error.go @@ -0,0 +1,14 @@ +package y7s + +// y7s (YAML Utils) + +import ( + "fmt" + "gopkg.in/yaml.v3" +) + +func NodeErr(n *yaml.Node, format string, aa ...interface{}) error { + format += " (%d:%d)" + aa = append(aa, n.Line, n.Column) + return fmt.Errorf(format, aa...) +} diff --git a/pkg/y7s/test.go b/pkg/y7s/test.go new file mode 100644 index 000000000..4b8fff269 --- /dev/null +++ b/pkg/y7s/test.go @@ -0,0 +1,19 @@ +package y7s + +// y7s (YAML Utils) + +import ( + "gopkg.in/yaml.v3" +) + +func IsKind(n *yaml.Node, tt ...yaml.Kind) bool { + if n != nil { + for _, t := range tt { + if t == n.Kind { + return true + } + } + } + + return false +}