forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
mustrunas.go
80 lines (66 loc) · 2.39 KB
/
mustrunas.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package group
import (
"fmt"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/api"
securityapi "github.com/openshift/origin/pkg/security/apis/security"
)
// mustRunAs implements the GroupSecurityContextConstraintsStrategy interface
type mustRunAs struct {
ranges []securityapi.IDRange
field string
}
var _ GroupSecurityContextConstraintsStrategy = &mustRunAs{}
// NewMustRunAs provides a new MustRunAs strategy based on ranges.
func NewMustRunAs(ranges []securityapi.IDRange, field string) (GroupSecurityContextConstraintsStrategy, error) {
if len(ranges) == 0 {
return nil, fmt.Errorf("ranges must be supplied for MustRunAs")
}
return &mustRunAs{
ranges: ranges,
field: field,
}, nil
}
// Generate creates the group based on policy rules. By default this returns the first group of the
// first range (min val).
func (s *mustRunAs) Generate(pod *api.Pod) ([]int64, error) {
return []int64{s.ranges[0].Min}, nil
}
// Generate a single value to be applied. This is used for FSGroup. This strategy will return
// the first group of the first range (min val).
func (s *mustRunAs) GenerateSingle(pod *api.Pod) (*int64, error) {
single := new(int64)
*single = s.ranges[0].Min
return single, nil
}
// Validate ensures that the specified values fall within the range of the strategy.
// Groups are passed in here to allow this strategy to support multiple group fields (fsgroup and
// supplemental groups).
func (s *mustRunAs) Validate(pod *api.Pod, groups []int64) field.ErrorList {
allErrs := field.ErrorList{}
if pod.Spec.SecurityContext == nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("securityContext"), pod.Spec.SecurityContext, "unable to validate nil security context"))
return allErrs
}
if len(groups) == 0 && len(s.ranges) > 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath(s.field), groups, "unable to validate empty groups against required ranges"))
}
for _, group := range groups {
if !s.isGroupValid(group) {
detail := fmt.Sprintf("%d is not an allowed group", group)
allErrs = append(allErrs, field.Invalid(field.NewPath(s.field), groups, detail))
}
}
return allErrs
}
func (s *mustRunAs) isGroupValid(group int64) bool {
for _, rng := range s.ranges {
if fallsInRange(group, rng) {
return true
}
}
return false
}
func fallsInRange(group int64, rng securityapi.IDRange) bool {
return group >= rng.Min && group <= rng.Max
}