Added merging to policies, need to make another interface for the shared all/per node policies to make a shared loading function

gql_cataclysm
noah metz 2023-07-28 00:32:43 -06:00
parent fb7e6d02f4
commit a16cf6bb38
3 changed files with 52 additions and 6 deletions

@ -66,7 +66,6 @@ type LockableExtJSON struct {
Dependencies map[string]string `json:"dependencies"`
}
// Simple json load function: TODO: make these a generic function as before
func LoadLockableExt(ctx *Context, data []byte) (Extension, error) {
var j LockableExtJSON
err := json.Unmarshal(data, &j)

@ -17,7 +17,7 @@ func lockableTestContext(t *testing.T, logs []string) *Context {
var link_policy = NewAllNodesPolicy([]SignalType{LinkSignalType, StatusSignalType})
var lock_policy = NewAllNodesPolicy([]SignalType{LinkSignalType, LockSignalType, StatusSignalType})
var lock_policy = NewAllNodesPolicy([]SignalType{LockSignalType})
func TestLink(t *testing.T) {
ctx := lockableTestContext(t, []string{"lockable"})
@ -50,13 +50,13 @@ func TestLink(t *testing.T) {
}
func TestLock(t *testing.T) {
ctx := lockableTestContext(t, []string{})
ctx := lockableTestContext(t, []string{"policy"})
NewLockable := func()(*Node, *ListenerExt) {
listener := NewListenerExt(10)
l := NewNode(ctx, RandID(), TestLockableType, nil,
listener,
NewACLExt(&lock_policy),
NewACLExt(&lock_policy, &link_policy),
NewLockableExt(),
)
return l, listener

@ -18,6 +18,8 @@ const (
type Policy interface {
Serializable[PolicyType]
Allows(principal_id NodeID, action SignalType, node *Node) error
// Merge with another policy of the same underlying type
Merge(Policy) Policy
}
//TODO: Update with change from principal *Node to principal_id so sane policies can still be made
@ -67,6 +69,51 @@ func NewRequirementOfPolicy(actions Actions) RequirementOfPolicy {
}
}
func MergeActions(first Actions, second Actions) Actions {
ret := second
for _, action := range(first) {
found := false
for _, a := range(second) {
if a == action {
break
}
}
if found == false {
ret = append(ret, action)
}
}
return ret
}
func MergeNodeActions(modified NodeActions, read NodeActions) {
for id, actions := range(read) {
existing, exists := modified[id]
if exists {
modified[id] = MergeActions(existing, actions)
} else {
modified[id] = actions
}
}
}
func (policy *PerNodePolicy) Merge(p Policy) Policy {
other := p.(*PerNodePolicy)
MergeNodeActions(policy.NodeActions, other.NodeActions)
return policy
}
func (policy *AllNodesPolicy) Merge(p Policy) Policy {
other := p.(*AllNodesPolicy)
policy.Actions = MergeActions(policy.Actions, other.Actions)
return policy
}
func (policy *RequirementOfPolicy) Merge(p Policy) Policy {
other := p.(*RequirementOfPolicy)
policy.Actions = MergeActions(policy.Actions, other.Actions)
return policy
}
type Actions []SignalType
func (actions Actions) Allows(action SignalType) error {
@ -223,9 +270,9 @@ func (ext *ACLExt) Process(ctx *Context, princ_id NodeID, node *Node, signal Sig
func NewACLExt(policies ...Policy) *ACLExt {
policy_map := map[PolicyType]Policy{}
for _, policy := range(policies) {
_, exists := policy_map[policy.Type()]
existing, exists := policy_map[policy.Type()]
if exists == true {
panic("Cannot add same policy type twice")
policy = existing.Merge(policy)
}
policy_map[policy.Type()] = policy