Add support for decoding roles from yaml def
This commit is contained in:
@@ -10,16 +10,12 @@ type (
|
||||
// Document defines the supported yaml structure
|
||||
Document struct {
|
||||
compose *compose
|
||||
roles roleSet
|
||||
*rbacRules
|
||||
}
|
||||
)
|
||||
|
||||
func (doc *Document) UnmarshalYAML(n *yaml.Node) (err error) {
|
||||
if !isKind(n, yaml.MappingNode) {
|
||||
// root node kind be mapping
|
||||
return nodeErr(n, "expecting mapping node")
|
||||
}
|
||||
|
||||
if err = n.Decode(&doc.compose); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -28,7 +24,14 @@ func (doc *Document) UnmarshalYAML(n *yaml.Node) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
return eachMap(n, func(k, v *yaml.Node) error {
|
||||
switch k.Value {
|
||||
case "roles":
|
||||
return v.Decode(&doc.roles)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type (
|
||||
role struct {
|
||||
// when role is at least partially defined
|
||||
res *types.Role
|
||||
|
||||
// all known modules on a role
|
||||
modules ComposeModuleSet
|
||||
|
||||
// module's RBAC rules
|
||||
*rbacRules
|
||||
}
|
||||
roleSet []*role
|
||||
)
|
||||
|
||||
// UnmarshalYAML resolves set of role definitions, either sequence or map
|
||||
//
|
||||
// When resolving map, key is used as handle
|
||||
// Also supporting { handle: name } definitions
|
||||
//
|
||||
func (wset *roleSet) UnmarshalYAML(n *yaml.Node) error {
|
||||
return each(n, func(k, v *yaml.Node) (err error) {
|
||||
var (
|
||||
wrap = &role{}
|
||||
)
|
||||
|
||||
if v == nil {
|
||||
return nodeErr(n, "malformed role definition")
|
||||
}
|
||||
|
||||
wrap.res = &types.Role{}
|
||||
|
||||
if isKind(v, yaml.ScalarNode) {
|
||||
|
||||
if k != nil {
|
||||
wrap.res.Handle = k.Value
|
||||
}
|
||||
|
||||
if err = decodeScalar(v, "role name", &wrap.res.Name); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
*wset = append(*wset, wrap)
|
||||
return
|
||||
}
|
||||
|
||||
if err = v.Decode(&wrap.res); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if k != nil {
|
||||
if wrap.res.Handle != "" {
|
||||
return nodeErr(k, "cannot define handle in mapped role definition")
|
||||
}
|
||||
|
||||
if err = decodeRef(k, "role", &wrap.res.Handle); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
*wset = append(*wset, wrap)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
//func (wset roleSet) MarshalEnvoy() ([]envoy.Node, error) {
|
||||
// // role usually have bunch of sub-resources defined
|
||||
// nn := make([]envoy.Node, 0, len(wset)*10)
|
||||
//
|
||||
// for _, res := range wset {
|
||||
// if tmp, err := res.MarshalEnvoy(); err != nil {
|
||||
// return nil, err
|
||||
// } else {
|
||||
// nn = append(nn, tmp...)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nn, nil
|
||||
//}
|
||||
|
||||
func (wrap *role) UnmarshalYAML(n *yaml.Node) (err error) {
|
||||
if !isKind(n, yaml.MappingNode) {
|
||||
return nodeErr(n, "role definition must be a map or scalar")
|
||||
}
|
||||
|
||||
if wrap.res == nil {
|
||||
wrap.res = &types.Role{}
|
||||
}
|
||||
|
||||
if err = n.Decode(&wrap.res); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if wrap.rbacRules, err = decodeResourceAccessControl(types.RoleRBACResource, n); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//func (wrap role) MarshalEnvoy() ([]envoy.Node, error) {
|
||||
// nn := make([]envoy.Node, 0, 1+len(wrap.modules))
|
||||
// nn = append(nn, &envoy.RoleNode{Ns: wrap.res})
|
||||
//
|
||||
// if tmp, err := wrap.modules.MarshalEnvoy(); err != nil {
|
||||
// return nil, err
|
||||
// } else {
|
||||
// nn = append(nn, tmp...)
|
||||
// }
|
||||
//
|
||||
// // @todo rbac
|
||||
//
|
||||
// //if tmp, err := wrap.rules.MarshalEnvoy(); err != nil {
|
||||
// // return nil, err
|
||||
// //} else {
|
||||
// // nn = append(nn, tmp...)
|
||||
// //}
|
||||
//
|
||||
// return nn, nil
|
||||
//}
|
||||
@@ -0,0 +1,47 @@
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/yaml.v3"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRole_UnmarshalYAML(t *testing.T) {
|
||||
var (
|
||||
parseString = func(src string) (*role, error) {
|
||||
w := &role{}
|
||||
return w, yaml.Unmarshal([]byte(src), w)
|
||||
}
|
||||
)
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
req := require.New(t)
|
||||
|
||||
w, err := parseString(``)
|
||||
req.NoError(err)
|
||||
req.NotNil(w)
|
||||
req.Nil(w.res)
|
||||
})
|
||||
|
||||
t.Run("simple name", func(t *testing.T) {
|
||||
req := require.New(t)
|
||||
|
||||
w, err := parseString(`{ name: Test }`)
|
||||
req.NoError(err)
|
||||
req.NotNil(w)
|
||||
req.NotNil(w.res)
|
||||
req.NotEmpty(w.res.Name)
|
||||
})
|
||||
|
||||
t.Run("role 1", func(t *testing.T) {
|
||||
req := require.New(t)
|
||||
|
||||
doc, err := parseDocument("role_1")
|
||||
req.NoError(err)
|
||||
req.NotNil(doc)
|
||||
req.Len(doc.roles, 2)
|
||||
req.NotNil(doc.roles[1])
|
||||
req.Equal("Role2", doc.roles[1].res.Name)
|
||||
req.Equal("r2", doc.roles[1].res.Handle)
|
||||
})
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
roles:
|
||||
r1: Role1
|
||||
r2:
|
||||
name: Role2
|
||||
Reference in New Issue
Block a user