diff --git a/pkg/envoy/store/compose_chart.go b/pkg/envoy/store/compose_chart.go index f494cd77b..fa4a60b35 100644 --- a/pkg/envoy/store/compose_chart.go +++ b/pkg/envoy/store/compose_chart.go @@ -2,7 +2,6 @@ package store import ( "context" - "errors" "time" "github.com/cortezaproject/corteza-server/compose/types" @@ -43,7 +42,7 @@ func (n *composeChartState) Prepare(ctx context.Context, s store.Storer, state * return err } if n.relNS == nil { - return errors.New("@todo couldn't resolve namespace") + return composeNamespaceErrUnresolved(n.res.NsRef.Identifiers) } // Can't do anything else, since the NS doesn't yet exist @@ -58,6 +57,9 @@ func (n *composeChartState) Prepare(ctx context.Context, s store.Storer, state * if err != nil { return err } + if n.relMods[i] == nil { + return composeModuleErrUnresolved(mRef.Identifiers) + } } // Try to get the original chart @@ -96,7 +98,7 @@ func (n *composeChartState) Encode(ctx context.Context, s store.Storer, state *e res.NamespaceID = ns.ID } if res.NamespaceID <= 0 { - return errors.New("[chart] couldn't find related namespace; @todo error") + return composeNamespaceErrUnresolved(n.res.NsRef.Identifiers) } // Report modules @@ -106,7 +108,7 @@ func (n *composeChartState) Encode(ctx context.Context, s store.Storer, state *e mod = findComposeModuleR(state.ParentResources, n.res.ModRef[i].Identifiers) } if mod == nil || mod.ID <= 0 { - return errors.New("[chart] couldn't find related report module; @todo error") + return composeModuleErrUnresolved(n.res.ModRef[i].Identifiers) } r.ModuleID = mod.ID diff --git a/pkg/envoy/store/compose_module.go b/pkg/envoy/store/compose_module.go index 1406dde2b..d90719636 100644 --- a/pkg/envoy/store/compose_module.go +++ b/pkg/envoy/store/compose_module.go @@ -2,7 +2,7 @@ package store import ( "context" - "errors" + "fmt" "time" "github.com/cortezaproject/corteza-server/compose/types" @@ -28,6 +28,8 @@ func NewComposeModuleState(res *resource.ComposeModule, cfg *EncoderConfig) reso cfg: cfg, res: res, + + recFields: make(map[string]uint64), } } @@ -43,21 +45,23 @@ func (n *composeModuleState) Prepare(ctx context.Context, s store.Storer, state return err } if n.relNS == nil { - return errors.New("@todo couldn't resolve namespace") - } - - // Can't do anything else, since the NS doesn't yet exist - if n.relNS.ID <= 0 { - return nil + return composeNamespaceErrUnresolved(n.res.NsRef.Identifiers) } // Get related record field modules for _, r := range n.res.ModRef { - mod, err := findComposeModuleRS(ctx, s, n.relNS.ID, state.ParentResources, r.Identifiers) - if err != nil { - return err - } else if mod == nil { - return errors.New("[mod prepare] couldn't find related module; @todo error") + var mod *types.Module + if n.relNS.ID > 0 { + mod, err = findComposeModuleS(ctx, s, n.relNS.ID, makeGenericFilter(r.Identifiers)) + if err != nil { + return err + } + } + if mod == nil { + mod = findComposeModuleR(state.ParentResources, r.Identifiers) + } + if mod == nil { + return composeModuleErrUnresolvedRecordField(r.Identifiers) } for i := range r.Identifiers { @@ -65,6 +69,11 @@ func (n *composeModuleState) Prepare(ctx context.Context, s store.Storer, state } } + // Can't do anything else, since the NS doesn't yet exist + if n.relNS.ID <= 0 { + return nil + } + // Try to get the original module n.mod, err = findComposeModuleS(ctx, s, n.relNS.ID, makeGenericFilter(n.res.Identifiers())) if err != nil { @@ -113,7 +122,7 @@ func (n *composeModuleState) Encode(ctx context.Context, s store.Storer, state * } if res.NamespaceID <= 0 { - return errors.New("[module] couldn't find related namespace; @todo error") + return composeNamespaceErrUnresolved(n.res.NsRef.Identifiers) } // Fields @@ -128,9 +137,10 @@ func (n *composeModuleState) Encode(ctx context.Context, s store.Storer, state * refM := f.Options.String("module") mID := n.recFields[refM] if mID <= 0 { - mod := findComposeModuleR(state.ParentResources, resource.MakeIdentifiers(refM)) + ii := resource.MakeIdentifiers(refM) + mod := findComposeModuleR(state.ParentResources, ii) if mod == nil || mod.ID <= 0 { - return errors.New("[module field] couldn't find related module; @todo error") + return composeModuleErrUnresolvedRecordField(ii) } mID = mod.ID } @@ -321,3 +331,11 @@ func findComposeModuleFieldsS(ctx context.Context, s store.Storer, mod *types.Mo return ff, nil } + +func composeModuleErrUnresolved(ii resource.Identifiers) error { + return fmt.Errorf("compose module unresolved %v", ii.StringSlice()) +} + +func composeModuleErrUnresolvedRecordField(ii resource.Identifiers) error { + return fmt.Errorf("record module field unresolved %v", ii.StringSlice()) +} diff --git a/pkg/envoy/store/compose_namespace.go b/pkg/envoy/store/compose_namespace.go index d34dff31d..ccf95b7cd 100644 --- a/pkg/envoy/store/compose_namespace.go +++ b/pkg/envoy/store/compose_namespace.go @@ -2,6 +2,7 @@ package store import ( "context" + "fmt" "time" "github.com/cortezaproject/corteza-server/compose/types" @@ -169,3 +170,7 @@ func findComposeNamespaceR(rr resource.InterfaceSet, ii resource.Identifiers) (n return nil } + +func composeNamespaceErrUnresolved(ii resource.Identifiers) error { + return fmt.Errorf("compose namespace unresolved %v", ii.StringSlice()) +} diff --git a/pkg/envoy/store/compose_page.go b/pkg/envoy/store/compose_page.go index 65b6e3c15..fa05dd2cb 100644 --- a/pkg/envoy/store/compose_page.go +++ b/pkg/envoy/store/compose_page.go @@ -2,7 +2,6 @@ package store import ( "context" - "errors" "time" "github.com/cortezaproject/corteza-server/compose/types" @@ -43,7 +42,7 @@ func (n *composePageState) Prepare(ctx context.Context, s store.Storer, state *e return err } if n.relNS == nil { - return errors.New("@todo couldn't resolve namespace") + return composeNamespaceErrUnresolved(n.res.NsRef.Identifiers) } // Can't do anything else, since the NS doesn't yet exist @@ -59,7 +58,7 @@ func (n *composePageState) Prepare(ctx context.Context, s store.Storer, state *e return err } if n.relMod == nil { - return errors.New("@todo couldn't resolve module") + return composeModuleErrUnresolved(n.res.ModRef.Identifiers) } } @@ -100,7 +99,7 @@ func (n *composePageState) Encode(ctx context.Context, s store.Storer, state *en } if res.NamespaceID <= 0 { - return errors.New("[chart] couldn't find related namespace; @todo error") + return composeNamespaceErrUnresolved(n.res.NsRef.Identifiers) } // Module? diff --git a/pkg/envoy/store/compose_record.go b/pkg/envoy/store/compose_record.go index def24921d..bfa4049d5 100644 --- a/pkg/envoy/store/compose_record.go +++ b/pkg/envoy/store/compose_record.go @@ -2,7 +2,6 @@ package store import ( "context" - "errors" "strconv" "time" @@ -44,7 +43,7 @@ func (n *composeRecordState) Prepare(ctx context.Context, s store.Storer, state return err } if n.relNS == nil { - return errors.New("@todo couldn't resolve namespace") + return composeNamespaceErrUnresolved(n.res.NsRef.Identifiers) } n.relMod = findComposeModuleR(state.ParentResources, n.res.ModRef.Identifiers) @@ -54,7 +53,7 @@ func (n *composeRecordState) Prepare(ctx context.Context, s store.Storer, state return err } if n.relMod == nil { - return errors.New("@todo couldn't resolve module") + return composeModuleErrUnresolved(n.res.ModRef.Identifiers) } // Preload existing fields diff --git a/pkg/envoy/store/encoder.go b/pkg/envoy/store/encoder.go index 9d5b64a12..eccfaace6 100644 --- a/pkg/envoy/store/encoder.go +++ b/pkg/envoy/store/encoder.go @@ -3,12 +3,12 @@ package store import ( "context" "errors" - "sync" + "fmt" + "strings" "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" "github.com/cortezaproject/corteza-server/store" - "github.com/davecgh/go-spew/spew" ) const ( @@ -48,6 +48,11 @@ type ( } ) +var ( + ErrUnknownResource = errors.New("unknown resource") + ErrResourceStateUndefined = errors.New("undefined resource state") +) + // NewStoreEncoder initializes a fresh store encoder // // If no config is provided, it uses Skip as the default merge alg. @@ -94,7 +99,7 @@ func (se *storeEncoder) Prepare(ctx context.Context, ee ...*envoy.ResourceState) case *resource.ComposePage: err = f(NewComposePageState(res, se.cfg), e) - // System things + // System things case *resource.User: err = f(NewUserState(res, se.cfg), e) case *resource.Role: @@ -107,11 +112,11 @@ func (se *storeEncoder) Prepare(ctx context.Context, ee ...*envoy.ResourceState) err = f(NewRbacRuleState(res, se.cfg), e) default: - return errors.New("[encoder] unknown resource; @todo error") + err = ErrUnknownResource } if err != nil { - return err + return se.WrapError("prepare", e.Res, err) } } @@ -130,13 +135,20 @@ func (se *storeEncoder) Encode(ctx context.Context, rc envoy.Rc) error { state := se.state[e.Res] if state == nil { - return errors.New("Resource state not defined; @todo error") + err = ErrResourceStateUndefined + } else { + err = state.Encode(ctx, se.s, e) } - err = state.Encode(ctx, se.s, e) if err != nil { - return err + return se.WrapError("encode", e.Res, err) + } } }) } + +func (se *storeEncoder) WrapError(act string, res resource.Interface, err error) error { + rt := strings.Join(strings.Split(strings.TrimSpace(strings.TrimRight(res.ResourceType(), ":")), ":"), " ") + return fmt.Errorf("store encoder %s %s %v: %s", act, rt, res.Identifiers().StringSlice(), err) +} diff --git a/pkg/envoy/store/rbac_rule.go b/pkg/envoy/store/rbac_rule.go index 1d0e4bd8c..14d028854 100644 --- a/pkg/envoy/store/rbac_rule.go +++ b/pkg/envoy/store/rbac_rule.go @@ -2,7 +2,7 @@ package store import ( "context" - "errors" + "fmt" "github.com/cortezaproject/corteza-server/pkg/envoy" "github.com/cortezaproject/corteza-server/pkg/envoy/resource" @@ -51,7 +51,7 @@ func (n *rbacRuleState) Prepare(ctx context.Context, s store.Storer, state *envo return err } if n.relRole == nil { - return errors.New("[rbac rule] couldn't resolve role; @todo error") + return roleErrUnresolved(n.res.RefRole.Identifiers) } // Check for resource if there is any @@ -79,7 +79,7 @@ func (n *rbacRuleState) Encode(ctx context.Context, s store.Storer, state *envoy // Resource? if n.res.RefResource != nil { if ir, ok := n.relResource.(resource.IdentifiableInterface); !ok { - return errors.New("[rbac rule] resource not identifiable; @todo error") + return rbacResourceErrUnidentifiable(n.relResource.Identifiers()) } else { rule.Resource = rule.Resource.AppendID(ir.SysID()) } @@ -129,3 +129,7 @@ func (n *rbacRuleState) findResourceR(ctx context.Context, rr resource.Interface } return nil } + +func rbacResourceErrUnidentifiable(ii resource.Identifiers) error { + return fmt.Errorf("rbac resource unidentifiable %v", ii.StringSlice()) +} diff --git a/pkg/envoy/store/role.go b/pkg/envoy/store/role.go index afc3291fe..f5e60cf02 100644 --- a/pkg/envoy/store/role.go +++ b/pkg/envoy/store/role.go @@ -2,6 +2,7 @@ package store import ( "context" + "fmt" "time" "github.com/cortezaproject/corteza-server/pkg/envoy" @@ -163,3 +164,7 @@ func findRoleR(rr resource.InterfaceSet, ii resource.Identifiers) (rl *types.Rol return nil } + +func roleErrUnresolved(ii resource.Identifiers) error { + return fmt.Errorf("role unresolved %v", ii.StringSlice()) +}