Improve resource identification

* Stop relying on names (eg. module name),
* use slices as underlying structure to avoid potential hashmap
  order related accidents.
This commit is contained in:
Tomaž Jerman
2022-01-18 21:50:18 +01:00
committed by Denis Arh
parent a47c1112e1
commit 9086bf34f4
16 changed files with 104 additions and 104 deletions
+12 -12
View File
@@ -57,7 +57,7 @@ func TestGraphBuilder_Rel(t *testing.T) {
rr := []resource.Interface{
&testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
identifiers: resource.Identifiers{"id1"},
refs: nil,
},
}
@@ -78,12 +78,12 @@ func TestGraphBuilder_Rel(t *testing.T) {
rr := []resource.Interface{
&testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
},
&testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id2": true},
identifiers: resource.Identifiers{"id2"},
refs: nil,
},
}
@@ -108,13 +108,13 @@ func TestGraphBuilder_Rel(t *testing.T) {
rr := []resource.Interface{
&testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
},
&testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id2": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1": true}}},
identifiers: resource.Identifiers{"id2"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1"}}},
},
}
@@ -142,8 +142,8 @@ func TestGraphBuilder_Rel(t *testing.T) {
rr := []resource.Interface{
&testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
},
}
@@ -163,8 +163,8 @@ func TestGraphBuilder_Rel(t *testing.T) {
rr := []resource.Interface{
&testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1"}}},
},
}
+34 -34
View File
@@ -17,13 +17,13 @@ func TestGraph_Walk(t *testing.T) {
a := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
}
b := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id2": true},
identifiers: resource.Identifiers{"id2"},
refs: nil,
}
@@ -50,14 +50,14 @@ func TestGraph_Walk(t *testing.T) {
a := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
}
b := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id2": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1": true}}},
identifiers: resource.Identifiers{"id2"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1"}}},
}
rr := []resource.Interface{
@@ -87,8 +87,8 @@ func TestGraph_Walk(t *testing.T) {
a := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id1"}}},
}
rr := []resource.Interface{
@@ -118,19 +118,19 @@ func TestGraph_WalkFlags(t *testing.T) {
a := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
}
b := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id2": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3": true}}},
identifiers: resource.Identifiers{"id2"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3"}}},
}
c := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id3": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3": true}}},
identifiers: resource.Identifiers{"id3"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3"}}},
}
rr := []resource.Interface{
@@ -172,28 +172,28 @@ func TestGraph_WalkFlags(t *testing.T) {
a := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
}
b := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id2": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3": true}}, &resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id5": true}}},
identifiers: resource.Identifiers{"id2"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3"}}, &resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id5"}}},
}
c := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id3": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id4": true}}},
identifiers: resource.Identifiers{"id3"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id4"}}},
}
d := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id4": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id4"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
}
e := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id5": true},
identifiers: resource.Identifiers{"id5"},
refs: nil,
}
@@ -248,29 +248,29 @@ func TestGraph_WalkFlags(t *testing.T) {
a := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id1": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id1"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
}
b := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id2": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3": true}}},
identifiers: resource.Identifiers{"id2"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id3"}}},
}
c := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id3": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id4": true}}, &resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id5": true}}},
identifiers: resource.Identifiers{"id3"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id4"}}, &resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id5"}}},
}
d := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id4": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id4"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
}
e := &testResource{
resType: "test:resource:1:",
identifiers: resource.Identifiers{"id5": true},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2": true}}},
identifiers: resource.Identifiers{"id5"},
refs: resource.RefSet{&resource.Ref{ResourceType: "test:resource:1:", Identifiers: resource.Identifiers{"id2"}}},
}
rr := []resource.Interface{
+2 -2
View File
@@ -66,7 +66,7 @@ func (ri nodeIndex) Add(nn ...*node) {
ri[rt] = make(map[string]nodeSet)
}
for i := range n.res.Identifiers() {
for _, i := range n.res.Identifiers() {
if ri[rt][i] == nil {
ri[rt][i] = make(nodeSet, 0, 5)
}
@@ -81,7 +81,7 @@ func (ri nodeIndex) GetRef(ref *resource.Ref) *node {
return nil
}
for i := range ref.Identifiers {
for _, i := range ref.Identifiers {
rr, has := refIi[i]
if !has || len(rr) == 0 {
continue
+1 -1
View File
@@ -41,7 +41,7 @@ func (r *Application) SysID() uint64 {
func (r *Application) RBACParts() (resource string, ref *Ref, path []*Ref) {
ref = r.Ref()
path = nil
resource = fmt.Sprintf(types.ApplicationRbacResourceTpl(), types.ApplicationResourceType, firstOkString(strconv.FormatUint(r.Res.ID, 10), r.Res.Name))
resource = fmt.Sprintf(types.ApplicationRbacResourceTpl(), types.ApplicationResourceType, firstOkString(strconv.FormatUint(r.Res.ID, 10)))
return
}
+1 -5
View File
@@ -97,11 +97,7 @@ func Check(a string, ii ...interface{}) bool {
// AddIdentifier adds a set of identifiers to the current resource
func (t *base) AddIdentifier(ss ...string) {
if t.ii == nil {
t.ii = make(Identifiers)
}
t.ii.Add(ss...)
t.ii = t.ii.Add(ss...)
}
// SetIdentifier sets the identifiers to whatever was provided
+33 -27
View File
@@ -1,6 +1,8 @@
package resource
import "strconv"
import (
"strconv"
)
type (
Interface interface {
@@ -55,7 +57,7 @@ type (
Constraints RefSet
}
Identifiers map[string]bool
Identifiers []string
)
var (
@@ -74,15 +76,15 @@ func MakeWildRef(rt string) *Ref {
}
func MakeIdentifiers(ss ...string) Identifiers {
ii := make(Identifiers)
ii.Add(ss...)
ii := make(Identifiers, 0, len(ss))
ii = ii.Add(ss...)
return ii
}
func (ri Identifiers) Add(ii ...string) Identifiers {
for _, i := range ii {
if len(i) > 0 {
ri[i] = true
ri = append(ri, i)
}
}
@@ -90,18 +92,21 @@ func (ri Identifiers) Add(ii ...string) Identifiers {
}
func (ri Identifiers) Clone() Identifiers {
out := make(Identifiers)
for i := range ri {
out[i] = true
out := make(Identifiers, 0, len(ri))
for _, i := range ri {
out = append(out, i)
}
return out
}
func (ri Identifiers) HasAny(ii Identifiers) bool {
for i := range ii {
if ri[i] {
return true
func (ri Identifiers) HasAny(check Identifiers) bool {
// The size of these will be tiny so no need for hashmaps
for _, i := range ri {
for _, j := range check {
if i == j {
return true
}
}
}
@@ -109,28 +114,22 @@ func (ri Identifiers) HasAny(ii Identifiers) bool {
}
func (ri Identifiers) StringSlice() []string {
ss := make([]string, 0, len(ri))
for k := range ri {
ss = append(ss, k)
}
return ss
return ri
}
func (ri Identifiers) First() string {
ss := ri.StringSlice()
if len(ss) <= 0 {
if len(ri) == 0 {
return ""
}
return ss[0]
return ri[0]
}
func (ri Identifiers) FirstID() uint64 {
ss := ri.StringSlice()
if len(ss) <= 0 {
if len(ri) <= 0 {
return 0
}
for _, s := range ss {
for _, s := range ri {
if v, err := strconv.ParseUint(s, 10, 64); err != nil {
continue
} else {
@@ -198,7 +197,16 @@ func (r *Ref) Constraint(c *Ref) *Ref {
// IsWildcard checks if this Ref points to all resources of a specific resource type
func (r *Ref) IsWildcard() bool {
return r.Identifiers != nil && r.Identifiers["*"]
if len(r.Identifiers) == 0 {
return false
}
for _, i := range r.Identifiers {
if i == "*" {
return true
}
}
return false
}
func (a *Ref) equals(b *Ref) bool {
@@ -284,9 +292,7 @@ func (rr RefSet) Unique() RefSet {
// not yet seen
if !ii.HasAny(r.Identifiers) {
out = append(out, r)
for i := range r.Identifiers {
seen[r.ResourceType][i] = true
}
seen[r.ResourceType] = seen[r.ResourceType].Add(r.Identifiers...)
}
}
+2 -2
View File
@@ -58,7 +58,7 @@ func (n *composeModule) Prepare(ctx context.Context, pl *payload) (err error) {
return composeModuleErrUnresolvedRecordField(refMod.Identifiers)
}
for i := range refMod.Identifiers {
for _, i := range refMod.Identifiers {
n.recFields[i] = mod.ID
}
}
@@ -77,7 +77,7 @@ func (n *composeModule) Prepare(ctx context.Context, pl *payload) (err error) {
return composeModuleErrUnresolvedUserField(refRole.Identifiers)
}
for i := range refRole.Identifiers {
for _, i := range refRole.Identifiers {
n.userFields[i] = rl.ID
}
}
+3 -3
View File
@@ -70,7 +70,7 @@ func (n *composePage) Prepare(ctx context.Context, pl *payload) (err error) {
if wf == nil {
return resource.AutomationWorkflowErrUnresolved(wfr.Identifiers)
}
for id := range wfr.Identifiers {
for _, id := range wfr.Identifiers {
n.relWfs[id] = wf
}
}
@@ -84,7 +84,7 @@ func (n *composePage) Prepare(ctx context.Context, pl *payload) (err error) {
if mod == nil {
return resource.ComposeModuleErrUnresolved(mr.Identifiers)
}
for id := range mr.Identifiers {
for _, id := range mr.Identifiers {
n.relMods[id] = mod
}
}
@@ -98,7 +98,7 @@ func (n *composePage) Prepare(ctx context.Context, pl *payload) (err error) {
if chr == nil {
return resource.ComposeChartErrUnresolved(refChart.Identifiers)
}
for id := range refChart.Identifiers {
for _, id := range refChart.Identifiers {
n.relCharts[id] = chr
}
}
+4 -4
View File
@@ -111,7 +111,7 @@ func (n *composeRecord) Prepare(ctx context.Context, pl *payload) (err error) {
return err
}
auxMap := make(map[string]uint64)
for i := range ref.Identifiers {
for _, i := range ref.Identifiers {
n.externalRef[i] = auxMap
}
@@ -153,7 +153,7 @@ func (n *composeRecord) Prepare(ctx context.Context, pl *payload) (err error) {
// Map existing records so we can perform updates
// Map to xref map for easier use later
auxMap := make(map[string]uint64)
for i := range n.res.RefMod.Identifiers {
for _, i := range n.res.RefMod.Identifiers {
n.externalRef[i] = auxMap
}
for _, r := range rr {
@@ -206,7 +206,7 @@ func (n *composeRecord) Encode(ctx context.Context, pl *payload) (err error) {
for _, ref := range pl.state.ParentResources {
if ref.ResourceType() == systemTypes.UserResourceType {
refUsr := ref.(*resource.User)
for i := range refUsr.Identifiers() {
for _, i := range refUsr.Identifiers() {
ux[i] = refUsr.SysID()
}
}
@@ -226,7 +226,7 @@ func (n *composeRecord) Encode(ctx context.Context, pl *payload) (err error) {
checkXRef := func(ii resource.Identifiers, ref string) (uint64, error) {
var auxMap map[string]uint64
for ri := range ii {
for _, ri := range ii {
if mp, ok := n.externalRef[ri]; ok {
auxMap = mp
break
+1 -1
View File
@@ -253,7 +253,7 @@ func (n *rbacRule) makeRBACResource(pl *payload) (string, error) {
return "", resource.ComposeRecordErrUnresolved(n.refRbacRes.Identifiers)
}
for i := range n.refRbacRes.Identifiers {
for _, i := range n.refRbacRes.Identifiers {
if p2ID = p2.IDMap[i]; p2ID > 0 {
break
}
+1 -1
View File
@@ -41,7 +41,7 @@ var (
)
func makeGenericFilter(ii resource.Identifiers) (f genericFilter) {
for i := range ii {
for _, i := range ii {
if i == "" {
continue
}
+1 -1
View File
@@ -48,5 +48,5 @@ func (nn composeChartSet) configureEncoder(cfg *EncoderConfig) {
}
func relChartToRef(chr *types.Chart) string {
return firstOkString(chr.Handle, chr.Name, strconv.FormatUint(chr.ID, 10))
return firstOkString(chr.Handle, strconv.FormatUint(chr.ID, 10))
}
+2 -1
View File
@@ -2,6 +2,7 @@ package yaml
import (
"context"
"strconv"
composeTypes "github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/envoy"
@@ -116,7 +117,7 @@ func (c *composeChartConfig) MarshalYAML() (interface{}, error) {
func (c *composeChartConfigReport) MarshalYAML() (interface{}, error) {
nn, err := makeMap(
"filter", c.report.Filter,
"module", firstOkString(c.relModule.Handle, c.relModule.Name),
"module", firstOkString(c.relModule.Handle, strconv.FormatUint(c.relModule.ID, 10)),
"metrics", c.report.Metrics,
"dimensions", c.report.Dimensions,
"yAxis", c.report.YAxis,
+3 -7
View File
@@ -142,19 +142,15 @@ func (c composeNamespaceMeta) empty() bool {
}
func relNsToRef(ns *types.Namespace) string {
return firstOkString(ns.Slug, ns.Name, strconv.FormatUint(ns.ID, 10))
return firstOkString(ns.Slug, strconv.FormatUint(ns.ID, 10))
}
func relModToRef(mod *types.Module) string {
return firstOkString(mod.Handle, mod.Name, strconv.FormatUint(mod.ID, 10))
return firstOkString(mod.Handle, strconv.FormatUint(mod.ID, 10))
}
func relWfToRef(mod *atypes.Workflow) string {
name := ""
if mod.Meta != nil {
name = mod.Meta.Name
}
return firstOkString(mod.Handle, name, strconv.FormatUint(mod.ID, 10))
return firstOkString(mod.Handle, strconv.FormatUint(mod.ID, 10))
}
func composeNamespaceErrNotFound(i string) error {
+3 -2
View File
@@ -2,6 +2,7 @@ package yaml
import (
"context"
"strconv"
automationTypes "github.com/cortezaproject/corteza-server/automation/types"
composeTypes "github.com/cortezaproject/corteza-server/compose/types"
@@ -138,14 +139,14 @@ func (p *composePage) MarshalYAML() (interface{}, error) {
nn, _ := makeMap()
if p.relMod != nil {
nn, err = addMap(nn, "module", firstOkString(p.relMod.Handle, p.relMod.Name))
nn, err = addMap(nn, "module", firstOkString(p.relMod.Handle, strconv.FormatUint(p.relMod.ID, 10)))
if err != nil {
return nil, err
}
}
if p.relParent != nil {
nn, err = addMap(nn, "parent", firstOkString(p.relParent.Handle, p.relParent.Title))
nn, err = addMap(nn, "parent", firstOkString(p.relParent.Handle, strconv.FormatUint(p.relParent.ID, 10)))
if err != nil {
return nil, err
}
+1 -1
View File
@@ -186,7 +186,7 @@ func (r *rbacRule) makeRBACResource(state *envoy.ResourceState) (string, error)
return "", resource.ComposeRecordErrUnresolved(res.RefRes.Identifiers)
}
for i := range res.RefRes.Identifiers {
for _, i := range res.RefRes.Identifiers {
if _, ok := p2.IDMap[i]; ok {
p2ID = res.RefRes.Identifiers.First()
break