Skip to content

Commit

Permalink
Add policy constructs based on jainvipin's gist
Browse files Browse the repository at this point in the history
  • Loading branch information
mapuri committed Mar 9, 2016
1 parent 839ce2d commit d380239
Show file tree
Hide file tree
Showing 7 changed files with 480 additions and 86 deletions.
4 changes: 2 additions & 2 deletions api/server/router/container/container_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,10 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
adjustCPUShares := version.LessThan("1.19")

// set container policies associated by authz plugin(s)
policies, ok := ctx.Value("policies").(map[container.PolicyType]string)
policies, ok := ctx.Value("policies").([]container.Policy)
if !ok {
logrus.Debugf("incorrect type for policy map %T, expected %T", ctx.Value("policies"), config.Policies)
policies = make(map[container.PolicyType]string)
policies = []container.Policy{}
}
config.Policies = policies

Expand Down
4 changes: 2 additions & 2 deletions pkg/authorization/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type Request struct {
ResponseHeaders map[string]string `json:"ResponseHeaders,omitempty"`

// Policies stores a list of policies associated/identified with given request till this point
Policies map[container.PolicyType]string `json:"Policies,omitempty"`
Policies []container.Policy `json:"Policies,omitempty"`
}

// Response represents authZ plugin response
Expand All @@ -58,5 +58,5 @@ type Response struct {
Err string `json:"Err,omitempty"`

// Policies stores a list of policies associated with the authorized request
Policies map[container.PolicyType]string `json:"Policies,omitempty"`
Policies []container.Policy `json:"Policies,omitempty"`
}
12 changes: 4 additions & 8 deletions pkg/authorization/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (ctx *Ctx) AuthZRequest(w http.ResponseWriter, r *http.Request) error {
RequestURI: ctx.requestURI,
RequestBody: body,
RequestHeaders: headers(r.Header),
Policies: make(map[container.PolicyType]string),
Policies: []container.Policy{},
}

