Add page layout definitons to envoy
This commit is contained in:
committed by
Jože Fortun
parent
7bf2234daf
commit
9ec7139c84
@@ -10,9 +10,9 @@ import (
|
||||
[
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/envoy/rbac_references_$component.go.tpl"
|
||||
output: "pkg/envoy/resource/rbac_references_\(cmp.ident).gen.go"
|
||||
output: "pkg/envoyx/rbac_references_\(cmp.ident).gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
package: "envoyx"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza/server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
137
server/compose/envoy/store_decode.gen.go
generated
137
server/compose/envoy/store_decode.gen.go
generated
@@ -128,6 +128,17 @@ func (d StoreDecoder) decode(ctx context.Context, s store.Storer, dl dal.FullSer
|
||||
}
|
||||
out = append(out, aux...)
|
||||
|
||||
case types.PageLayoutResourceType:
|
||||
aux, err = d.decodePageLayout(ctx, s, dl, d.makePageLayoutFilter(scopedNodes[i], refNodes[i], wf.f))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, a := range aux {
|
||||
a.Identifiers = a.Identifiers.Merge(wf.f.Identifiers)
|
||||
a.References = envoyx.MergeRefs(a.References, refRefs[i])
|
||||
}
|
||||
out = append(out, aux...)
|
||||
|
||||
default:
|
||||
aux, err = d.extendDecoder(ctx, s, dl, wf.rt, refNodes[i], wf.f)
|
||||
if err != nil {
|
||||
@@ -629,6 +640,132 @@ func (d StoreDecoder) makePageFilter(scope *envoyx.Node, refs map[string]*envoyx
|
||||
return
|
||||
}
|
||||
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
// Functions for resource pageLayout
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
|
||||
func (d StoreDecoder) decodePageLayout(ctx context.Context, s store.Storer, dl dal.FullService, f types.PageLayoutFilter) (out envoyx.NodeSet, err error) {
|
||||
// @todo this might need to be improved.
|
||||
// Currently, no resource is vast enough to pose a problem.
|
||||
rr, _, err := store.SearchComposePageLayouts(ctx, s, f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, r := range rr {
|
||||
var n *envoyx.Node
|
||||
n, err = PageLayoutToEnvoyNode(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out = append(out, n)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func PageLayoutToEnvoyNode(r *types.PageLayout) (node *envoyx.Node, err error) {
|
||||
// Identifiers
|
||||
ii := envoyx.MakeIdentifiers(
|
||||
r.Handle,
|
||||
r.ID,
|
||||
)
|
||||
|
||||
// Handle references
|
||||
// Omit any non-defined values
|
||||
refs := map[string]envoyx.Ref{}
|
||||
if r.NamespaceID > 0 {
|
||||
refs["NamespaceID"] = envoyx.Ref{
|
||||
ResourceType: "corteza::compose:namespace",
|
||||
Identifiers: envoyx.MakeIdentifiers(r.NamespaceID),
|
||||
}
|
||||
}
|
||||
if r.OwnedBy > 0 {
|
||||
refs["OwnedBy"] = envoyx.Ref{
|
||||
ResourceType: "corteza::system:user",
|
||||
Identifiers: envoyx.MakeIdentifiers(r.OwnedBy),
|
||||
}
|
||||
}
|
||||
if r.PageID > 0 {
|
||||
refs["PageID"] = envoyx.Ref{
|
||||
ResourceType: "corteza::compose:page",
|
||||
Identifiers: envoyx.MakeIdentifiers(r.PageID),
|
||||
}
|
||||
}
|
||||
if r.ParentID > 0 {
|
||||
refs["ParentID"] = envoyx.Ref{
|
||||
ResourceType: "corteza::compose:page-layout",
|
||||
Identifiers: envoyx.MakeIdentifiers(r.ParentID),
|
||||
}
|
||||
}
|
||||
|
||||
var scope envoyx.Scope
|
||||
|
||||
scope = envoyx.Scope{
|
||||
ResourceType: refs["NamespaceID"].ResourceType,
|
||||
Identifiers: refs["NamespaceID"].Identifiers,
|
||||
}
|
||||
for k, ref := range refs {
|
||||
// @todo temporary solution to not needlessly scope resources.
|
||||
// Optimally, this would be selectively handled by codegen.
|
||||
if !strings.HasPrefix(ref.ResourceType, "corteza::compose") {
|
||||
continue
|
||||
}
|
||||
|
||||
ref.Scope = scope
|
||||
refs[k] = ref
|
||||
}
|
||||
|
||||
node = &envoyx.Node{
|
||||
Resource: r,
|
||||
|
||||
ResourceType: types.PageLayoutResourceType,
|
||||
Identifiers: ii,
|
||||
References: refs,
|
||||
Scope: scope,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d StoreDecoder) makePageLayoutFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter) (out types.PageLayoutFilter) {
|
||||
out.Limit = auxf.Limit
|
||||
|
||||
ids, hh := auxf.Identifiers.Idents()
|
||||
_ = ids
|
||||
_ = hh
|
||||
|
||||
out.PageLayoutID = ids
|
||||
|
||||
if len(hh) > 0 {
|
||||
out.Handle = hh[0]
|
||||
}
|
||||
|
||||
// Refs
|
||||
var (
|
||||
ar *envoyx.Node
|
||||
ok bool
|
||||
)
|
||||
_ = ar
|
||||
_ = ok
|
||||
|
||||
ar, ok = refs["NamespaceID"]
|
||||
if ok {
|
||||
out.NamespaceID = ar.Resource.GetID()
|
||||
}
|
||||
|
||||
ar, ok = refs["PageID"]
|
||||
if ok {
|
||||
out.PageID = ar.Resource.GetID()
|
||||
}
|
||||
|
||||
ar, ok = refs["ParentID"]
|
||||
if ok {
|
||||
out.ParentID = ar.Resource.GetID()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
// Utilities
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
|
||||
229
server/compose/envoy/store_encode.gen.go
generated
229
server/compose/envoy/store_encode.gen.go
generated
@@ -55,6 +55,8 @@ func (e StoreEncoder) Prepare(ctx context.Context, p envoyx.EncodeParams, rt str
|
||||
return e.prepareNamespace(ctx, p, s, nn)
|
||||
case types.PageResourceType:
|
||||
return e.preparePage(ctx, p, s, nn)
|
||||
case types.PageLayoutResourceType:
|
||||
return e.preparePageLayout(ctx, p, s, nn)
|
||||
|
||||
default:
|
||||
return e.prepare(ctx, p, s, rt, nn)
|
||||
@@ -99,6 +101,9 @@ func (e StoreEncoder) Encode(ctx context.Context, p envoyx.EncodeParams, rt stri
|
||||
|
||||
case types.PageResourceType:
|
||||
return e.encodePages(ctx, p, s, nodes, tree)
|
||||
|
||||
case types.PageLayoutResourceType:
|
||||
return e.encodePageLayouts(ctx, p, s, nodes, tree)
|
||||
default:
|
||||
return e.encode(ctx, p, s, rt, nodes, tree)
|
||||
}
|
||||
@@ -1171,6 +1176,12 @@ func (e StoreEncoder) encodePage(ctx context.Context, p envoyx.EncodeParams, s s
|
||||
|
||||
switch rt {
|
||||
|
||||
case types.PageLayoutResourceType:
|
||||
err = e.encodePageLayouts(ctx, p, s, nn, tree)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1233,6 +1244,224 @@ func (e StoreEncoder) matchupPages(ctx context.Context, s store.Storer, uu map[i
|
||||
return
|
||||
}
|
||||
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
// Functions for resource pageLayout
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
|
||||
// preparePageLayout prepares the resources of the given type for encoding
|
||||
func (e StoreEncoder) preparePageLayout(ctx context.Context, p envoyx.EncodeParams, s store.Storer, nn envoyx.NodeSet) (err error) {
|
||||
// Grab an index of already existing resources of this type
|
||||
// @note since these resources should be fairly low-volume and existing for
|
||||
// a short time (and because we batch by resource type); fetching them all
|
||||
// into memory shouldn't hurt too much.
|
||||
// @todo do some benchmarks and potentially implement some smarter check such as
|
||||
// a bloom filter or something similar.
|
||||
|
||||
// Get node scopes
|
||||
scopedNodes, err := e.getScopeNodes(ctx, s, nn)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "failed to get scope nodes")
|
||||
return
|
||||
}
|
||||
|
||||
// Initializing the index here (and using a hashmap) so it's not escaped to the heap
|
||||
existing := make(map[int]types.PageLayout, len(nn))
|
||||
err = e.matchupPageLayouts(ctx, s, existing, scopedNodes, nn)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "failed to matchup existing PageLayouts")
|
||||
return
|
||||
}
|
||||
|
||||
for i, n := range nn {
|
||||
if n.Resource == nil {
|
||||
panic("unexpected state: cannot call preparePageLayout with nodes without a defined Resource")
|
||||
}
|
||||
|
||||
res, ok := n.Resource.(*types.PageLayout)
|
||||
if !ok {
|
||||
panic("unexpected resource type: node expecting type of pageLayout")
|
||||
}
|
||||
|
||||
existing, hasExisting := existing[i]
|
||||
|
||||
// Run expressions on the nodes
|
||||
err = e.runEvals(ctx, hasExisting, n)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if hasExisting {
|
||||
// On existing, we don't need to re-do identifiers and references; simply
|
||||
// changing up the internal resource is enough.
|
||||
//
|
||||
// In the future, we can pass down the tree and re-do the deps like that
|
||||
switch n.Config.MergeAlg {
|
||||
case envoyx.OnConflictPanic:
|
||||
err = errors.Errorf("resource %v already exists", n.Identifiers.Slice)
|
||||
return
|
||||
|
||||
case envoyx.OnConflictReplace:
|
||||
// Replace; simple ID change should do the trick
|
||||
res.ID = existing.ID
|
||||
|
||||
case envoyx.OnConflictSkip:
|
||||
// Replace the node's resource with the fetched one
|
||||
res = &existing
|
||||
|
||||
// @todo merging
|
||||
}
|
||||
} else {
|
||||
// @todo actually a bottleneck. As per sonyflake docs, it can at most
|
||||
// generate up to 2**8 (256) IDs per 10ms in a single thread.
|
||||
// How can we improve this?
|
||||
res.ID = id.Next()
|
||||
}
|
||||
|
||||
// We can skip validation/defaults when the resource is overwritten by
|
||||
// the one already stored (the panic one errors out anyway) since it
|
||||
// should already be ok.
|
||||
if !hasExisting || n.Config.MergeAlg != envoyx.OnConflictSkip {
|
||||
err = e.setPageLayoutDefaults(res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = e.validatePageLayout(res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
n.Resource = res
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodePageLayouts encodes a set of resource into the database
|
||||
func (e StoreEncoder) encodePageLayouts(ctx context.Context, p envoyx.EncodeParams, s store.Storer, nn envoyx.NodeSet, tree envoyx.Traverser) (err error) {
|
||||
for _, n := range nn {
|
||||
err = e.encodePageLayout(ctx, p, s, n, tree)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodePageLayout encodes the resource into the database
|
||||
func (e StoreEncoder) encodePageLayout(ctx context.Context, p envoyx.EncodeParams, s store.Storer, n *envoyx.Node, tree envoyx.Traverser) (err error) {
|
||||
// Grab dependency references
|
||||
var auxID uint64
|
||||
err = func() (err error) {
|
||||
for fieldLabel, ref := range n.References {
|
||||
rn := tree.ParentForRef(n, ref)
|
||||
if rn == nil {
|
||||
err = fmt.Errorf("parent reference %v not found", ref)
|
||||
return
|
||||
}
|
||||
|
||||
auxID = rn.Resource.GetID()
|
||||
if auxID == 0 {
|
||||
err = fmt.Errorf("parent reference does not provide an identifier")
|
||||
return
|
||||
}
|
||||
|
||||
err = n.Resource.SetValue(fieldLabel, 0, auxID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}()
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("failed to set dependency references for %s %v", n.ResourceType, n.Identifiers.Slice))
|
||||
return
|
||||
}
|
||||
|
||||
// Flush to the DB
|
||||
if !n.Evaluated.Skip {
|
||||
err = store.UpsertComposePageLayout(ctx, s, n.Resource.(*types.PageLayout))
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "failed to upsert PageLayout")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Handle resources nested under it
|
||||
//
|
||||
// @todo how can we remove the OmitPlaceholderNodes call the same way we did for
|
||||
// the root function calls?
|
||||
|
||||
err = func() (err error) {
|
||||
for rt, nn := range envoyx.NodesByResourceType(tree.Children(n)...) {
|
||||
nn = envoyx.OmitPlaceholderNodes(nn...)
|
||||
|
||||
switch rt {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}()
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "failed to encode nested resources")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// matchupPageLayouts returns an index with indicates what resources already exist
|
||||
func (e StoreEncoder) matchupPageLayouts(ctx context.Context, s store.Storer, uu map[int]types.PageLayout, scopes envoyx.NodeSet, nn envoyx.NodeSet) (err error) {
|
||||
// @todo might need to do it smarter then this.
|
||||
// Most resources won't really be that vast so this should be acceptable for now.
|
||||
aa, _, err := store.SearchComposePageLayouts(ctx, s, types.PageLayoutFilter{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
idMap := make(map[uint64]*types.PageLayout, len(aa))
|
||||
strMap := make(map[string]*types.PageLayout, len(aa))
|
||||
|
||||
for _, a := range aa {
|
||||
strMap[a.Handle] = a
|
||||
idMap[a.ID] = a
|
||||
|
||||
}
|
||||
|
||||
var aux *types.PageLayout
|
||||
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 {
|
||||
aux, ok = idMap[id]
|
||||
if ok {
|
||||
uu[i] = *aux
|
||||
// When any identifier matches we can end it
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
aux, ok = strMap[idf]
|
||||
if ok {
|
||||
uu[i] = *aux
|
||||
// When any identifier matches we can end it
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
// Utility functions
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
|
||||
@@ -117,6 +117,21 @@ func (e StoreEncoder) validatePage(*types.Page) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setPageLayoutDefaults(res *types.PageLayout) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
// @note these pageblocks reference the ones define on the page so nothing
|
||||
// to do here.
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validatePageLayout(*types.PageLayout) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setRecordDefaults(*types.Record) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
397
server/compose/envoy/yaml_decode.gen.go
generated
397
server/compose/envoy/yaml_decode.gen.go
generated
@@ -181,6 +181,21 @@ func (d *auxYamlDoc) UnmarshalYAML(n *yaml.Node) (err error) {
|
||||
}
|
||||
return err
|
||||
|
||||
case "pagelayout", "page_layouts", "pagelayouts", "layouts":
|
||||
if y7s.IsMapping(v) {
|
||||
aux, err = d.unmarshalPageLayoutMap(dctx, v)
|
||||
d.nodes = append(d.nodes, aux...)
|
||||
}
|
||||
|
||||
if y7s.IsSeq(v) {
|
||||
aux, err = d.unmarshalPageLayoutSeq(dctx, v)
|
||||
d.nodes = append(d.nodes, aux...)
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "failed to unmarshal node: pageLayout")
|
||||
}
|
||||
return err
|
||||
|
||||
// Offload to custom handlers
|
||||
default:
|
||||
aux, err = d.unmarshalYAML(kv, v)
|
||||
@@ -1432,6 +1447,20 @@ func (d *auxYamlDoc) unmarshalNamespaceNode(dctx documentContext, n *yaml.Node,
|
||||
}
|
||||
break
|
||||
|
||||
case "pagelayout", "page_layouts", "pagelayouts", "layouts":
|
||||
if y7s.IsSeq(n) {
|
||||
nestedNodes, err = d.unmarshalPageLayoutSeq(dctx, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
nestedNodes, err = d.unmarshalPageLayoutMap(dctx, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
// Iterate nested nodes and update their reference to the current resource
|
||||
@@ -1832,6 +1861,20 @@ func (d *auxYamlDoc) unmarshalPageNode(dctx documentContext, n *yaml.Node, meta
|
||||
|
||||
switch strings.ToLower(k.Value) {
|
||||
|
||||
case "pagelayout", "page_layouts", "pagelayouts", "layouts":
|
||||
if y7s.IsSeq(n) {
|
||||
nestedNodes, err = d.unmarshalPageLayoutSeq(dctx, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
nestedNodes, err = d.unmarshalPageLayoutMap(dctx, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
case "children", "pages":
|
||||
if y7s.IsSeq(n) {
|
||||
nestedNodes, err = d.unmarshalExtendedPagesSeq(dctx, n)
|
||||
@@ -1950,6 +1993,360 @@ func (d *auxYamlDoc) unmarshalPageNode(dctx documentContext, n *yaml.Node, meta
|
||||
return
|
||||
}
|
||||
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
// Functions for resource pageLayout
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
|
||||
// unmarshalPageLayoutSeq unmarshals PageLayout when provided as a sequence node
|
||||
func (d *auxYamlDoc) unmarshalPageLayoutSeq(dctx documentContext, n *yaml.Node) (out envoyx.NodeSet, err error) {
|
||||
var aux envoyx.NodeSet
|
||||
err = y7s.EachSeq(n, func(n *yaml.Node) error {
|
||||
aux, err = d.unmarshalPageLayoutNode(dctx, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out = append(out, aux...)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// unmarshalPageLayoutMap unmarshals PageLayout when provided as a mapping node
|
||||
//
|
||||
// When map encoded, the map key is used as a preset identifier.
|
||||
// The identifier is passed to the node function as a meta node
|
||||
func (d *auxYamlDoc) unmarshalPageLayoutMap(dctx documentContext, n *yaml.Node) (out envoyx.NodeSet, err error) {
|
||||
var aux envoyx.NodeSet
|
||||
err = y7s.EachMap(n, func(k, n *yaml.Node) error {
|
||||
aux, err = d.unmarshalPageLayoutNode(dctx, n, k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out = append(out, aux...)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// unmarshalPageLayoutNode is a cookie-cutter function to unmarshal
|
||||
// the yaml node into the corresponding Corteza type & Node
|
||||
func (d *auxYamlDoc) unmarshalPageLayoutNode(dctx documentContext, n *yaml.Node, meta ...*yaml.Node) (out envoyx.NodeSet, err error) {
|
||||
var r *types.PageLayout
|
||||
|
||||
// @todo we're omitting errors because there will be a bunch due to invalid
|
||||
// resource field types. This might be a bit unstable as other errors may
|
||||
// also get ignored.
|
||||
//
|
||||
// A potential fix would be to firstly unmarshal into an any, check errors
|
||||
// and then unmarshal into the resource while omitting errors.
|
||||
n.Decode(&r)
|
||||
|
||||
// Identifiers are determined manually when iterating the yaml node.
|
||||
// This is to help assure there are no duplicates and everything
|
||||
// was accounted for especially when working with aliases such as
|
||||
// user_name instead of userName.
|
||||
ii := envoyx.Identifiers{}
|
||||
|
||||
// When a resource supports mapped input, the key is passed as meta which
|
||||
// needs to be registered as an identifier (since it is)
|
||||
if len(meta) > 0 {
|
||||
y7s.DecodeScalar(meta[0], "Handle", &r.Handle)
|
||||
ii = ii.Add(r.Handle)
|
||||
}
|
||||
|
||||
var (
|
||||
refs = make(map[string]envoyx.Ref)
|
||||
auxOut envoyx.NodeSet
|
||||
nestedNodes envoyx.NodeSet
|
||||
scope envoyx.Scope
|
||||
envoyConfig envoyx.EnvoyConfig
|
||||
rbacNodes envoyx.NodeSet
|
||||
)
|
||||
_ = auxOut
|
||||
_ = refs
|
||||
|
||||
err = y7s.EachMap(n, func(k, n *yaml.Node) error {
|
||||
var auxNodeValue any
|
||||
_ = auxNodeValue
|
||||
|
||||
switch strings.ToLower(k.Value) {
|
||||
|
||||
case "handle":
|
||||
// Handle identifiers
|
||||
err = y7s.DecodeScalar(n, "handle", &auxNodeValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ii = ii.Add(auxNodeValue)
|
||||
|
||||
break
|
||||
|
||||
case "id":
|
||||
// Handle identifiers
|
||||
err = y7s.DecodeScalar(n, "id", &auxNodeValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ii = ii.Add(auxNodeValue)
|
||||
|
||||
break
|
||||
|
||||
case "namespaceid", "namespace":
|
||||
// Handle references
|
||||
err = y7s.DecodeScalar(n, "namespaceID", &auxNodeValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Omit if not defined
|
||||
tmp := cast.ToString(auxNodeValue)
|
||||
if tmp == "0" || tmp == "" {
|
||||
break
|
||||
}
|
||||
refs["NamespaceID"] = envoyx.Ref{
|
||||
ResourceType: "corteza::compose:namespace",
|
||||
Identifiers: envoyx.MakeIdentifiers(auxNodeValue),
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
case "ownedby":
|
||||
// Handle references
|
||||
err = y7s.DecodeScalar(n, "ownedBy", &auxNodeValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Omit if not defined
|
||||
tmp := cast.ToString(auxNodeValue)
|
||||
if tmp == "0" || tmp == "" {
|
||||
break
|
||||
}
|
||||
refs["OwnedBy"] = envoyx.Ref{
|
||||
ResourceType: "corteza::system:user",
|
||||
Identifiers: envoyx.MakeIdentifiers(auxNodeValue),
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
case "pageid", "page":
|
||||
// Handle references
|
||||
err = y7s.DecodeScalar(n, "pageID", &auxNodeValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Omit if not defined
|
||||
tmp := cast.ToString(auxNodeValue)
|
||||
if tmp == "0" || tmp == "" {
|
||||
break
|
||||
}
|
||||
refs["PageID"] = envoyx.Ref{
|
||||
ResourceType: "corteza::compose:page",
|
||||
Identifiers: envoyx.MakeIdentifiers(auxNodeValue),
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
case "parentid", "parent":
|
||||
// Handle references
|
||||
err = y7s.DecodeScalar(n, "parentID", &auxNodeValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Omit if not defined
|
||||
tmp := cast.ToString(auxNodeValue)
|
||||
if tmp == "0" || tmp == "" {
|
||||
break
|
||||
}
|
||||
refs["ParentID"] = envoyx.Ref{
|
||||
ResourceType: "corteza::compose:page-layout",
|
||||
Identifiers: envoyx.MakeIdentifiers(auxNodeValue),
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
// Handle RBAC rules
|
||||
case "allow":
|
||||
auxOut, err = unmarshalAllowNode(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rbacNodes = append(rbacNodes, auxOut...)
|
||||
auxOut = nil
|
||||
|
||||
case "deny":
|
||||
auxOut, err = unmarshalDenyNode(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rbacNodes = append(rbacNodes, auxOut...)
|
||||
auxOut = nil
|
||||
case "(envoy)":
|
||||
envoyConfig = d.decodeEnvoyConfig(n)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Make parent identifiers available through the dctx
|
||||
dctx.parentIdent = ii
|
||||
|
||||
// Handle global namespace reference which can be provided as the doc. context
|
||||
//
|
||||
// @todo this is a temporary solution and should be extended when the document
|
||||
// context needs to be extended.
|
||||
// Limit this only to the compose resource since that is the only scenario
|
||||
// the previous implementation supports.
|
||||
if ref, ok := dctx.references["namespace"]; ok {
|
||||
refs["NamespaceID"] = envoyx.Ref{
|
||||
ResourceType: types.NamespaceResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(ref),
|
||||
}
|
||||
}
|
||||
|
||||
// Define the scope
|
||||
//
|
||||
// This resource is scoped to the first parent (generally the namespace)
|
||||
// when talking about Compose resources (the only supported scenario at the moment).
|
||||
scope = envoyx.Scope{
|
||||
ResourceType: refs["NamespaceID"].ResourceType,
|
||||
Identifiers: refs["NamespaceID"].Identifiers,
|
||||
}
|
||||
|
||||
// Apply the scope to all of the references of the same type
|
||||
for k, ref := range refs {
|
||||
if !strings.HasPrefix(ref.ResourceType, "corteza::compose") {
|
||||
continue
|
||||
}
|
||||
ref.Scope = scope
|
||||
refs[k] = ref
|
||||
}
|
||||
|
||||
// Handle any resources that could be inserted under pageLayout such as a module inside a namespace
|
||||
//
|
||||
// This operation is done in the second pass of the document so we have
|
||||
// the complete context of the current resource; such as the identifier,
|
||||
// references, and scope.
|
||||
var auxNestedNodes envoyx.NodeSet
|
||||
err = y7s.EachMap(n, func(k, n *yaml.Node) error {
|
||||
nestedNodes = nil
|
||||
|
||||
switch strings.ToLower(k.Value) {
|
||||
|
||||
}
|
||||
|
||||
// Iterate nested nodes and update their reference to the current resource
|
||||
//
|
||||
// Any reference to the parent resource from the child resource is overwritten
|
||||
// to avoid potential user-error edge cases.
|
||||
for _, a := range nestedNodes {
|
||||
// @note all nested resources fall under the same component and the same scope.
|
||||
// Simply assign the same scope to all -- if it shouldn't be scoped
|
||||
// the parent won't have it (saving CPU ticks :)
|
||||
a.Scope = scope
|
||||
|
||||
if a.References == nil {
|
||||
a.References = make(map[string]envoyx.Ref)
|
||||
}
|
||||
|
||||
a.References["PageLayoutID"] = envoyx.Ref{
|
||||
ResourceType: types.PageLayoutResourceType,
|
||||
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
|
||||
}
|
||||
|
||||
for f, ref := range refs {
|
||||
// Only inherit root references
|
||||
// @todo improve; this is a hack
|
||||
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
|
||||
}
|
||||
}
|
||||
auxNestedNodes = append(auxNestedNodes, nestedNodes...)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out = append(out, auxNestedNodes...)
|
||||
|
||||
a := &envoyx.Node{
|
||||
Resource: r,
|
||||
|
||||
ResourceType: types.PageLayoutResourceType,
|
||||
Identifiers: ii,
|
||||
References: refs,
|
||||
|
||||
Scope: scope,
|
||||
|
||||
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)
|
||||
|
||||
// The RBAC rule's most specific identifier is the resource itself.
|
||||
// Using this we can hardcode it to point to the location after the parent resource.
|
||||
//
|
||||
// @todo consider using a more descriptive identifier for the position
|
||||
// such as `index-%d`.
|
||||
rn.References["2"] = envoyx.Ref{
|
||||
ResourceType: a.ResourceType,
|
||||
Identifiers: a.Identifiers,
|
||||
Scope: scope,
|
||||
}
|
||||
|
||||
for _, r := range rn.References {
|
||||
if r.Scope.IsEmpty() {
|
||||
continue
|
||||
}
|
||||
rn.Scope = r.Scope
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Put it all together...
|
||||
out = append(out, a)
|
||||
out = append(out, auxOut...)
|
||||
out = append(out, rbacNodes...)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
// RBAC unmarshal logic
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
|
||||
106
server/compose/envoy/yaml_encode.gen.go
generated
106
server/compose/envoy/yaml_encode.gen.go
generated
@@ -105,6 +105,16 @@ func (e YamlEncoder) Encode(ctx context.Context, p envoyx.EncodeParams, rt strin
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
case types.PageLayoutResourceType:
|
||||
aux, err = e.encodePageLayouts(ctx, p, nodes, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// Root level resources are always encoded as a map
|
||||
out, err = y7s.AddMap(out, "pageLayout", aux)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
out, err = e.encode(ctx, out, p, rt, nodes, tt)
|
||||
@@ -540,6 +550,102 @@ func (e YamlEncoder) encodePage(ctx context.Context, p envoyx.EncodeParams, node
|
||||
var aux *yaml.Node
|
||||
_ = aux
|
||||
|
||||
aux, err = e.encodePageLayouts(ctx, p, tt.ChildrenForResourceType(node, types.PageLayoutResourceType), tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out, err = y7s.AddMap(out,
|
||||
"pageLayout", aux,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
// Functions for resource pageLayout
|
||||
// // // // // // // // // // // // // // // // // // // // // // // // //
|
||||
|
||||
func (e YamlEncoder) encodePageLayouts(ctx context.Context, p envoyx.EncodeParams, nodes envoyx.NodeSet, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
var aux *yaml.Node
|
||||
for _, n := range nodes {
|
||||
aux, err = e.encodePageLayout(ctx, p, n, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out, err = y7s.AddSeq(out, aux)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodePageLayout focuses on the specific resource invoked by the Encode method
|
||||
func (e YamlEncoder) encodePageLayout(ctx context.Context, p envoyx.EncodeParams, node *envoyx.Node, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
res := node.Resource.(*types.PageLayout)
|
||||
|
||||
// Pre-compute some map values so we can omit error checking when encoding yaml nodes
|
||||
|
||||
auxCreatedAt, err := e.encodeTimestamp(p, res.CreatedAt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
auxDeletedAt, err := e.encodeTimestampNil(p, res.DeletedAt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
auxNamespaceID, err := e.encodeRef(p, res.NamespaceID, "NamespaceID", node, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
auxOwnedBy, err := e.encodeRef(p, res.OwnedBy, "OwnedBy", node, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
auxPageID, err := e.encodeRef(p, res.PageID, "PageID", node, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
auxParentID, err := e.encodeRef(p, res.ParentID, "ParentID", node, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
auxUpdatedAt, err := e.encodeTimestampNil(p, res.UpdatedAt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out, err = y7s.AddMap(out,
|
||||
"blocks", res.Blocks,
|
||||
"config", res.Config,
|
||||
"createdAt", auxCreatedAt,
|
||||
"deletedAt", auxDeletedAt,
|
||||
"handle", res.Handle,
|
||||
"id", res.ID,
|
||||
"meta", res.Meta,
|
||||
"namespaceID", auxNamespaceID,
|
||||
"ownedBy", auxOwnedBy,
|
||||
"pageID", auxPageID,
|
||||
"parentID", auxParentID,
|
||||
"primary", res.Primary,
|
||||
"updatedAt", auxUpdatedAt,
|
||||
"weight", res.Weight,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Handle nested resources
|
||||
var aux *yaml.Node
|
||||
_ = aux
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,22 @@ pageLayout: {
|
||||
goType: "uint64",
|
||||
dal: { type: "Ref", refModelResType: "corteza::compose:page" }
|
||||
sortable: true
|
||||
envoy: {
|
||||
yaml: {
|
||||
identKeyAlias: ["page"]
|
||||
}
|
||||
}
|
||||
}
|
||||
parent_id: {
|
||||
ident: "parentID",
|
||||
goType: "uint64",
|
||||
dal: { type: "Ref", refModelResType: "corteza::compose:page-layout" }
|
||||
sortable: true
|
||||
envoy: {
|
||||
yaml: {
|
||||
identKeyAlias: ["parent"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace_id: {
|
||||
@@ -33,6 +43,11 @@ pageLayout: {
|
||||
goType: "uint64",
|
||||
storeIdent: "rel_namespace"
|
||||
dal: { type: "Ref", refModelResType: "corteza::compose:namespace" }
|
||||
envoy: {
|
||||
yaml: {
|
||||
identKeyAlias: ["namespace"]
|
||||
}
|
||||
}
|
||||
}
|
||||
weight: {
|
||||
goType: "int", sortable: true
|
||||
@@ -84,26 +99,28 @@ pageLayout: {
|
||||
|
||||
filter: {
|
||||
struct: {
|
||||
page_layout_id: { goType: "[]uint64", ident: "pageLayoutID", storeIdent: "id" }
|
||||
namespace_id: { goType: "uint64", ident: "namespaceID", storeIdent: "rel_namespace" }
|
||||
page_id: { goType: "uint64", ident: "pageID", storeIdent: "page_id" }
|
||||
parent_id: { goType: "uint64", ident: "parentID", storeIdent: "parent_id" }
|
||||
default: { goType: "bool", ident: "default" }
|
||||
handle: { goType: "string" }
|
||||
deleted: { goType: "filter.State", storeIdent: "deleted_at" }
|
||||
}
|
||||
|
||||
query: ["handle"]
|
||||
byValue: ["handle", "namespace_id", "page_id"]
|
||||
byValue: ["handle", "parent_id", "namespace_id", "page_id", "page_layout_id"]
|
||||
byNilState: ["deleted"]
|
||||
}
|
||||
|
||||
envoy: {
|
||||
omit: true
|
||||
}
|
||||
|
||||
rbac: {
|
||||
operations: {
|
||||
// @todo not sure how RBAC should work here
|
||||
// we'll probably use the page's RBAC whith some bool flags for user-defined ones
|
||||
scoped: true
|
||||
yaml: {
|
||||
supportMappedInput: true
|
||||
mappedField: "Handle"
|
||||
identKeyAlias: ["page_layouts", "pagelayouts", "layouts"]
|
||||
}
|
||||
store: {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
19
server/pkg/envoyx/rbac_references_compose.gen.go
generated
19
server/pkg/envoyx/rbac_references_compose.gen.go
generated
@@ -90,6 +90,25 @@ func ComposePageRbacReferences(namespaceID string, page string) (res *Ref, pp []
|
||||
return
|
||||
}
|
||||
|
||||
// ComposePageLayoutRbacReferences generates RBAC references
|
||||
//
|
||||
// Resources with "envoy: false" are skipped
|
||||
//
|
||||
// This function is auto-generated
|
||||
func ComposePageLayoutRbacReferences(namespaceID string, pageID string, pageLayout string) (res *Ref, pp []*Ref, err error) {
|
||||
if namespaceID != "*" {
|
||||
pp = append(pp, &Ref{ResourceType: types.NamespaceResourceType, Identifiers: MakeIdentifiers(namespaceID)})
|
||||
}
|
||||
if pageID != "*" {
|
||||
pp = append(pp, &Ref{ResourceType: types.PageResourceType, Identifiers: MakeIdentifiers(pageID)})
|
||||
}
|
||||
if pageLayout != "*" {
|
||||
res = &Ref{ResourceType: types.PageLayoutResourceType, Identifiers: MakeIdentifiers(pageLayout)}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ComposeRecordRbacReferences generates RBAC references
|
||||
//
|
||||
// Resources with "envoy: false" are skipped
|
||||
|
||||
11
server/pkg/envoyx/rbac_rules_parse.gen.go
generated
11
server/pkg/envoyx/rbac_rules_parse.gen.go
generated
@@ -193,6 +193,17 @@ func ParseRule(res string) (string, *Ref, []*Ref, error) {
|
||||
)
|
||||
return resourceType, ref, pp, err
|
||||
|
||||
case composeTypes.PageLayoutResourceType:
|
||||
if len(path) != 3 {
|
||||
return "", nil, nil, fmt.Errorf("expecting 3 reference components in path, got %d", len(path))
|
||||
}
|
||||
ref, pp, err := ComposePageLayoutRbacReferences(
|
||||
path[0],
|
||||
path[1],
|
||||
path[2],
|
||||
)
|
||||
return resourceType, ref, pp, err
|
||||
|
||||
case composeTypes.RecordResourceType:
|
||||
if len(path) != 3 {
|
||||
return "", nil, nil, fmt.Errorf("expecting 3 reference components in path, got %d", len(path))
|
||||
|
||||
39
server/pkg/envoyx/util_rbac.gen.go
generated
39
server/pkg/envoyx/util_rbac.gen.go
generated
@@ -489,6 +489,45 @@ func SplitResourceIdentifier(ref string) (out map[string]Ref) {
|
||||
Scope: scope,
|
||||
}
|
||||
|
||||
case "corteza::compose:page-layout":
|
||||
scope := Scope{}
|
||||
|
||||
if gRef(pp, 0) == "" {
|
||||
return
|
||||
}
|
||||
|
||||
aux := gRef(pp, 0)
|
||||
if aux != "" {
|
||||
scope.ResourceType = "corteza::compose:namespace"
|
||||
scope.Identifiers = MakeIdentifiers(aux)
|
||||
}
|
||||
|
||||
out["Path.0"] = Ref{
|
||||
ResourceType: "corteza::compose:namespace",
|
||||
Identifiers: MakeIdentifiers(gRef(pp, 0)),
|
||||
Scope: scope,
|
||||
}
|
||||
|
||||
if gRef(pp, 1) == "" {
|
||||
return
|
||||
}
|
||||
|
||||
out["Path.1"] = Ref{
|
||||
ResourceType: "corteza::compose:page",
|
||||
Identifiers: MakeIdentifiers(gRef(pp, 1)),
|
||||
Scope: scope,
|
||||
}
|
||||
|
||||
if gRef(pp, 2) == "" {
|
||||
return
|
||||
}
|
||||
|
||||
out["Path.2"] = Ref{
|
||||
ResourceType: "corteza::compose:page-layout",
|
||||
Identifiers: MakeIdentifiers(gRef(pp, 2)),
|
||||
Scope: scope,
|
||||
}
|
||||
|
||||
case "corteza::compose:record":
|
||||
scope := Scope{}
|
||||
|
||||
|
||||
5
server/pkg/envoyx/utils.gen.go
generated
5
server/pkg/envoyx/utils.gen.go
generated
@@ -19,8 +19,9 @@ var (
|
||||
"corteza::compose:module": true,
|
||||
"corteza::compose:module-field": true,
|
||||
|
||||
"corteza::compose:page": true,
|
||||
"corteza::compose:record": true,
|
||||
"corteza::compose:page": true,
|
||||
"corteza::compose:page-layout": true,
|
||||
"corteza::compose:record": true,
|
||||
|
||||
"corteza::compose:record-datasource": true,
|
||||
}
|
||||
|
||||
8
server/store/adapters/rdbms/filters.gen.go
generated
8
server/store/adapters/rdbms/filters.gen.go
generated
@@ -702,6 +702,10 @@ func ComposePageLayoutFilter(d drivers.Dialect, f composeType.PageLayoutFilter)
|
||||
ee = append(ee, goqu.C("handle").Eq(f.Handle))
|
||||
}
|
||||
|
||||
if f.ParentID > 0 {
|
||||
ee = append(ee, goqu.C("parent_id").Eq(f.ParentID))
|
||||
}
|
||||
|
||||
if f.NamespaceID > 0 {
|
||||
ee = append(ee, goqu.C("rel_namespace").Eq(f.NamespaceID))
|
||||
}
|
||||
@@ -710,6 +714,10 @@ func ComposePageLayoutFilter(d drivers.Dialect, f composeType.PageLayoutFilter)
|
||||
ee = append(ee, goqu.C("page_id").Eq(f.PageID))
|
||||
}
|
||||
|
||||
if len(f.PageLayoutID) > 0 {
|
||||
ee = append(ee, goqu.C("id").In(f.PageLayoutID))
|
||||
}
|
||||
|
||||
if len(f.LabeledIDs) > 0 {
|
||||
ee = append(ee, goqu.I("id").In(f.LabeledIDs))
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func TestImportExport(t *testing.T) {
|
||||
req.NoError(err)
|
||||
})
|
||||
|
||||
assertState(ctx, t, defaultStore, req)
|
||||
assertFullState(ctx, t, defaultStore, req)
|
||||
})
|
||||
|
||||
// Prepare a temp file where we'll dump the YAML into
|
||||
@@ -94,10 +94,11 @@ func TestImportExport(t *testing.T) {
|
||||
"dal": defaultDal,
|
||||
},
|
||||
Filter: map[string]envoyx.ResourceFilter{
|
||||
types.ChartResourceType: {},
|
||||
types.ModuleResourceType: {},
|
||||
types.NamespaceResourceType: {},
|
||||
types.PageResourceType: {},
|
||||
types.ChartResourceType: {},
|
||||
types.ModuleResourceType: {},
|
||||
types.NamespaceResourceType: {},
|
||||
types.PageResourceType: {},
|
||||
types.PageLayoutResourceType: {},
|
||||
|
||||
systemTypes.ApplicationResourceType: {},
|
||||
systemTypes.ApigwRouteResourceType: {},
|
||||
@@ -173,11 +174,11 @@ func TestImportExport(t *testing.T) {
|
||||
req.NoError(err)
|
||||
})
|
||||
|
||||
assertState(ctx, t, defaultStore, req)
|
||||
assertFullState(ctx, t, defaultStore, req)
|
||||
})
|
||||
}
|
||||
|
||||
func assertState(ctx context.Context, t *testing.T, s store.Storer, req *require.Assertions) {
|
||||
func assertFullState(ctx context.Context, t *testing.T, s store.Storer, req *require.Assertions) {
|
||||
t.Run("check state", func(t *testing.T) {
|
||||
t.Run("corteza::compose", func(t *testing.T) {
|
||||
// Namespaces
|
||||
@@ -241,6 +242,25 @@ func assertState(ctx context.Context, t *testing.T, s store.Storer, req *require
|
||||
rpg1 := pages.FindByHandle("test_ns_1_record_page_1")
|
||||
req.NotNil(rpg1)
|
||||
req.Equal(mod1.ID, rpg1.ModuleID)
|
||||
|
||||
// Page layouts
|
||||
layouts, _, err := store.SearchComposePageLayouts(ctx, s, types.PageLayoutFilter{
|
||||
NamespaceID: ns.ID,
|
||||
})
|
||||
req.NoError(err)
|
||||
|
||||
ly1 := layouts.FindByHandle("test_ns_1_page_1_layout_1")
|
||||
req.NotNil(ly1)
|
||||
|
||||
ly2 := layouts.FindByHandle("test_ns_1_page_1_layout_2")
|
||||
req.NotNil(ly2)
|
||||
|
||||
// Record page layouts
|
||||
ly3 := layouts.FindByHandle("test_ns_1_record_page_1_layout_1")
|
||||
req.NotNil(ly3)
|
||||
|
||||
ly4 := layouts.FindByHandle("test_ns_1_record_page_1_layout_2")
|
||||
req.NotNil(ly4)
|
||||
})
|
||||
t.Run("corteza::system", func(t *testing.T) {
|
||||
// Users
|
||||
|
||||
14
server/tests/envoy/testdata/full/full.yaml
vendored
14
server/tests/envoy/testdata/full/full.yaml
vendored
@@ -41,6 +41,13 @@ namespace:
|
||||
test_ns_1_page_1:
|
||||
title: Test Namespace 1 Page 1
|
||||
visible: true
|
||||
page_layouts:
|
||||
test_ns_1_page_1_layout_1:
|
||||
meta:
|
||||
title: Test Namespace 1 Page 1 Layout 1
|
||||
test_ns_1_page_1_layout_2:
|
||||
meta:
|
||||
title: Test Namespace 1 Page 1 Layout 2
|
||||
blocks:
|
||||
- title: Test Namespace 1 Page 1 Block 1
|
||||
kind: RecordList
|
||||
@@ -87,6 +94,13 @@ namespace:
|
||||
test_ns_1_record_page_1:
|
||||
title: Test Namespace 1 Record Page 1
|
||||
module: test_ns_1_mod_1
|
||||
page_layouts:
|
||||
test_ns_1_record_page_1_layout_1:
|
||||
meta:
|
||||
title: Test Namespace 1 Record Page 1 Layout 1
|
||||
test_ns_1_record_page_1_layout_2:
|
||||
meta:
|
||||
title: Test Namespace 1 Record Page 1 Layout 2
|
||||
|
||||
application:
|
||||
test_app_1:
|
||||
|
||||
Reference in New Issue
Block a user