diff --git a/server/automation/envoy/store_encode.gen.go b/server/automation/envoy/store_encode.gen.go index 7aaaf60f0..30a4f3b6e 100644 --- a/server/automation/envoy/store_encode.gen.go +++ b/server/automation/envoy/store_encode.gen.go @@ -226,10 +226,12 @@ func (e StoreEncoder) encodeWorkflow(ctx context.Context, p envoyx.EncodeParams, } // Flush to the DB - err = store.UpsertAutomationWorkflow(ctx, s, n.Resource.(*types.Workflow)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Workflow") - return + if !n.Evaluated.Skip { + err = store.UpsertAutomationWorkflow(ctx, s, n.Resource.(*types.Workflow)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Workflow") + return + } } // Handle resources nested under it @@ -277,10 +279,6 @@ func (e StoreEncoder) matchupWorkflows(ctx context.Context, s store.Storer, uu m var aux *types.Workflow var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -441,10 +439,12 @@ func (e StoreEncoder) encodeTrigger(ctx context.Context, p envoyx.EncodeParams, } // Flush to the DB - err = store.UpsertAutomationTrigger(ctx, s, n.Resource.(*types.Trigger)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Trigger") - return + if !n.Evaluated.Skip { + err = store.UpsertAutomationTrigger(ctx, s, n.Resource.(*types.Trigger)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Trigger") + return + } } // Handle resources nested under it @@ -491,10 +491,6 @@ func (e StoreEncoder) matchupTriggers(ctx context.Context, s store.Storer, uu ma var aux *types.Trigger var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { diff --git a/server/automation/envoy/yaml_decode.gen.go b/server/automation/envoy/yaml_decode.gen.go index ce400df17..1b6290d0f 100644 --- a/server/automation/envoy/yaml_decode.gen.go +++ b/server/automation/envoy/yaml_decode.gen.go @@ -388,7 +388,7 @@ func (d *auxYamlDoc) unmarshalWorkflowNode(dctx documentContext, n *yaml.Node, m // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -437,6 +437,9 @@ func (d *auxYamlDoc) unmarshalWorkflowNode(dctx documentContext, n *yaml.Node, m } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -447,6 +450,12 @@ func (d *auxYamlDoc) unmarshalWorkflowNode(dctx documentContext, n *yaml.Node, m if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -469,7 +478,13 @@ func (d *auxYamlDoc) unmarshalWorkflowNode(dctx documentContext, n *yaml.Node, m Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -484,6 +499,14 @@ func (d *auxYamlDoc) unmarshalWorkflowNode(dctx documentContext, n *yaml.Node, m Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -676,7 +699,7 @@ func (d *auxYamlDoc) unmarshalTriggerNode(dctx documentContext, n *yaml.Node, me // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -717,6 +740,9 @@ func (d *auxYamlDoc) unmarshalTriggerNode(dctx documentContext, n *yaml.Node, me } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -727,6 +753,12 @@ func (d *auxYamlDoc) unmarshalTriggerNode(dctx documentContext, n *yaml.Node, me if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -770,12 +802,12 @@ func unmarshalDenyNode(n *yaml.Node) (out envoyx.NodeSet, err error) { func unmarshalRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { if y7s.IsMapping(n.Content[1]) { - out, err = unmarshalNestedRBACNode(n, acc) + out, err = unmarshalFlatRBACNode(n, acc) if err != nil { return } } else { - out, err = unmarshalFlatRBACNode(n, acc) + out, err = unmarshalNestedRBACNode(n, acc) if err != nil { return } @@ -810,6 +842,35 @@ func unmarshalRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err e // - read // - delete func unmarshalNestedRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { + return out, y7s.EachMap(n, func(role, op *yaml.Node) error { + out = append(out, &envoyx.Node{ + Resource: &rbac.Rule{ + Operation: op.Value, + Access: acc, + }, + ResourceType: rbac.RuleResourceType, + References: map[string]envoyx.Ref{ + "RoleID": { + // Providing resource type as plain text to reduce cross component references + ResourceType: "corteza::system:role", + Identifiers: envoyx.MakeIdentifiers(role.Value), + }, + }, + }) + return nil + }) +} + +// unmarshalFlatRBACNode handles RBAC rules when they are provided on the root level +// +// Example: +// +// allow: +// role1: +// corteza::system/: +// - users.search +// - users.create +func unmarshalFlatRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { // Handles role return out, y7s.EachMap(n, func(role, perm *yaml.Node) error { // Handles operations @@ -838,35 +899,6 @@ func unmarshalNestedRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, }) } -// unmarshalFlatRBACNode handles RBAC rules when they are provided on the root level -// -// Example: -// -// allow: -// role1: -// corteza::system/: -// - users.search -// - users.create -func unmarshalFlatRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { - return out, y7s.EachMap(n, func(role, op *yaml.Node) error { - out = append(out, &envoyx.Node{ - Resource: &rbac.Rule{ - Operation: op.Value, - Access: acc, - }, - ResourceType: rbac.RuleResourceType, - References: map[string]envoyx.Ref{ - "RoleID": { - // Providing resource type as plain text to reduce cross component references - ResourceType: "corteza::system:role", - Identifiers: envoyx.MakeIdentifiers(role.Value), - }, - }, - }) - return nil - }) -} - // // // // // // // // // // // // // // // // // // // // // // // // // // i18n unmarshal logic // // // // // // // // // // // // // // // // // // // // // // // // // diff --git a/server/codegen/assets/templates/gocode/envoy/store_encode.go.tpl b/server/codegen/assets/templates/gocode/envoy/store_encode.go.tpl index 55855982c..3abc0b5d9 100644 --- a/server/codegen/assets/templates/gocode/envoy/store_encode.go.tpl +++ b/server/codegen/assets/templates/gocode/envoy/store_encode.go.tpl @@ -246,10 +246,12 @@ func (e StoreEncoder) encode{{.expIdent}}(ctx context.Context, p envoyx.EncodePa {{ end }} // Flush to the DB - err = store.Upsert{{.store.expIdent}}(ctx, s, n.Resource.(*types.{{.expIdent}})) - if err != nil { - err = errors.Wrap(err, "failed to upsert {{.expIdent}}") - return + if !n.Evaluated.Skip { + err = store.Upsert{{.store.expIdent}}(ctx, s, n.Resource.(*types.{{.expIdent}})) + if err != nil { + err = errors.Wrap(err, "failed to upsert {{.expIdent}}") + return + } } {{ $a := . }} @@ -350,10 +352,12 @@ func (e StoreEncoder) matchup{{.expIdent}}s(ctx context.Context, s store.Storer, var aux *types.{{.expIdent}} var ok bool for i, n := range nn { - scope := scopes[i] + {{ if eq .componentIdent "compose" }} + scope := scopes[i] if scope == nil { continue } + {{ end }} for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { diff --git a/server/codegen/assets/templates/gocode/envoy/yaml_decode.go.tpl b/server/codegen/assets/templates/gocode/envoy/yaml_decode.go.tpl index a22d7da1f..06a61d803 100644 --- a/server/codegen/assets/templates/gocode/envoy/yaml_decode.go.tpl +++ b/server/codegen/assets/templates/gocode/envoy/yaml_decode.go.tpl @@ -163,7 +163,6 @@ func (d *auxYamlDoc) UnmarshalYAML(n *yaml.Node) (err error) { } {{ end }} - {{ if .envoy.yaml.defaultDecoder }} // Offload to custom handlers default: aux, err = d.unmarshalYAML(kv, v) @@ -171,7 +170,6 @@ func (d *auxYamlDoc) UnmarshalYAML(n *yaml.Node) (err error) { if err != nil { err = errors.Wrap(err, "failed to unmarshal node") } - {{ end }} } return nil }) @@ -468,7 +466,7 @@ func (d *auxYamlDoc) unmarshal{{ .expIdent }}Node(dctx documentContext, n *yaml. // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -561,13 +559,16 @@ func (d *auxYamlDoc) unmarshal{{ .expIdent }}Node(dctx documentContext, n *yaml. a.References = make(map[string]envoyx.Ref) } - a.References["{{.expIdent}}ID"] = envoyx.Ref{ + a.References["{{if .envoy.yaml.extendedResourceRefIdent}}{{.envoy.yaml.extendedResourceRefIdent}}{{else}}{{.expIdent}}ID{{end}}"] = envoyx.Ref{ ResourceType: types.{{ .expIdent }}ResourceType, Identifiers: ii, Scope: scope, } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -578,6 +579,12 @@ func (d *auxYamlDoc) unmarshal{{ .expIdent }}Node(dctx documentContext, n *yaml. if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -609,7 +616,13 @@ func (d *auxYamlDoc) unmarshal{{ .expIdent }}Node(dctx documentContext, n *yaml. } {{- if .rbac }} // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -624,6 +637,14 @@ func (d *auxYamlDoc) unmarshal{{ .expIdent }}Node(dctx documentContext, n *yaml. Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } {{ end }} @@ -653,12 +674,12 @@ func unmarshalDenyNode(n *yaml.Node) (out envoyx.NodeSet, err error) { func unmarshalRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { if y7s.IsMapping(n.Content[1]) { - out, err = unmarshalNestedRBACNode(n, acc) + out, err = unmarshalFlatRBACNode(n, acc) if err != nil { return } } else { - out, err = unmarshalFlatRBACNode(n, acc) + out, err = unmarshalNestedRBACNode(n, acc) if err != nil { return } @@ -693,7 +714,36 @@ func unmarshalRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err e // - read // - delete func unmarshalNestedRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { - // Handles role + return out, y7s.EachMap(n, func(role, op *yaml.Node) error { + out = append(out, &envoyx.Node{ + Resource: &rbac.Rule{ + Operation: op.Value, + Access: acc, + }, + ResourceType: rbac.RuleResourceType, + References: map[string]envoyx.Ref{ + "RoleID": { + // Providing resource type as plain text to reduce cross component references + ResourceType: "corteza::system:role", + Identifiers: envoyx.MakeIdentifiers(role.Value), + }, + }, + }) + return nil + }) +} + +// unmarshalFlatRBACNode handles RBAC rules when they are provided on the root level +// +// Example: +// +// allow: +// role1: +// corteza::system/: +// - users.search +// - users.create +func unmarshalFlatRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { + // Handles role return out, y7s.EachMap(n, func(role, perm *yaml.Node) error { // Handles operations return y7s.EachMap(perm, func(res, ops *yaml.Node) error { @@ -721,35 +771,6 @@ func unmarshalNestedRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, }) } -// unmarshalFlatRBACNode handles RBAC rules when they are provided on the root level -// -// Example: -// -// allow: -// role1: -// corteza::system/: -// - users.search -// - users.create -func unmarshalFlatRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { - return out, y7s.EachMap(n, func(role, op *yaml.Node) error { - out = append(out, &envoyx.Node{ - Resource: &rbac.Rule{ - Operation: op.Value, - Access: acc, - }, - ResourceType: rbac.RuleResourceType, - References: map[string]envoyx.Ref{ - "RoleID": { - // Providing resource type as plain text to reduce cross component references - ResourceType: "corteza::system:role", - Identifiers: envoyx.MakeIdentifiers(role.Value), - }, - }, - }) - return nil - }) -} - // // // // // // // // // // // // // // // // // // // // // // // // // // i18n unmarshal logic // // // // // // // // // // // // // // // // // // // // // // // // // diff --git a/server/codegen/schema/resource.cue b/server/codegen/schema/resource.cue index 22b5927d5..9ec0aef54 100644 --- a/server/codegen/schema/resource.cue +++ b/server/codegen/schema/resource.cue @@ -188,6 +188,7 @@ import ( supportMappedInput: bool | *true mappedField: string | *"" }] | *[] + extendedResourceRefIdent: string | *"" // enable or disable offloading unhandled nodes onto a custom default decoder defaultDecoder: bool | *false diff --git a/server/compose/envoy/store_encode.gen.go b/server/compose/envoy/store_encode.gen.go index a1f9d7529..e236c2201 100644 --- a/server/compose/envoy/store_encode.gen.go +++ b/server/compose/envoy/store_encode.gen.go @@ -241,10 +241,12 @@ func (e StoreEncoder) encodeChart(ctx context.Context, p envoyx.EncodeParams, s } // Flush to the DB - err = store.UpsertComposeChart(ctx, s, n.Resource.(*types.Chart)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Chart") - return + if !n.Evaluated.Skip { + err = store.UpsertComposeChart(ctx, s, n.Resource.(*types.Chart)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Chart") + return + } } // Handle resources nested under it @@ -292,10 +294,6 @@ func (e StoreEncoder) matchupCharts(ctx context.Context, s store.Storer, uu map[ var aux *types.Chart var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -457,10 +455,12 @@ func (e StoreEncoder) encodeModule(ctx context.Context, p envoyx.EncodeParams, s } // Flush to the DB - err = store.UpsertComposeModule(ctx, s, n.Resource.(*types.Module)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Module") - return + if !n.Evaluated.Skip { + err = store.UpsertComposeModule(ctx, s, n.Resource.(*types.Module)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Module") + return + } } // Handle resources nested under it @@ -524,10 +524,6 @@ func (e StoreEncoder) matchupModules(ctx context.Context, s store.Storer, uu map var aux *types.Module var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -692,10 +688,12 @@ func (e StoreEncoder) encodeModuleField(ctx context.Context, p envoyx.EncodePara e.sanitizeModuleFieldBeforeSave(n.Resource.(*types.ModuleField)) // Flush to the DB - err = store.UpsertComposeModuleField(ctx, s, n.Resource.(*types.ModuleField)) - if err != nil { - err = errors.Wrap(err, "failed to upsert ModuleField") - return + if !n.Evaluated.Skip { + err = store.UpsertComposeModuleField(ctx, s, n.Resource.(*types.ModuleField)) + if err != nil { + err = errors.Wrap(err, "failed to upsert ModuleField") + return + } } // Handle resources nested under it @@ -743,10 +741,6 @@ func (e StoreEncoder) matchupModuleFields(ctx context.Context, s store.Storer, u var aux *types.ModuleField var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -907,10 +901,12 @@ func (e StoreEncoder) encodeNamespace(ctx context.Context, p envoyx.EncodeParams } // Flush to the DB - err = store.UpsertComposeNamespace(ctx, s, n.Resource.(*types.Namespace)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Namespace") - return + if !n.Evaluated.Skip { + err = store.UpsertComposeNamespace(ctx, s, n.Resource.(*types.Namespace)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Namespace") + return + } } // Handle resources nested under it @@ -976,10 +972,6 @@ func (e StoreEncoder) matchupNamespaces(ctx context.Context, s store.Storer, uu var aux *types.Namespace var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -1140,10 +1132,12 @@ func (e StoreEncoder) encodePage(ctx context.Context, p envoyx.EncodeParams, s s } // Flush to the DB - err = store.UpsertComposePage(ctx, s, n.Resource.(*types.Page)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Page") - return + if !n.Evaluated.Skip { + err = store.UpsertComposePage(ctx, s, n.Resource.(*types.Page)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Page") + return + } } // Handle resources nested under it @@ -1191,10 +1185,6 @@ func (e StoreEncoder) matchupPages(ctx context.Context, s store.Storer, uu map[i var aux *types.Page var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { diff --git a/server/compose/envoy/yaml_decode.gen.go b/server/compose/envoy/yaml_decode.gen.go index 114adf10a..4ea74b5a1 100644 --- a/server/compose/envoy/yaml_decode.gen.go +++ b/server/compose/envoy/yaml_decode.gen.go @@ -386,7 +386,7 @@ func (d *auxYamlDoc) unmarshalChartNode(dctx documentContext, n *yaml.Node, meta // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -427,6 +427,9 @@ func (d *auxYamlDoc) unmarshalChartNode(dctx documentContext, n *yaml.Node, meta } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -437,6 +440,12 @@ func (d *auxYamlDoc) unmarshalChartNode(dctx documentContext, n *yaml.Node, meta if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -461,7 +470,13 @@ func (d *auxYamlDoc) unmarshalChartNode(dctx documentContext, n *yaml.Node, meta Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -476,6 +491,14 @@ func (d *auxYamlDoc) unmarshalChartNode(dctx documentContext, n *yaml.Node, meta Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -676,7 +699,7 @@ func (d *auxYamlDoc) unmarshalModuleNode(dctx documentContext, n *yaml.Node, met // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -739,6 +762,9 @@ func (d *auxYamlDoc) unmarshalModuleNode(dctx documentContext, n *yaml.Node, met } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -749,6 +775,12 @@ func (d *auxYamlDoc) unmarshalModuleNode(dctx documentContext, n *yaml.Node, met if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -778,7 +810,13 @@ func (d *auxYamlDoc) unmarshalModuleNode(dctx documentContext, n *yaml.Node, met Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -793,6 +831,14 @@ func (d *auxYamlDoc) unmarshalModuleNode(dctx documentContext, n *yaml.Node, met Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -1034,7 +1080,7 @@ func (d *auxYamlDoc) unmarshalModuleFieldNode(dctx documentContext, n *yaml.Node // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -1075,6 +1121,9 @@ func (d *auxYamlDoc) unmarshalModuleFieldNode(dctx documentContext, n *yaml.Node } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -1085,6 +1134,12 @@ func (d *auxYamlDoc) unmarshalModuleFieldNode(dctx documentContext, n *yaml.Node if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -1109,7 +1164,13 @@ func (d *auxYamlDoc) unmarshalModuleFieldNode(dctx documentContext, n *yaml.Node Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -1124,6 +1185,14 @@ func (d *auxYamlDoc) unmarshalModuleFieldNode(dctx documentContext, n *yaml.Node Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -1289,7 +1358,7 @@ func (d *auxYamlDoc) unmarshalNamespaceNode(dctx documentContext, n *yaml.Node, // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -1386,6 +1455,9 @@ func (d *auxYamlDoc) unmarshalNamespaceNode(dctx documentContext, n *yaml.Node, } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -1396,6 +1468,12 @@ func (d *auxYamlDoc) unmarshalNamespaceNode(dctx documentContext, n *yaml.Node, if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -1420,7 +1498,13 @@ func (d *auxYamlDoc) unmarshalNamespaceNode(dctx documentContext, n *yaml.Node, Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -1435,6 +1519,14 @@ func (d *auxYamlDoc) unmarshalNamespaceNode(dctx documentContext, n *yaml.Node, Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -1722,7 +1814,7 @@ func (d *auxYamlDoc) unmarshalPageNode(dctx documentContext, n *yaml.Node, meta // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -1769,13 +1861,16 @@ func (d *auxYamlDoc) unmarshalPageNode(dctx documentContext, n *yaml.Node, meta a.References = make(map[string]envoyx.Ref) } - a.References["PageID"] = envoyx.Ref{ + a.References["SelfID"] = envoyx.Ref{ ResourceType: types.PageResourceType, Identifiers: ii, Scope: scope, } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -1786,6 +1881,12 @@ func (d *auxYamlDoc) unmarshalPageNode(dctx documentContext, n *yaml.Node, meta if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -1810,7 +1911,13 @@ func (d *auxYamlDoc) unmarshalPageNode(dctx documentContext, n *yaml.Node, meta Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -1825,6 +1932,14 @@ func (d *auxYamlDoc) unmarshalPageNode(dctx documentContext, n *yaml.Node, meta Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -1849,12 +1964,12 @@ func unmarshalDenyNode(n *yaml.Node) (out envoyx.NodeSet, err error) { func unmarshalRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { if y7s.IsMapping(n.Content[1]) { - out, err = unmarshalNestedRBACNode(n, acc) + out, err = unmarshalFlatRBACNode(n, acc) if err != nil { return } } else { - out, err = unmarshalFlatRBACNode(n, acc) + out, err = unmarshalNestedRBACNode(n, acc) if err != nil { return } @@ -1889,6 +2004,35 @@ func unmarshalRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err e // - read // - delete func unmarshalNestedRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { + return out, y7s.EachMap(n, func(role, op *yaml.Node) error { + out = append(out, &envoyx.Node{ + Resource: &rbac.Rule{ + Operation: op.Value, + Access: acc, + }, + ResourceType: rbac.RuleResourceType, + References: map[string]envoyx.Ref{ + "RoleID": { + // Providing resource type as plain text to reduce cross component references + ResourceType: "corteza::system:role", + Identifiers: envoyx.MakeIdentifiers(role.Value), + }, + }, + }) + return nil + }) +} + +// unmarshalFlatRBACNode handles RBAC rules when they are provided on the root level +// +// Example: +// +// allow: +// role1: +// corteza::system/: +// - users.search +// - users.create +func unmarshalFlatRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { // Handles role return out, y7s.EachMap(n, func(role, perm *yaml.Node) error { // Handles operations @@ -1917,35 +2061,6 @@ func unmarshalNestedRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, }) } -// unmarshalFlatRBACNode handles RBAC rules when they are provided on the root level -// -// Example: -// -// allow: -// role1: -// corteza::system/: -// - users.search -// - users.create -func unmarshalFlatRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { - return out, y7s.EachMap(n, func(role, op *yaml.Node) error { - out = append(out, &envoyx.Node{ - Resource: &rbac.Rule{ - Operation: op.Value, - Access: acc, - }, - ResourceType: rbac.RuleResourceType, - References: map[string]envoyx.Ref{ - "RoleID": { - // Providing resource type as plain text to reduce cross component references - ResourceType: "corteza::system:role", - Identifiers: envoyx.MakeIdentifiers(role.Value), - }, - }, - }) - return nil - }) -} - // // // // // // // // // // // // // // // // // // // // // // // // // // i18n unmarshal logic // // // // // // // // // // // // // // // // // // // // // // // // // diff --git a/server/compose/page.cue b/server/compose/page.cue index ab69122e4..4c2122d35 100644 --- a/server/compose/page.cue +++ b/server/compose/page.cue @@ -147,6 +147,7 @@ page: { supportMappedInput: true mappedField: "Handle" }] + extendedResourceRefIdent: "SelfID" } store: { extendedFilterBuilder: true diff --git a/server/system/envoy/store_encode.gen.go b/server/system/envoy/store_encode.gen.go index 4928346a4..83fce2b23 100644 --- a/server/system/envoy/store_encode.gen.go +++ b/server/system/envoy/store_encode.gen.go @@ -274,10 +274,12 @@ func (e StoreEncoder) encodeApplication(ctx context.Context, p envoyx.EncodePara } // Flush to the DB - err = store.UpsertApplication(ctx, s, n.Resource.(*types.Application)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Application") - return + if !n.Evaluated.Skip { + err = store.UpsertApplication(ctx, s, n.Resource.(*types.Application)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Application") + return + } } // Handle resources nested under it @@ -324,10 +326,6 @@ func (e StoreEncoder) matchupApplications(ctx context.Context, s store.Storer, u var aux *types.Application var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -488,10 +486,12 @@ func (e StoreEncoder) encodeApigwRoute(ctx context.Context, p envoyx.EncodeParam } // Flush to the DB - err = store.UpsertApigwRoute(ctx, s, n.Resource.(*types.ApigwRoute)) - if err != nil { - err = errors.Wrap(err, "failed to upsert ApigwRoute") - return + if !n.Evaluated.Skip { + err = store.UpsertApigwRoute(ctx, s, n.Resource.(*types.ApigwRoute)) + if err != nil { + err = errors.Wrap(err, "failed to upsert ApigwRoute") + return + } } // Handle resources nested under it @@ -538,10 +538,6 @@ func (e StoreEncoder) matchupApigwRoutes(ctx context.Context, s store.Storer, uu var aux *types.ApigwRoute var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -702,10 +698,12 @@ func (e StoreEncoder) encodeApigwFilter(ctx context.Context, p envoyx.EncodePara } // Flush to the DB - err = store.UpsertApigwFilter(ctx, s, n.Resource.(*types.ApigwFilter)) - if err != nil { - err = errors.Wrap(err, "failed to upsert ApigwFilter") - return + if !n.Evaluated.Skip { + err = store.UpsertApigwFilter(ctx, s, n.Resource.(*types.ApigwFilter)) + if err != nil { + err = errors.Wrap(err, "failed to upsert ApigwFilter") + return + } } // Handle resources nested under it @@ -752,10 +750,6 @@ func (e StoreEncoder) matchupApigwFilters(ctx context.Context, s store.Storer, u var aux *types.ApigwFilter var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -916,10 +910,12 @@ func (e StoreEncoder) encodeAuthClient(ctx context.Context, p envoyx.EncodeParam } // Flush to the DB - err = store.UpsertAuthClient(ctx, s, n.Resource.(*types.AuthClient)) - if err != nil { - err = errors.Wrap(err, "failed to upsert AuthClient") - return + if !n.Evaluated.Skip { + err = store.UpsertAuthClient(ctx, s, n.Resource.(*types.AuthClient)) + if err != nil { + err = errors.Wrap(err, "failed to upsert AuthClient") + return + } } // Handle resources nested under it @@ -967,10 +963,6 @@ func (e StoreEncoder) matchupAuthClients(ctx context.Context, s store.Storer, uu var aux *types.AuthClient var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -1131,10 +1123,12 @@ func (e StoreEncoder) encodeQueue(ctx context.Context, p envoyx.EncodeParams, s } // Flush to the DB - err = store.UpsertQueue(ctx, s, n.Resource.(*types.Queue)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Queue") - return + if !n.Evaluated.Skip { + err = store.UpsertQueue(ctx, s, n.Resource.(*types.Queue)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Queue") + return + } } // Handle resources nested under it @@ -1182,10 +1176,6 @@ func (e StoreEncoder) matchupQueues(ctx context.Context, s store.Storer, uu map[ var aux *types.Queue var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -1346,10 +1336,12 @@ func (e StoreEncoder) encodeReport(ctx context.Context, p envoyx.EncodeParams, s } // Flush to the DB - err = store.UpsertReport(ctx, s, n.Resource.(*types.Report)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Report") - return + if !n.Evaluated.Skip { + err = store.UpsertReport(ctx, s, n.Resource.(*types.Report)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Report") + return + } } // Handle resources nested under it @@ -1397,10 +1389,6 @@ func (e StoreEncoder) matchupReports(ctx context.Context, s store.Storer, uu map var aux *types.Report var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -1561,10 +1549,12 @@ func (e StoreEncoder) encodeRole(ctx context.Context, p envoyx.EncodeParams, s s } // Flush to the DB - err = store.UpsertRole(ctx, s, n.Resource.(*types.Role)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Role") - return + if !n.Evaluated.Skip { + err = store.UpsertRole(ctx, s, n.Resource.(*types.Role)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Role") + return + } } // Handle resources nested under it @@ -1612,10 +1602,6 @@ func (e StoreEncoder) matchupRoles(ctx context.Context, s store.Storer, uu map[i var aux *types.Role var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -1776,10 +1762,12 @@ func (e StoreEncoder) encodeTemplate(ctx context.Context, p envoyx.EncodeParams, } // Flush to the DB - err = store.UpsertTemplate(ctx, s, n.Resource.(*types.Template)) - if err != nil { - err = errors.Wrap(err, "failed to upsert Template") - return + if !n.Evaluated.Skip { + err = store.UpsertTemplate(ctx, s, n.Resource.(*types.Template)) + if err != nil { + err = errors.Wrap(err, "failed to upsert Template") + return + } } // Handle resources nested under it @@ -1827,10 +1815,6 @@ func (e StoreEncoder) matchupTemplates(ctx context.Context, s store.Storer, uu m var aux *types.Template var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -1991,10 +1975,12 @@ func (e StoreEncoder) encodeUser(ctx context.Context, p envoyx.EncodeParams, s s } // Flush to the DB - err = store.UpsertUser(ctx, s, n.Resource.(*types.User)) - if err != nil { - err = errors.Wrap(err, "failed to upsert User") - return + if !n.Evaluated.Skip { + err = store.UpsertUser(ctx, s, n.Resource.(*types.User)) + if err != nil { + err = errors.Wrap(err, "failed to upsert User") + return + } } // Handle resources nested under it @@ -2042,10 +2028,6 @@ func (e StoreEncoder) matchupUsers(ctx context.Context, s store.Storer, uu map[i var aux *types.User var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -2206,10 +2188,12 @@ func (e StoreEncoder) encodeDalConnection(ctx context.Context, p envoyx.EncodePa } // Flush to the DB - err = store.UpsertDalConnection(ctx, s, n.Resource.(*types.DalConnection)) - if err != nil { - err = errors.Wrap(err, "failed to upsert DalConnection") - return + if !n.Evaluated.Skip { + err = store.UpsertDalConnection(ctx, s, n.Resource.(*types.DalConnection)) + if err != nil { + err = errors.Wrap(err, "failed to upsert DalConnection") + return + } } // Handle resources nested under it @@ -2257,10 +2241,6 @@ func (e StoreEncoder) matchupDalConnections(ctx context.Context, s store.Storer, var aux *types.DalConnection var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { @@ -2421,10 +2401,12 @@ func (e StoreEncoder) encodeDalSensitivityLevel(ctx context.Context, p envoyx.En } // Flush to the DB - err = store.UpsertDalSensitivityLevel(ctx, s, n.Resource.(*types.DalSensitivityLevel)) - if err != nil { - err = errors.Wrap(err, "failed to upsert DalSensitivityLevel") - return + if !n.Evaluated.Skip { + err = store.UpsertDalSensitivityLevel(ctx, s, n.Resource.(*types.DalSensitivityLevel)) + if err != nil { + err = errors.Wrap(err, "failed to upsert DalSensitivityLevel") + return + } } // Handle resources nested under it @@ -2472,10 +2454,6 @@ func (e StoreEncoder) matchupDalSensitivityLevels(ctx context.Context, s store.S var aux *types.DalSensitivityLevel var ok bool for i, n := range nn { - scope := scopes[i] - if scope == nil { - continue - } for _, idf := range n.Identifiers.Slice { if id, err := strconv.ParseUint(idf, 10, 64); err == nil { diff --git a/server/system/envoy/yaml_decode.gen.go b/server/system/envoy/yaml_decode.gen.go index 7af5e96fe..30103e0f2 100644 --- a/server/system/envoy/yaml_decode.gen.go +++ b/server/system/envoy/yaml_decode.gen.go @@ -446,7 +446,7 @@ func (d *auxYamlDoc) unmarshalApplicationNode(dctx documentContext, n *yaml.Node // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -487,6 +487,9 @@ func (d *auxYamlDoc) unmarshalApplicationNode(dctx documentContext, n *yaml.Node } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -497,6 +500,12 @@ func (d *auxYamlDoc) unmarshalApplicationNode(dctx documentContext, n *yaml.Node if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -519,7 +528,13 @@ func (d *auxYamlDoc) unmarshalApplicationNode(dctx documentContext, n *yaml.Node Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -534,6 +549,14 @@ func (d *auxYamlDoc) unmarshalApplicationNode(dctx documentContext, n *yaml.Node Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -759,7 +782,7 @@ func (d *auxYamlDoc) unmarshalApigwRouteNode(dctx documentContext, n *yaml.Node, // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -808,6 +831,9 @@ func (d *auxYamlDoc) unmarshalApigwRouteNode(dctx documentContext, n *yaml.Node, } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -818,6 +844,12 @@ func (d *auxYamlDoc) unmarshalApigwRouteNode(dctx documentContext, n *yaml.Node, if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -840,7 +872,13 @@ func (d *auxYamlDoc) unmarshalApigwRouteNode(dctx documentContext, n *yaml.Node, Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -855,6 +893,14 @@ func (d *auxYamlDoc) unmarshalApigwRouteNode(dctx documentContext, n *yaml.Node, Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -1028,7 +1074,7 @@ func (d *auxYamlDoc) unmarshalApigwFilterNode(dctx documentContext, n *yaml.Node // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -1069,6 +1115,9 @@ func (d *auxYamlDoc) unmarshalApigwFilterNode(dctx documentContext, n *yaml.Node } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -1079,6 +1128,12 @@ func (d *auxYamlDoc) unmarshalApigwFilterNode(dctx documentContext, n *yaml.Node if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -1336,7 +1391,7 @@ func (d *auxYamlDoc) unmarshalAuthClientNode(dctx documentContext, n *yaml.Node, // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -1377,6 +1432,9 @@ func (d *auxYamlDoc) unmarshalAuthClientNode(dctx documentContext, n *yaml.Node, } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -1387,6 +1445,12 @@ func (d *auxYamlDoc) unmarshalAuthClientNode(dctx documentContext, n *yaml.Node, if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -1409,7 +1473,13 @@ func (d *auxYamlDoc) unmarshalAuthClientNode(dctx documentContext, n *yaml.Node, Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -1424,6 +1494,14 @@ func (d *auxYamlDoc) unmarshalAuthClientNode(dctx documentContext, n *yaml.Node, Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -1624,7 +1702,7 @@ func (d *auxYamlDoc) unmarshalQueueNode(dctx documentContext, n *yaml.Node, meta // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -1665,6 +1743,9 @@ func (d *auxYamlDoc) unmarshalQueueNode(dctx documentContext, n *yaml.Node, meta } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -1675,6 +1756,12 @@ func (d *auxYamlDoc) unmarshalQueueNode(dctx documentContext, n *yaml.Node, meta if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -1697,7 +1784,13 @@ func (d *auxYamlDoc) unmarshalQueueNode(dctx documentContext, n *yaml.Node, meta Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -1712,6 +1805,14 @@ func (d *auxYamlDoc) unmarshalQueueNode(dctx documentContext, n *yaml.Node, meta Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -1931,7 +2032,7 @@ func (d *auxYamlDoc) unmarshalReportNode(dctx documentContext, n *yaml.Node, met // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -1972,6 +2073,9 @@ func (d *auxYamlDoc) unmarshalReportNode(dctx documentContext, n *yaml.Node, met } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -1982,6 +2086,12 @@ func (d *auxYamlDoc) unmarshalReportNode(dctx documentContext, n *yaml.Node, met if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -2004,7 +2114,13 @@ func (d *auxYamlDoc) unmarshalReportNode(dctx documentContext, n *yaml.Node, met Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -2019,6 +2135,14 @@ func (d *auxYamlDoc) unmarshalReportNode(dctx documentContext, n *yaml.Node, met Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -2162,7 +2286,7 @@ func (d *auxYamlDoc) unmarshalRoleNode(dctx documentContext, n *yaml.Node, meta // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -2203,6 +2327,9 @@ func (d *auxYamlDoc) unmarshalRoleNode(dctx documentContext, n *yaml.Node, meta } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -2213,6 +2340,12 @@ func (d *auxYamlDoc) unmarshalRoleNode(dctx documentContext, n *yaml.Node, meta if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -2235,7 +2368,13 @@ func (d *auxYamlDoc) unmarshalRoleNode(dctx documentContext, n *yaml.Node, meta Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -2250,6 +2389,14 @@ func (d *auxYamlDoc) unmarshalRoleNode(dctx documentContext, n *yaml.Node, meta Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -2412,7 +2559,7 @@ func (d *auxYamlDoc) unmarshalTemplateNode(dctx documentContext, n *yaml.Node, m // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -2453,6 +2600,9 @@ func (d *auxYamlDoc) unmarshalTemplateNode(dctx documentContext, n *yaml.Node, m } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -2463,6 +2613,12 @@ func (d *auxYamlDoc) unmarshalTemplateNode(dctx documentContext, n *yaml.Node, m if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -2485,7 +2641,13 @@ func (d *auxYamlDoc) unmarshalTemplateNode(dctx documentContext, n *yaml.Node, m Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -2500,6 +2662,14 @@ func (d *auxYamlDoc) unmarshalTemplateNode(dctx documentContext, n *yaml.Node, m Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -2662,7 +2832,7 @@ func (d *auxYamlDoc) unmarshalUserNode(dctx documentContext, n *yaml.Node, meta // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -2703,6 +2873,9 @@ func (d *auxYamlDoc) unmarshalUserNode(dctx documentContext, n *yaml.Node, meta } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -2713,6 +2886,12 @@ func (d *auxYamlDoc) unmarshalUserNode(dctx documentContext, n *yaml.Node, meta if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -2735,7 +2914,13 @@ func (d *auxYamlDoc) unmarshalUserNode(dctx documentContext, n *yaml.Node, meta Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -2750,6 +2935,14 @@ func (d *auxYamlDoc) unmarshalUserNode(dctx documentContext, n *yaml.Node, meta Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -2950,7 +3143,7 @@ func (d *auxYamlDoc) unmarshalDalConnectionNode(dctx documentContext, n *yaml.No // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -2991,6 +3184,9 @@ func (d *auxYamlDoc) unmarshalDalConnectionNode(dctx documentContext, n *yaml.No } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -3001,6 +3197,12 @@ func (d *auxYamlDoc) unmarshalDalConnectionNode(dctx documentContext, n *yaml.No if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -3023,7 +3225,13 @@ func (d *auxYamlDoc) unmarshalDalConnectionNode(dctx documentContext, n *yaml.No Config: envoyConfig, } // Update RBAC resource nodes with references regarding the resource + rres := r.RbacResource() for _, rn := range rbacNodes { + aux := rn.Resource.(*rbac.Rule) + if aux.Resource == "" { + aux.Resource = rres + } + // Since the rule belongs to the resource, it will have the same // subset of references as the parent resource. rn.References = envoyx.MergeRefs(rn.References, a.References) @@ -3038,6 +3246,14 @@ func (d *auxYamlDoc) unmarshalDalConnectionNode(dctx documentContext, n *yaml.No Identifiers: a.Identifiers, Scope: scope, } + + for _, r := range rn.References { + if r.Scope.IsEmpty() { + continue + } + rn.Scope = r.Scope + break + } } // Put it all together... @@ -3221,7 +3437,7 @@ func (d *auxYamlDoc) unmarshalDalSensitivityLevelNode(dctx documentContext, n *y // Apply the scope to all of the references of the same type for k, ref := range refs { - if ref.ResourceType != scope.ResourceType { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { continue } ref.Scope = scope @@ -3262,6 +3478,9 @@ func (d *auxYamlDoc) unmarshalDalSensitivityLevelNode(dctx documentContext, n *y } for f, ref := range a.References { + if !strings.HasPrefix(ref.ResourceType, "corteza::compose") { + continue + } ref.Scope = scope a.References[f] = ref } @@ -3272,6 +3491,12 @@ func (d *auxYamlDoc) unmarshalDalSensitivityLevelNode(dctx documentContext, n *y if strings.Contains(f, ".") { continue } + + // Only assume refs if they're not yet set + if _, ok := a.References[f]; ok { + continue + } + a.References[f] = ref } } @@ -3315,12 +3540,12 @@ func unmarshalDenyNode(n *yaml.Node) (out envoyx.NodeSet, err error) { func unmarshalRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { if y7s.IsMapping(n.Content[1]) { - out, err = unmarshalNestedRBACNode(n, acc) + out, err = unmarshalFlatRBACNode(n, acc) if err != nil { return } } else { - out, err = unmarshalFlatRBACNode(n, acc) + out, err = unmarshalNestedRBACNode(n, acc) if err != nil { return } @@ -3355,6 +3580,35 @@ func unmarshalRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err e // - read // - delete func unmarshalNestedRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { + return out, y7s.EachMap(n, func(role, op *yaml.Node) error { + out = append(out, &envoyx.Node{ + Resource: &rbac.Rule{ + Operation: op.Value, + Access: acc, + }, + ResourceType: rbac.RuleResourceType, + References: map[string]envoyx.Ref{ + "RoleID": { + // Providing resource type as plain text to reduce cross component references + ResourceType: "corteza::system:role", + Identifiers: envoyx.MakeIdentifiers(role.Value), + }, + }, + }) + return nil + }) +} + +// unmarshalFlatRBACNode handles RBAC rules when they are provided on the root level +// +// Example: +// +// allow: +// role1: +// corteza::system/: +// - users.search +// - users.create +func unmarshalFlatRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { // Handles role return out, y7s.EachMap(n, func(role, perm *yaml.Node) error { // Handles operations @@ -3383,35 +3637,6 @@ func unmarshalNestedRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, }) } -// unmarshalFlatRBACNode handles RBAC rules when they are provided on the root level -// -// Example: -// -// allow: -// role1: -// corteza::system/: -// - users.search -// - users.create -func unmarshalFlatRBACNode(n *yaml.Node, acc rbac.Access) (out envoyx.NodeSet, err error) { - return out, y7s.EachMap(n, func(role, op *yaml.Node) error { - out = append(out, &envoyx.Node{ - Resource: &rbac.Rule{ - Operation: op.Value, - Access: acc, - }, - ResourceType: rbac.RuleResourceType, - References: map[string]envoyx.Ref{ - "RoleID": { - // Providing resource type as plain text to reduce cross component references - ResourceType: "corteza::system:role", - Identifiers: envoyx.MakeIdentifiers(role.Value), - }, - }, - }) - return nil - }) -} - // // // // // // // // // // // // // // // // // // // // // // // // // // i18n unmarshal logic // // // // // // // // // // // // // // // // // // // // // // // // //