for _, plugin := range ctx.plugins {
Expand All @@ -90,12 +90,8 @@ func (ctx *Ctx) AuthZRequest(w http.ResponseWriter, r *http.Request) error {
return fmt.Errorf("authorization denied by plugin %s: %s", plugin.Name(), authRes.Msg)
} else {
// store the policies returned by authz plugin.
for k, v := range authRes.Policies {
if !k.IsValidType() {
logrus.Infof("authz plugin returned an invalid policy type: %d", k)
continue
}
ctx.authReq.Policies[k] = v
for _, p := range authRes.Policies {
ctx.authReq.Policies = append(ctx.authReq.Policies, p)
}
}
}
Expand Down Expand Up @@ -131,7 +127,7 @@ func (ctx *Ctx) AuthZResponse(rm ResponseModifier, r *http.Request) error {
}

// Policies returns the policies associated with the authz context for a request
func (ctx *Ctx) Policies() map[container.PolicyType]string {
func (ctx *Ctx) Policies() []container.Policy {
return ctx.authReq.Policies
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ type Config struct {
OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile
Labels map[string]string // List of labels set to this container
StopSignal string `json:",omitempty"` // Signal to stop a container
Policies PolicyMap // List of policy values
Policies []Policy // List of policy values
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
package container

import (
"encoding/json"
"fmt"
)

const (
NetworkFirewallAttrType = "firewall"
NetworkBandwidthAttrType = "bandwidth"
NetworkCOSAttrType = "cos"
NetworkVendorSpecificAttrType = "vendor-specific"
)

var AllowedPolicyAttributes = map[string]bool{
NetworkFirewallAttrType: true,
NetworkBandwidthAttrType: true,
NetworkCOSAttrType: true,
NetworkVendorSpecificAttrType: true,
}

func InvalidPolicyAttributeStringError(rcvd, exptd string) error {
return fmt.Errorf("invalid policy attribute string: %q. Expected: %q", rcvd, exptd)
}

type firewallRule struct {
direction string
action string
protocol string
port string
peerGroupId string
peerCIDR string
}

// NetworkFirewallAttr defines a security policy that is collection of
// actions for traffic matching L3/L4 protocol and L4 port
type NetworkFirewallAttr struct {
rules []firewallRule
groupId string
}

func NewNetworkFirewallAttr() *NetworkFirewallAttr {
return &NetworkFirewallAttr{rules: []firewallRule{}}
}

func (fw *NetworkFirewallAttr) AddRule(direction, action, protocol, port, peerGroupId, peerCIDR string) {
fw.rules = append(fw.rules, firewallRule{
direction: direction,
action: action,
protocol: protocol,
port: port,
peerGroupId: peerGroupId,
peerCIDR: peerCIDR,
})
}

func (fw *NetworkFirewallAttr) Type() string {
return NetworkFirewallAttrType
}

func (fw *NetworkFirewallAttr) MarshalJSON() ([]byte, error) {
// local type for marshalling
type forJSON struct {
Direction string `json:"direction"`
Action string `json:"action"`
Protocol string `json: "protocol"`
Port string `json:"port"`
PeerGroupId string `json:"peerGroupId"`
PeerCIDR string `json:"peerCIDR"`
}
rules := []forJSON{}

for _, r := range fw.rules {
rules = append(rules, forJSON{
Direction: r.direction,
Action: r.action,
Protocol: r.protocol,
Port: r.port,
PeerGroupId: r.peerGroupId,
PeerCIDR: r.peerCIDR,
})
}

return json.Marshal(struct {
Type string `json:"type"`
Data struct {
Rules []forJSON `json:"rules"`
GroupId string `json:"groupId"`
} `json:"data"`
}{
Type: NetworkFirewallAttrType,
Data: struct {
Rules []forJSON `json:"rules"`
GroupId string `json:"groupId"`
}{
Rules: rules,
GroupId: fw.groupId,
},
})
}

func (fw *NetworkFirewallAttr) UnmarshalJSON(in []byte) error {
// local type for marshalling
type forJSON struct {
Type string `json:"type"`
Data struct {
GroupId string `json:"groupId"`
Rules []struct {
Direction string `json:"direction"`
Action string `json:"action"`
Protocol string `json: "protocol"`
Port string `json:"port"`
PeerGroupId string `json:"peerGroupId"`
PeerCIDR string `json:"peerCIDR"`
} `json:"rules"`
} `json:"data"`
}

val := forJSON{}
if err := json.Unmarshal(in, &val); err != nil {
return err
}

if val.Type != NetworkFirewallAttrType {
return InvalidPolicyAttributeStringError(val.Type, NetworkFirewallAttrType)
}

fw.groupId = val.Data.GroupId
for _, r := range val.Data.Rules {
fw.AddRule(r.Direction, r.Action, r.Protocol, r.Port, r.PeerGroupId, r.PeerCIDR)
}
return nil
}

// NetworkBandwidthAttr defines a policy that controls the bandwidth
// available for traffic originating from the endpoint in a network
type NetworkBandwidthAttr string

func NewNetworkBandwidthAttr(bw string) *NetworkBandwidthAttr {
val := NetworkBandwidthAttr(bw)
return &val
}

func (bw *NetworkBandwidthAttr) Type() string {
return NetworkBandwidthAttrType
}

func (bw *NetworkBandwidthAttr) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type string `json:"type"`
Data string `json:"data"`
}{
Type: NetworkBandwidthAttrType,
Data: string(*bw),
})
}

func (bw *NetworkBandwidthAttr) UnmarshalJSON(in []byte) error {
val := struct {
Type string `json:"type"`
Data string `json:"data"`
}{}

if err := json.Unmarshal(in, &val); err != nil {
return err
}

if val.Type != NetworkBandwidthAttrType {
return InvalidPolicyAttributeStringError(val.Type, NetworkBandwidthAttrType)
}

*bw = NetworkBandwidthAttr(val.Data)
return nil
}

// NetworkCOSAttr defines a policy that controls the class of service
// applied for traffic originating from the endpoint in a network
type NetworkCOSAttr int

func NewNetworkCOSAttr(cos int) *NetworkCOSAttr {
val := NetworkCOSAttr(cos)
return &val
}

func (cos *NetworkCOSAttr) Type() string {
return NetworkCOSAttrType
}

func (cos *NetworkCOSAttr) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type string `json:"type"`
Data int `json:"data"`
}{
Type: NetworkCOSAttrType,
Data: int(*cos),
})
}

func (cos *NetworkCOSAttr) UnmarshalJSON(in []byte) error {
val := struct {
Type string `json:"type"`
Data int `json:"data"`
}{}

if err := json.Unmarshal(in, &val); err != nil {
return err
}

if val.Type != NetworkCOSAttrType {
return InvalidPolicyAttributeStringError(val.Type, NetworkCOSAttrType)
}

*cos = NetworkCOSAttr(val.Data)
return nil
}

// NetworkVendorSpecificAttr defines a vendor specific policy label that allows
// to apply vendor specific polices for traffic originating from the
// endpoint in a network
type NetworkVendorSpecificAttr string

func NewNetworkVendorSpecificAttr(vs string) *NetworkVendorSpecificAttr {
val := NetworkVendorSpecificAttr(vs)
return &val
}

func (vs *NetworkVendorSpecificAttr) Type() string {
return NetworkVendorSpecificAttrType
}

func (vs *NetworkVendorSpecificAttr) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type string `json:"type"`
Data string `json:"data"`
}{
Type: NetworkVendorSpecificAttrType,
Data: string(*vs),
})
}

func (vs *NetworkVendorSpecificAttr) UnmarshalJSON(in []byte) error {
val := struct {
Type string `json:"type"`
Data string `json:"data"`
}{}

if err := json.Unmarshal(in, &val); err != nil {
return err
}

if val.Type != NetworkVendorSpecificAttrType {
return InvalidPolicyAttributeStringError(val.Type, NetworkVendorSpecificAttrType)
}

*vs = NetworkVendorSpecificAttr(val.Data)
return nil
}
Loading

0 comments on commit d380239

Please sign in to comment.