Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
2.9 KiB

10 years ago
package acl
import (
"fmt"
10 years ago
"github.com/hashicorp/hcl"
)
const (
KeyPolicyDeny = "deny"
KeyPolicyRead = "read"
KeyPolicyWrite = "write"
ServicePolicyDeny = "deny"
ServicePolicyRead = "read"
ServicePolicyWrite = "write"
EventPolicyRead = "read"
EventPolicyWrite = "write"
EventPolicyDeny = "deny"
KeyringPolicyWrite = "write"
KeyringPolicyRead = "read"
KeyringPolicyDeny = "deny"
10 years ago
)
// Policy is used to represent the policy specified by
// an ACL configuration.
type Policy struct {
ID string `hcl:"-"`
Keys []*KeyPolicy `hcl:"key,expand"`
Services []*ServicePolicy `hcl:"service,expand"`
Events []*EventPolicy `hcl:"event,expand"`
Keyring []*KeyringPolicy `hcl:"keyring"`
10 years ago
}
// KeyPolicy represents a policy for a key
type KeyPolicy struct {
Prefix string `hcl:",key"`
10 years ago
Policy string
}
func (k *KeyPolicy) GoString() string {
return fmt.Sprintf("%#v", *k)
10 years ago
}
// ServicePolicy represents a policy for a service
type ServicePolicy struct {
Name string `hcl:",key"`
Policy string
}
func (k *ServicePolicy) GoString() string {
return fmt.Sprintf("%#v", *k)
}
// EventPolicy represents a user event policy.
type EventPolicy struct {
Event string `hcl:",key"`
Policy string
}
func (e *EventPolicy) GoString() string {
return fmt.Sprintf("%#v", *e)
}
// KeyringPolicy represents a policy for the encryption keyring.
type KeyringPolicy struct {
// We only need a single field for the keyring, since access
// is binary (allowed or disallowed) and no prefix is respected.
Policy string
}
func (k *KeyringPolicy) GoString() string {
return fmt.Sprintf("%#v", *k)
}
10 years ago
// Parse is used to parse the specified ACL rules into an
// intermediary set of policies, before being compiled into
// the ACL
func Parse(rules string) (*Policy, error) {
// Decode the rules
p := &Policy{}
if rules == "" {
// Hot path for empty rules
return p, nil
}
10 years ago
if err := hcl.Decode(p, rules); err != nil {
return nil, fmt.Errorf("Failed to parse ACL rules: %v", err)
}
// Validate the key policy
for _, kp := range p.Keys {
switch kp.Policy {
case KeyPolicyDeny:
case KeyPolicyRead:
case KeyPolicyWrite:
default:
return nil, fmt.Errorf("Invalid key policy: %#v", kp)
}
}
// Validate the service policy
for _, sp := range p.Services {
switch sp.Policy {
case ServicePolicyDeny:
case ServicePolicyRead:
case ServicePolicyWrite:
default:
return nil, fmt.Errorf("Invalid service policy: %#v", sp)
}
}
// Validate the user event policies
for _, ep := range p.Events {
switch ep.Policy {
case EventPolicyRead:
case EventPolicyWrite:
case EventPolicyDeny:
default:
return nil, fmt.Errorf("Invalid event policy: %#v", ep)
}
}
// Validate the keyring policy
for _, krp := range p.Keyring {
switch krp.Policy {
case KeyringPolicyRead:
case KeyringPolicyWrite:
case KeyringPolicyDeny:
default:
return nil, fmt.Errorf("Invalid keyring policy: %#v", krp)
}
}
10 years ago
return p, nil
}