diff --git a/pkg/envoy/resource/compose_record.go b/pkg/envoy/resource/compose_record.go index d06a4189c..91f35f0d5 100644 --- a/pkg/envoy/resource/compose_record.go +++ b/pkg/envoy/resource/compose_record.go @@ -9,7 +9,7 @@ type ( ID string Values map[string]string SysValues map[string]string - RefUser map[string]string + RefUsers map[string]string } ComposeRecordRawSet []*ComposeRecordRaw @@ -40,10 +40,6 @@ func NewComposeRecordSet(w crsWalker, nsRef, modRef string) *ComposeRecord { r.AddIdentifier(identifiers(modRef)...) - // for _, u := range userRef { - // r.AddRef(USER_RESOURCE_TYPE, u) - // } - r.NsRef = r.AddRef(COMPOSE_NAMESPACE_RESOURCE_TYPE, nsRef) r.ModRef = r.AddRef(COMPOSE_MODULE_RESOURCE_TYPE, modRef) diff --git a/pkg/envoy/store/compose_record.go b/pkg/envoy/store/compose_record.go index 90705adcb..3313758ff 100644 --- a/pkg/envoy/store/compose_record.go +++ b/pkg/envoy/store/compose_record.go @@ -52,15 +52,17 @@ func (n *composeRecordState) Prepare(ctx context.Context, s store.Storer, state if err != nil { return err } - if n.relMod == nil { - return composeModuleErrUnresolved(n.res.ModRef.Identifiers) + if n.relMod != nil { + // Preload existing fields + n.relMod.Fields, err = findComposeModuleFieldsS(ctx, s, n.relMod) + if err != nil { + return err + } } + } - // Preload existing fields - n.relMod.Fields, err = findComposeModuleFieldsS(ctx, s, n.relMod) - if err != nil { - return err - } + if n.relMod == nil { + return composeModuleErrUnresolved(n.res.ModRef.Identifiers) } // Add missing refs @@ -148,27 +150,10 @@ func (n *composeRecordState) Encode(ctx context.Context, s store.Storer, state * } // Sys values - // // @todo - for k, v := range r.SysValues { - if v == "" { - continue - } - - switch k { - case "createdAt": - // @todo set time - rec.CreatedAt = time.Now() - - case "updatedAt": - // @todo set time - rec.UpdatedAt = nil - - case "deletedAt": - // @todo set time - rec.DeletedAt = nil - } - } + // + // for k, v := range r.SysValues { + // } rvs := make(types.RecordValueSet, 0, len(r.Values)) for k, v := range r.Values { @@ -182,8 +167,11 @@ func (n *composeRecordState) Encode(ctx context.Context, s store.Storer, state * rvs = append(rvs, rv) } - // @todo validator rec.Values = rvSanitizer.Run(mod, rvs) + rve := rvValidator.Run(ctx, s, mod, rec) + if !rve.IsValid() { + return rve + } // Create a new record if !exists { diff --git a/pkg/envoy/tests/main_test.go b/pkg/envoy/tests/main_test.go index 0d01144ee..b2f992fbb 100644 --- a/pkg/envoy/tests/main_test.go +++ b/pkg/envoy/tests/main_test.go @@ -102,6 +102,20 @@ func storeModule(ctx context.Context, s store.Storer, nsID, modID uint64, ss ... return store.CreateComposeModule(ctx, s, mod) } +func storeModuleField(ctx context.Context, s store.Storer, modID, fieldID uint64, ss ...string) error { + f := &types.ModuleField{ + ID: fieldID, + ModuleID: modID, + } + if len(ss) > 0 { + f.Name = ss[0] + } + if len(ss) > 1 { + f.Label = ss[1] + } + return store.CreateComposeModuleField(ctx, s, f) +} + func storeRole(ctx context.Context, s store.Storer, rID uint64, ss ...string) error { r := &stypes.Role{ ID: rID, diff --git a/pkg/envoy/tests/simple_test.go b/pkg/envoy/tests/simple_test.go index 8b84a0bac..8933e4f67 100644 --- a/pkg/envoy/tests/simple_test.go +++ b/pkg/envoy/tests/simple_test.go @@ -436,6 +436,83 @@ func TestSimpleCases(t *testing.T) { req.Len(rr, 3) }, }, + + { + name: "simple records; no ns", + suite: "simple", + file: "records_no_ns", + pre: func() (err error) { + return ce( + s.TruncateComposeNamespaces(ctx), + s.TruncateComposeModules(ctx), + ) + }, + post: func(req *require.Assertions, err error) { + req.Error(err) + + req.True(strings.Contains(err.Error(), "prepare compose record")) + req.True(strings.Contains(err.Error(), "compose namespace unresolved")) + }, + check: func(req *require.Assertions) {}, + }, + + { + name: "simple records; no mod", + suite: "simple", + file: "records_no_mod", + pre: func() (err error) { + return ce( + s.TruncateComposeNamespaces(ctx), + s.TruncateComposeModules(ctx), + + storeNamespace(ctx, s, 100, "ns1"), + ) + }, + post: func(req *require.Assertions, err error) { + req.Error(err) + + req.True(strings.Contains(err.Error(), "prepare compose record")) + req.True(strings.Contains(err.Error(), "compose module unresolved")) + }, + check: func(req *require.Assertions) {}, + }, + + { + name: "simple records", + suite: "simple", + file: "records", + pre: func() (err error) { + return ce( + s.TruncateComposeNamespaces(ctx), + s.TruncateComposeModules(ctx), + + storeNamespace(ctx, s, 100, "ns1"), + storeModule(ctx, s, 100, 200, "mod1"), + storeModuleField(ctx, s, 200, 300, "f1"), + ) + }, + post: func(req *require.Assertions, err error) { + req.NoError(err) + }, + check: func(req *require.Assertions) { + m, err := store.LookupComposeModuleByID(ctx, s, 200) + req.NoError(err) + req.NotNil(m) + + rr, _, err := store.SearchComposeRecords(ctx, s, m, types.RecordFilter{ModuleID: m.ID, NamespaceID: m.NamespaceID}) + req.NoError(err) + req.NotNil(rr) + req.Len(rr, 1) + + r := rr[0] + req.Equal(uint64(100), r.NamespaceID) + req.Equal(uint64(200), r.ModuleID) + + req.Len(r.Values, 1) + v := r.Values[0] + req.Equal("v1", v.Value) + }, + }, } for _, c := range cases { diff --git a/pkg/envoy/tests/testdata/simple/records.yaml b/pkg/envoy/tests/testdata/simple/records.yaml new file mode 100644 index 000000000..f494433da --- /dev/null +++ b/pkg/envoy/tests/testdata/simple/records.yaml @@ -0,0 +1,5 @@ +namespace: ns1 +records: + mod1: + - values: + f1: "v1" diff --git a/pkg/envoy/tests/testdata/simple/records_no_mod.yaml b/pkg/envoy/tests/testdata/simple/records_no_mod.yaml new file mode 100644 index 000000000..ea605bc7d --- /dev/null +++ b/pkg/envoy/tests/testdata/simple/records_no_mod.yaml @@ -0,0 +1,5 @@ +namespace: ns1 +records: + notThere: + - values: + f1: "v1" diff --git a/pkg/envoy/tests/testdata/simple/records_no_ns.yaml b/pkg/envoy/tests/testdata/simple/records_no_ns.yaml new file mode 100644 index 000000000..bbbbb857a --- /dev/null +++ b/pkg/envoy/tests/testdata/simple/records_no_ns.yaml @@ -0,0 +1,5 @@ +namespace: notThere +records: + mod1: + - values: + f1: "v1" diff --git a/pkg/envoy/yaml/compose_record.go b/pkg/envoy/yaml/compose_record.go index 5f1e732e6..89abb0170 100644 --- a/pkg/envoy/yaml/compose_record.go +++ b/pkg/envoy/yaml/compose_record.go @@ -10,7 +10,6 @@ import ( type ( composeRecord struct { - // res *types.Record `yaml:",inline"` values map[string]string sysValues map[string]string @@ -29,9 +28,6 @@ type ( // UnmarshalYAML resolves set of record definitions, either sequence or map // // When resolving map, key is used as module handle -// -// { module-handle: [ { ... values ... } ] } -// [ { module: module-handle, ... values ... } ] func (wset *composeRecordSet) UnmarshalYAML(n *yaml.Node) error { return each(n, func(k, v *yaml.Node) (err error) { var ( @@ -102,7 +98,7 @@ func (wset composeRecordSet) MarshalEnvoy() ([]resource.Interface, error) { ID: res.values["id"], Values: res.values, - RefUser: res.refUser, + RefUsers: res.refUser, SysValues: res.sysValues, } recMap[res.refModule].rr = append(recMap[res.refModule].rr, r)