Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
293770ef
Unverified
Commit
293770ef
authored
Aug 17, 2016
by
Tim St. Clair
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AppArmor PodSecurityPolicy implementation
parent
52b3ef6f
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
493 additions
and
6 deletions
+493
-6
.linted_packages
hack/.linted_packages
+2
-2
validation.go
pkg/apis/extensions/validation/validation.go
+19
-0
validation_test.go
pkg/apis/extensions/validation/validation_test.go
+32
-1
helpers.go
pkg/security/apparmor/helpers.go
+13
-0
strategy.go
pkg/security/podsecuritypolicy/apparmor/strategy.go
+110
-0
strategy_test.go
pkg/security/podsecuritypolicy/apparmor/strategy_test.go
+173
-0
factory.go
pkg/security/podsecuritypolicy/factory.go
+12
-0
provider.go
pkg/security/podsecuritypolicy/provider.go
+6
-0
provider_test.go
pkg/security/podsecuritypolicy/provider_test.go
+39
-3
types.go
pkg/security/podsecuritypolicy/types.go
+2
-0
admission_test.go
...kg/admission/security/podsecuritypolicy/admission_test.go
+85
-0
No files found.
hack/.linted_packages
View file @
293770ef
...
@@ -206,4 +206,5 @@ pkg/util/maps
...
@@ -206,4 +206,5 @@ pkg/util/maps
pkg/volume/quobyte
pkg/volume/quobyte
test/integration/discoverysummarizer
test/integration/discoverysummarizer
test/integration/examples
test/integration/examples
test/integration/federation
test/integration/federation
\ No newline at end of file
pkg/security/podsecuritypolicy/apparmor
pkg/apis/extensions/validation/validation.go
View file @
293770ef
...
@@ -30,6 +30,7 @@ import (
...
@@ -30,6 +30,7 @@ import (
apivalidation
"k8s.io/kubernetes/pkg/api/validation"
apivalidation
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/security/apparmor"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/sets"
...
@@ -552,6 +553,7 @@ var ValidatePodSecurityPolicyName = apivalidation.NameIsDNSSubdomain
...
@@ -552,6 +553,7 @@ var ValidatePodSecurityPolicyName = apivalidation.NameIsDNSSubdomain
func
ValidatePodSecurityPolicy
(
psp
*
extensions
.
PodSecurityPolicy
)
field
.
ErrorList
{
func
ValidatePodSecurityPolicy
(
psp
*
extensions
.
PodSecurityPolicy
)
field
.
ErrorList
{
allErrs
:=
field
.
ErrorList
{}
allErrs
:=
field
.
ErrorList
{}
allErrs
=
append
(
allErrs
,
apivalidation
.
ValidateObjectMeta
(
&
psp
.
ObjectMeta
,
false
,
ValidatePodSecurityPolicyName
,
field
.
NewPath
(
"metadata"
))
...
)
allErrs
=
append
(
allErrs
,
apivalidation
.
ValidateObjectMeta
(
&
psp
.
ObjectMeta
,
false
,
ValidatePodSecurityPolicyName
,
field
.
NewPath
(
"metadata"
))
...
)
allErrs
=
append
(
allErrs
,
ValidatePodSecurityPolicySpecificAnnotations
(
psp
.
Annotations
,
field
.
NewPath
(
"metadata"
)
.
Child
(
"annotations"
))
...
)
allErrs
=
append
(
allErrs
,
ValidatePodSecurityPolicySpec
(
&
psp
.
Spec
,
field
.
NewPath
(
"spec"
))
...
)
allErrs
=
append
(
allErrs
,
ValidatePodSecurityPolicySpec
(
&
psp
.
Spec
,
field
.
NewPath
(
"spec"
))
...
)
return
allErrs
return
allErrs
}
}
...
@@ -570,6 +572,23 @@ func ValidatePodSecurityPolicySpec(spec *extensions.PodSecurityPolicySpec, fldPa
...
@@ -570,6 +572,23 @@ func ValidatePodSecurityPolicySpec(spec *extensions.PodSecurityPolicySpec, fldPa
return
allErrs
return
allErrs
}
}
func
ValidatePodSecurityPolicySpecificAnnotations
(
annotations
map
[
string
]
string
,
fldPath
*
field
.
Path
)
field
.
ErrorList
{
allErrs
:=
field
.
ErrorList
{}
if
p
:=
annotations
[
apparmor
.
DefaultProfileAnnotationKey
];
p
!=
""
{
if
err
:=
apparmor
.
ValidateProfileFormat
(
p
);
err
!=
nil
{
allErrs
=
append
(
allErrs
,
field
.
Invalid
(
fldPath
.
Key
(
apparmor
.
DefaultProfileAnnotationKey
),
p
,
err
.
Error
()))
}
}
if
allowed
:=
annotations
[
apparmor
.
AllowedProfilesAnnotationKey
];
allowed
!=
""
{
for
_
,
p
:=
range
strings
.
Split
(
allowed
,
","
)
{
if
err
:=
apparmor
.
ValidateProfileFormat
(
p
);
err
!=
nil
{
allErrs
=
append
(
allErrs
,
field
.
Invalid
(
fldPath
.
Key
(
apparmor
.
AllowedProfilesAnnotationKey
),
allowed
,
err
.
Error
()))
}
}
}
return
allErrs
}
// validatePSPSELinux validates the SELinux fields of PodSecurityPolicy.
// validatePSPSELinux validates the SELinux fields of PodSecurityPolicy.
func
validatePSPSELinux
(
fldPath
*
field
.
Path
,
seLinux
*
extensions
.
SELinuxStrategyOptions
)
field
.
ErrorList
{
func
validatePSPSELinux
(
fldPath
*
field
.
Path
,
seLinux
*
extensions
.
SELinuxStrategyOptions
)
field
.
ErrorList
{
allErrs
:=
field
.
ErrorList
{}
allErrs
:=
field
.
ErrorList
{}
...
...
pkg/apis/extensions/validation/validation_test.go
View file @
293770ef
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/security/apparmor"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/util/validation/field"
...
@@ -1510,7 +1511,9 @@ func TestValidateReplicaSet(t *testing.T) {
...
@@ -1510,7 +1511,9 @@ func TestValidateReplicaSet(t *testing.T) {
func
TestValidatePodSecurityPolicy
(
t
*
testing
.
T
)
{
func
TestValidatePodSecurityPolicy
(
t
*
testing
.
T
)
{
validPSP
:=
func
()
*
extensions
.
PodSecurityPolicy
{
validPSP
:=
func
()
*
extensions
.
PodSecurityPolicy
{
return
&
extensions
.
PodSecurityPolicy
{
return
&
extensions
.
PodSecurityPolicy
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"foo"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"foo"
,
},
Spec
:
extensions
.
PodSecurityPolicySpec
{
Spec
:
extensions
.
PodSecurityPolicySpec
{
SELinux
:
extensions
.
SELinuxStrategyOptions
{
SELinux
:
extensions
.
SELinuxStrategyOptions
{
Rule
:
extensions
.
SELinuxStrategyRunAsAny
,
Rule
:
extensions
.
SELinuxStrategyRunAsAny
,
...
@@ -1584,6 +1587,15 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
...
@@ -1584,6 +1587,15 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
allowedCapListedInRequiredDrop
.
Spec
.
RequiredDropCapabilities
=
[]
api
.
Capability
{
"foo"
}
allowedCapListedInRequiredDrop
.
Spec
.
RequiredDropCapabilities
=
[]
api
.
Capability
{
"foo"
}
allowedCapListedInRequiredDrop
.
Spec
.
AllowedCapabilities
=
[]
api
.
Capability
{
"foo"
}
allowedCapListedInRequiredDrop
.
Spec
.
AllowedCapabilities
=
[]
api
.
Capability
{
"foo"
}
invalidAppArmorDefault
:=
validPSP
()
invalidAppArmorDefault
.
Annotations
=
map
[
string
]
string
{
apparmor
.
DefaultProfileAnnotationKey
:
"not-good"
,
}
invalidAppArmorAllowed
:=
validPSP
()
invalidAppArmorAllowed
.
Annotations
=
map
[
string
]
string
{
apparmor
.
AllowedProfilesAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
+
",not-good"
,
}
errorCases
:=
map
[
string
]
struct
{
errorCases
:=
map
[
string
]
struct
{
psp
*
extensions
.
PodSecurityPolicy
psp
*
extensions
.
PodSecurityPolicy
errorType
field
.
ErrorType
errorType
field
.
ErrorType
...
@@ -1664,6 +1676,16 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
...
@@ -1664,6 +1676,16 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
errorType
:
field
.
ErrorTypeInvalid
,
errorType
:
field
.
ErrorTypeInvalid
,
errorDetail
:
"capability is listed in allowedCapabilities and requiredDropCapabilities"
,
errorDetail
:
"capability is listed in allowedCapabilities and requiredDropCapabilities"
,
},
},
"invalid AppArmor default profile"
:
{
psp
:
invalidAppArmorDefault
,
errorType
:
field
.
ErrorTypeInvalid
,
errorDetail
:
"invalid AppArmor profile name:
\"
not-good
\"
"
,
},
"invalid AppArmor allowed profile"
:
{
psp
:
invalidAppArmorAllowed
,
errorType
:
field
.
ErrorTypeInvalid
,
errorDetail
:
"invalid AppArmor profile name:
\"
not-good
\"
"
,
},
}
}
for
k
,
v
:=
range
errorCases
{
for
k
,
v
:=
range
errorCases
{
...
@@ -1700,6 +1722,12 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
...
@@ -1700,6 +1722,12 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
caseInsensitiveAllowedDrop
.
Spec
.
RequiredDropCapabilities
=
[]
api
.
Capability
{
"FOO"
}
caseInsensitiveAllowedDrop
.
Spec
.
RequiredDropCapabilities
=
[]
api
.
Capability
{
"FOO"
}
caseInsensitiveAllowedDrop
.
Spec
.
AllowedCapabilities
=
[]
api
.
Capability
{
"foo"
}
caseInsensitiveAllowedDrop
.
Spec
.
AllowedCapabilities
=
[]
api
.
Capability
{
"foo"
}
validAppArmor
:=
validPSP
()
validAppArmor
.
Annotations
=
map
[
string
]
string
{
apparmor
.
DefaultProfileAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
,
apparmor
.
AllowedProfilesAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
+
","
+
apparmor
.
ProfileNamePrefix
+
"foo"
,
}
successCases
:=
map
[
string
]
struct
{
successCases
:=
map
[
string
]
struct
{
psp
*
extensions
.
PodSecurityPolicy
psp
*
extensions
.
PodSecurityPolicy
}{
}{
...
@@ -1718,6 +1746,9 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
...
@@ -1718,6 +1746,9 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
"comparison for allowed -> drop is case sensitive"
:
{
"comparison for allowed -> drop is case sensitive"
:
{
psp
:
caseInsensitiveAllowedDrop
,
psp
:
caseInsensitiveAllowedDrop
,
},
},
"valid AppArmor annotations"
:
{
psp
:
validAppArmor
,
},
}
}
for
k
,
v
:=
range
successCases
{
for
k
,
v
:=
range
successCases
{
...
...
pkg/security/apparmor/helpers.go
View file @
293770ef
...
@@ -26,6 +26,10 @@ import (
...
@@ -26,6 +26,10 @@ import (
const
(
const
(
// The prefix to an annotation key specifying a container profile.
// The prefix to an annotation key specifying a container profile.
ContainerAnnotationKeyPrefix
=
"container.apparmor.security.alpha.kubernetes.io/"
ContainerAnnotationKeyPrefix
=
"container.apparmor.security.alpha.kubernetes.io/"
// The annotation key specifying the default AppArmor profile.
DefaultProfileAnnotationKey
=
"apparmor.security.alpha.kubernetes.io/defaultProfileName"
// The annotation key specifying the allowed AppArmor profiles.
AllowedProfilesAnnotationKey
=
"apparmor.security.alpha.kubernetes.io/allowedProfileNames"
// The profile specifying the runtime default.
// The profile specifying the runtime default.
ProfileRuntimeDefault
=
"runtime/default"
ProfileRuntimeDefault
=
"runtime/default"
...
@@ -47,3 +51,12 @@ func isRequired(pod *api.Pod) bool {
...
@@ -47,3 +51,12 @@ func isRequired(pod *api.Pod) bool {
func
GetProfileName
(
pod
*
api
.
Pod
,
containerName
string
)
string
{
func
GetProfileName
(
pod
*
api
.
Pod
,
containerName
string
)
string
{
return
pod
.
Annotations
[
ContainerAnnotationKeyPrefix
+
containerName
]
return
pod
.
Annotations
[
ContainerAnnotationKeyPrefix
+
containerName
]
}
}
// Sets the name of the profile to use with the container.
func
SetProfileName
(
pod
*
api
.
Pod
,
containerName
,
profileName
string
)
error
{
if
pod
.
Annotations
==
nil
{
pod
.
Annotations
=
map
[
string
]
string
{}
}
pod
.
Annotations
[
ContainerAnnotationKeyPrefix
+
containerName
]
=
profileName
return
nil
}
pkg/security/podsecuritypolicy/apparmor/strategy.go
0 → 100644
View file @
293770ef
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
apparmor
import
(
"fmt"
"strings"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/security/apparmor"
"k8s.io/kubernetes/pkg/util/maps"
"k8s.io/kubernetes/pkg/util/validation/field"
)
// Strategy defines the interface for all AppArmor constraint strategies.
type
Strategy
interface
{
// Generate updates the annotations based on constraint rules. The updates are applied to a copy
// of the annotations, and returned.
Generate
(
annotations
map
[
string
]
string
,
container
*
api
.
Container
)
(
map
[
string
]
string
,
error
)
// Validate ensures that the specified values fall within the range of the strategy.
Validate
(
pod
*
api
.
Pod
,
container
*
api
.
Container
)
field
.
ErrorList
}
type
strategy
struct
{
defaultProfile
string
allowedProfiles
map
[
string
]
bool
// For printing error messages (preserves order).
allowedProfilesString
string
}
var
_
Strategy
=
&
strategy
{}
// NewStrategy creates a new strategy that enforces AppArmor profile constraints.
func
NewStrategy
(
pspAnnotations
map
[
string
]
string
)
Strategy
{
var
allowedProfiles
map
[
string
]
bool
if
allowed
,
ok
:=
pspAnnotations
[
apparmor
.
AllowedProfilesAnnotationKey
];
ok
{
profiles
:=
strings
.
Split
(
allowed
,
","
)
allowedProfiles
=
make
(
map
[
string
]
bool
,
len
(
profiles
))
for
_
,
p
:=
range
profiles
{
allowedProfiles
[
p
]
=
true
}
}
return
&
strategy
{
defaultProfile
:
pspAnnotations
[
apparmor
.
DefaultProfileAnnotationKey
],
allowedProfiles
:
allowedProfiles
,
allowedProfilesString
:
pspAnnotations
[
apparmor
.
AllowedProfilesAnnotationKey
],
}
}
func
(
s
*
strategy
)
Generate
(
annotations
map
[
string
]
string
,
container
*
api
.
Container
)
(
map
[
string
]
string
,
error
)
{
copy
:=
maps
.
CopySS
(
annotations
)
if
annotations
[
apparmor
.
ContainerAnnotationKeyPrefix
+
container
.
Name
]
!=
""
{
// Profile already set, nothing to do.
return
copy
,
nil
}
if
s
.
defaultProfile
==
""
{
// No default set.
return
copy
,
nil
}
if
copy
==
nil
{
copy
=
map
[
string
]
string
{}
}
// Add the default profile.
copy
[
apparmor
.
ContainerAnnotationKeyPrefix
+
container
.
Name
]
=
s
.
defaultProfile
return
copy
,
nil
}
func
(
s
*
strategy
)
Validate
(
pod
*
api
.
Pod
,
container
*
api
.
Container
)
field
.
ErrorList
{
if
s
.
allowedProfiles
==
nil
{
// Unrestricted: allow all.
return
nil
}
allErrs
:=
field
.
ErrorList
{}
fieldPath
:=
field
.
NewPath
(
"pod"
,
"metadata"
,
"annotations"
)
.
Key
(
apparmor
.
ContainerAnnotationKeyPrefix
+
container
.
Name
)
profile
:=
apparmor
.
GetProfileName
(
pod
,
container
.
Name
)
if
profile
==
""
{
if
len
(
s
.
allowedProfiles
)
>
0
{
allErrs
=
append
(
allErrs
,
field
.
Forbidden
(
fieldPath
,
"AppArmor profile must be set"
))
return
allErrs
}
return
nil
}
if
!
s
.
allowedProfiles
[
profile
]
{
msg
:=
fmt
.
Sprintf
(
"%s is not an allowed profile. Allowed values: %q"
,
profile
,
s
.
allowedProfilesString
)
allErrs
=
append
(
allErrs
,
field
.
Forbidden
(
fieldPath
,
msg
))
}
return
allErrs
}
pkg/security/podsecuritypolicy/apparmor/strategy_test.go
0 → 100644
View file @
293770ef
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
apparmor
import
(
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/stretchr/testify/assert"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/security/apparmor"
"k8s.io/kubernetes/pkg/util/maps"
)
const
(
containerName
=
"test-c"
)
var
(
withoutAppArmor
=
map
[
string
]
string
{
"foo"
:
"bar"
}
withDefault
=
map
[
string
]
string
{
"foo"
:
"bar"
,
apparmor
.
ContainerAnnotationKeyPrefix
+
containerName
:
apparmor
.
ProfileRuntimeDefault
,
}
withLocal
=
map
[
string
]
string
{
"foo"
:
"bar"
,
apparmor
.
ContainerAnnotationKeyPrefix
+
containerName
:
apparmor
.
ProfileNamePrefix
+
"foo"
,
}
withDisallowed
=
map
[
string
]
string
{
"foo"
:
"bar"
,
apparmor
.
ContainerAnnotationKeyPrefix
+
containerName
:
apparmor
.
ProfileNamePrefix
+
"bad"
,
}
noAppArmor
=
map
[
string
]
string
{
"foo"
:
"bar"
}
unconstrainedWithDefault
=
map
[
string
]
string
{
apparmor
.
DefaultProfileAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
,
}
constrained
=
map
[
string
]
string
{
apparmor
.
AllowedProfilesAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
+
","
+
apparmor
.
ProfileNamePrefix
+
"foo"
,
}
constrainedWithDefault
=
map
[
string
]
string
{
apparmor
.
DefaultProfileAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
,
apparmor
.
AllowedProfilesAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
+
","
+
apparmor
.
ProfileNamePrefix
+
"foo"
,
}
container
=
api
.
Container
{
Name
:
containerName
,
Image
:
"busybox"
,
}
)
func
TestGenerate
(
t
*
testing
.
T
)
{
type
testcase
struct
{
pspAnnotations
map
[
string
]
string
podAnnotations
map
[
string
]
string
expected
map
[
string
]
string
}
tests
:=
[]
testcase
{{
pspAnnotations
:
noAppArmor
,
podAnnotations
:
withoutAppArmor
,
expected
:
withoutAppArmor
,
},
{
pspAnnotations
:
unconstrainedWithDefault
,
podAnnotations
:
withoutAppArmor
,
expected
:
withDefault
,
},
{
pspAnnotations
:
constrained
,
podAnnotations
:
withoutAppArmor
,
expected
:
withoutAppArmor
,
},
{
pspAnnotations
:
constrainedWithDefault
,
podAnnotations
:
withoutAppArmor
,
expected
:
withDefault
,
}}
// Add unchanging permutations.
for
_
,
podAnnotations
:=
range
[]
map
[
string
]
string
{
withDefault
,
withLocal
}
{
for
_
,
pspAnnotations
:=
range
[]
map
[
string
]
string
{
noAppArmor
,
unconstrainedWithDefault
,
constrained
,
constrainedWithDefault
}
{
tests
=
append
(
tests
,
testcase
{
pspAnnotations
:
pspAnnotations
,
podAnnotations
:
podAnnotations
,
expected
:
podAnnotations
,
})
}
}
for
i
,
test
:=
range
tests
{
s
:=
NewStrategy
(
test
.
pspAnnotations
)
msgAndArgs
:=
[]
interface
{}{
"testcase[%d]: %s"
,
i
,
spew
.
Sdump
(
test
)}
actual
,
err
:=
s
.
Generate
(
test
.
podAnnotations
,
&
container
)
assert
.
NoError
(
t
,
err
,
msgAndArgs
...
)
assert
.
Equal
(
t
,
test
.
expected
,
actual
,
msgAndArgs
...
)
}
}
func
TestValidate
(
t
*
testing
.
T
)
{
type
testcase
struct
{
pspAnnotations
map
[
string
]
string
podAnnotations
map
[
string
]
string
expectErr
bool
}
tests
:=
[]
testcase
{}
// Valid combinations
for
_
,
podAnnotations
:=
range
[]
map
[
string
]
string
{
withDefault
,
withLocal
}
{
for
_
,
pspAnnotations
:=
range
[]
map
[
string
]
string
{
noAppArmor
,
unconstrainedWithDefault
,
constrained
,
constrainedWithDefault
}
{
tests
=
append
(
tests
,
testcase
{
pspAnnotations
:
pspAnnotations
,
podAnnotations
:
podAnnotations
,
expectErr
:
false
,
})
}
}
for
_
,
podAnnotations
:=
range
[]
map
[
string
]
string
{
withoutAppArmor
,
withDisallowed
}
{
for
_
,
pspAnnotations
:=
range
[]
map
[
string
]
string
{
noAppArmor
,
unconstrainedWithDefault
}
{
tests
=
append
(
tests
,
testcase
{
pspAnnotations
:
pspAnnotations
,
podAnnotations
:
podAnnotations
,
expectErr
:
false
,
})
}
}
// Invalid combinations
for
_
,
podAnnotations
:=
range
[]
map
[
string
]
string
{
withoutAppArmor
,
withDisallowed
}
{
for
_
,
pspAnnotations
:=
range
[]
map
[
string
]
string
{
constrained
,
constrainedWithDefault
}
{
tests
=
append
(
tests
,
testcase
{
pspAnnotations
:
pspAnnotations
,
podAnnotations
:
podAnnotations
,
expectErr
:
true
,
})
}
}
for
i
,
test
:=
range
tests
{
s
:=
NewStrategy
(
test
.
pspAnnotations
)
pod
,
container
:=
makeTestPod
(
test
.
podAnnotations
)
msgAndArgs
:=
[]
interface
{}{
"testcase[%d]: %s"
,
i
,
spew
.
Sdump
(
test
)}
errs
:=
s
.
Validate
(
pod
,
container
)
if
test
.
expectErr
{
assert
.
Len
(
t
,
errs
,
1
,
msgAndArgs
...
)
}
else
{
assert
.
Len
(
t
,
errs
,
0
,
msgAndArgs
...
)
}
}
}
func
makeTestPod
(
annotations
map
[
string
]
string
)
(
*
api
.
Pod
,
*
api
.
Container
)
{
return
&
api
.
Pod
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"test-pod"
,
Annotations
:
maps
.
CopySS
(
annotations
),
},
Spec
:
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{
container
},
},
},
&
container
}
pkg/security/podsecuritypolicy/factory.go
View file @
293770ef
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/apparmor"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/capabilities"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/capabilities"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/group"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/group"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/selinux"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/selinux"
...
@@ -49,6 +50,11 @@ func (f *simpleStrategyFactory) CreateStrategies(psp *extensions.PodSecurityPoli
...
@@ -49,6 +50,11 @@ func (f *simpleStrategyFactory) CreateStrategies(psp *extensions.PodSecurityPoli
errs
=
append
(
errs
,
err
)
errs
=
append
(
errs
,
err
)
}
}
appArmorStrat
,
err
:=
createAppArmorStrategy
(
psp
)
if
err
!=
nil
{
errs
=
append
(
errs
,
err
)
}
fsGroupStrat
,
err
:=
createFSGroupStrategy
(
&
psp
.
Spec
.
FSGroup
)
fsGroupStrat
,
err
:=
createFSGroupStrategy
(
&
psp
.
Spec
.
FSGroup
)
if
err
!=
nil
{
if
err
!=
nil
{
errs
=
append
(
errs
,
err
)
errs
=
append
(
errs
,
err
)
...
@@ -71,6 +77,7 @@ func (f *simpleStrategyFactory) CreateStrategies(psp *extensions.PodSecurityPoli
...
@@ -71,6 +77,7 @@ func (f *simpleStrategyFactory) CreateStrategies(psp *extensions.PodSecurityPoli
strategies
:=
&
ProviderStrategies
{
strategies
:=
&
ProviderStrategies
{
RunAsUserStrategy
:
userStrat
,
RunAsUserStrategy
:
userStrat
,
SELinuxStrategy
:
seLinuxStrat
,
SELinuxStrategy
:
seLinuxStrat
,
AppArmorStrategy
:
appArmorStrat
,
FSGroupStrategy
:
fsGroupStrat
,
FSGroupStrategy
:
fsGroupStrat
,
SupplementalGroupStrategy
:
supGroupStrat
,
SupplementalGroupStrategy
:
supGroupStrat
,
CapabilitiesStrategy
:
capStrat
,
CapabilitiesStrategy
:
capStrat
,
...
@@ -105,6 +112,11 @@ func createSELinuxStrategy(opts *extensions.SELinuxStrategyOptions) (selinux.SEL
...
@@ -105,6 +112,11 @@ func createSELinuxStrategy(opts *extensions.SELinuxStrategyOptions) (selinux.SEL
}
}
}
}
// createAppArmorStrategy creates a new AppArmor strategy.
func
createAppArmorStrategy
(
psp
*
extensions
.
PodSecurityPolicy
)
(
apparmor
.
Strategy
,
error
)
{
return
apparmor
.
NewStrategy
(
psp
.
Annotations
),
nil
}
// createFSGroupStrategy creates a new fsgroup strategy
// createFSGroupStrategy creates a new fsgroup strategy
func
createFSGroupStrategy
(
opts
*
extensions
.
FSGroupStrategyOptions
)
(
group
.
GroupStrategy
,
error
)
{
func
createFSGroupStrategy
(
opts
*
extensions
.
FSGroupStrategyOptions
)
(
group
.
GroupStrategy
,
error
)
{
switch
opts
.
Rule
{
switch
opts
.
Rule
{
...
...
pkg/security/podsecuritypolicy/provider.go
View file @
293770ef
...
@@ -139,6 +139,11 @@ func (s *simpleProvider) CreateContainerSecurityContext(pod *api.Pod, container
...
@@ -139,6 +139,11 @@ func (s *simpleProvider) CreateContainerSecurityContext(pod *api.Pod, container
sc
.
SELinuxOptions
=
seLinux
sc
.
SELinuxOptions
=
seLinux
}
}
annotations
,
err
:=
s
.
strategies
.
AppArmorStrategy
.
Generate
(
annotations
,
container
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
if
sc
.
Privileged
==
nil
{
if
sc
.
Privileged
==
nil
{
priv
:=
false
priv
:=
false
sc
.
Privileged
=
&
priv
sc
.
Privileged
=
&
priv
...
@@ -220,6 +225,7 @@ func (s *simpleProvider) ValidateContainerSecurityContext(pod *api.Pod, containe
...
@@ -220,6 +225,7 @@ func (s *simpleProvider) ValidateContainerSecurityContext(pod *api.Pod, containe
sc
:=
container
.
SecurityContext
sc
:=
container
.
SecurityContext
allErrs
=
append
(
allErrs
,
s
.
strategies
.
RunAsUserStrategy
.
Validate
(
pod
,
container
)
...
)
allErrs
=
append
(
allErrs
,
s
.
strategies
.
RunAsUserStrategy
.
Validate
(
pod
,
container
)
...
)
allErrs
=
append
(
allErrs
,
s
.
strategies
.
SELinuxStrategy
.
Validate
(
pod
,
container
)
...
)
allErrs
=
append
(
allErrs
,
s
.
strategies
.
SELinuxStrategy
.
Validate
(
pod
,
container
)
...
)
allErrs
=
append
(
allErrs
,
s
.
strategies
.
AppArmorStrategy
.
Validate
(
pod
,
container
)
...
)
if
!
s
.
psp
.
Spec
.
Privileged
&&
*
sc
.
Privileged
{
if
!
s
.
psp
.
Spec
.
Privileged
&&
*
sc
.
Privileged
{
allErrs
=
append
(
allErrs
,
field
.
Invalid
(
fldPath
.
Child
(
"privileged"
),
*
sc
.
Privileged
,
"Privileged containers are not allowed"
))
allErrs
=
append
(
allErrs
,
field
.
Invalid
(
fldPath
.
Child
(
"privileged"
),
*
sc
.
Privileged
,
"Privileged containers are not allowed"
))
...
...
pkg/security/podsecuritypolicy/provider_test.go
View file @
293770ef
...
@@ -22,13 +22,18 @@ import (
...
@@ -22,13 +22,18 @@ import (
"strings"
"strings"
"testing"
"testing"
"github.com/davecgh/go-spew/spew"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/security/apparmor"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
"k8s.io/kubernetes/pkg/util/diff"
"k8s.io/kubernetes/pkg/util/diff"
"k8s.io/kubernetes/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/util/validation/field"
)
)
const
defaultContainerName
=
"test-c"
func
TestCreatePodSecurityContextNonmutating
(
t
*
testing
.
T
)
{
func
TestCreatePodSecurityContextNonmutating
(
t
*
testing
.
T
)
{
// Create a pod with a security context that needs filling in
// Create a pod with a security context that needs filling in
createPod
:=
func
()
*
api
.
Pod
{
createPod
:=
func
()
*
api
.
Pod
{
...
@@ -303,6 +308,14 @@ func TestValidateContainerSecurityContextFailures(t *testing.T) {
...
@@ -303,6 +308,14 @@ func TestValidateContainerSecurityContextFailures(t *testing.T) {
Level
:
"bar"
,
Level
:
"bar"
,
}
}
failNilAppArmorPod
:=
defaultPod
()
failInvalidAppArmorPod
:=
defaultPod
()
apparmor
.
SetProfileName
(
failInvalidAppArmorPod
,
defaultContainerName
,
apparmor
.
ProfileNamePrefix
+
"foo"
)
failAppArmorPSP
:=
defaultPSP
()
failAppArmorPSP
.
Annotations
=
map
[
string
]
string
{
apparmor
.
AllowedProfilesAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
,
}
failPrivPod
:=
defaultPod
()
failPrivPod
:=
defaultPod
()
var
priv
bool
=
true
var
priv
bool
=
true
failPrivPod
.
Spec
.
Containers
[
0
]
.
SecurityContext
.
Privileged
=
&
priv
failPrivPod
.
Spec
.
Containers
[
0
]
.
SecurityContext
.
Privileged
=
&
priv
...
@@ -347,6 +360,16 @@ func TestValidateContainerSecurityContextFailures(t *testing.T) {
...
@@ -347,6 +360,16 @@ func TestValidateContainerSecurityContextFailures(t *testing.T) {
psp
:
failSELinuxPSP
,
psp
:
failSELinuxPSP
,
expectedError
:
"does not match required level"
,
expectedError
:
"does not match required level"
,
},
},
"failNilAppArmor"
:
{
pod
:
failNilAppArmorPod
,
psp
:
failAppArmorPSP
,
expectedError
:
"AppArmor profile must be set"
,
},
"failInvalidAppArmor"
:
{
pod
:
failInvalidAppArmorPod
,
psp
:
failAppArmorPSP
,
expectedError
:
"localhost/foo is not an allowed profile. Allowed values:
\"
runtime/default
\"
"
,
},
"failPrivPSP"
:
{
"failPrivPSP"
:
{
pod
:
failPrivPod
,
pod
:
failPrivPod
,
psp
:
defaultPSP
(),
psp
:
defaultPSP
(),
...
@@ -499,6 +522,7 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
...
@@ -499,6 +522,7 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
SecurityContext
:
&
api
.
PodSecurityContext
{},
SecurityContext
:
&
api
.
PodSecurityContext
{},
Containers
:
[]
api
.
Container
{
Containers
:
[]
api
.
Container
{
{
{
Name
:
defaultContainerName
,
SecurityContext
:
&
api
.
SecurityContext
{
SecurityContext
:
&
api
.
SecurityContext
{
// expected to be set by defaulting mechanisms
// expected to be set by defaulting mechanisms
Privileged
:
&
notPriv
,
Privileged
:
&
notPriv
,
...
@@ -510,7 +534,7 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
...
@@ -510,7 +534,7 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
}
}
}
}
//
fail
user strat
//
success
user strat
userPSP
:=
defaultPSP
()
userPSP
:=
defaultPSP
()
var
uid
int64
=
999
var
uid
int64
=
999
userPSP
.
Spec
.
RunAsUser
=
extensions
.
RunAsUserStrategyOptions
{
userPSP
.
Spec
.
RunAsUser
=
extensions
.
RunAsUserStrategyOptions
{
...
@@ -520,7 +544,7 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
...
@@ -520,7 +544,7 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
userPod
:=
defaultPod
()
userPod
:=
defaultPod
()
userPod
.
Spec
.
Containers
[
0
]
.
SecurityContext
.
RunAsUser
=
&
uid
userPod
.
Spec
.
Containers
[
0
]
.
SecurityContext
.
RunAsUser
=
&
uid
//
fail
selinux strat
//
success
selinux strat
seLinuxPSP
:=
defaultPSP
()
seLinuxPSP
:=
defaultPSP
()
seLinuxPSP
.
Spec
.
SELinux
=
extensions
.
SELinuxStrategyOptions
{
seLinuxPSP
.
Spec
.
SELinux
=
extensions
.
SELinuxStrategyOptions
{
Rule
:
extensions
.
SELinuxStrategyMustRunAs
,
Rule
:
extensions
.
SELinuxStrategyMustRunAs
,
...
@@ -533,6 +557,13 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
...
@@ -533,6 +557,13 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
Level
:
"foo"
,
Level
:
"foo"
,
}
}
appArmorPSP
:=
defaultPSP
()
appArmorPSP
.
Annotations
=
map
[
string
]
string
{
apparmor
.
AllowedProfilesAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
,
}
appArmorPod
:=
defaultPod
()
apparmor
.
SetProfileName
(
appArmorPod
,
defaultContainerName
,
apparmor
.
ProfileRuntimeDefault
)
privPSP
:=
defaultPSP
()
privPSP
:=
defaultPSP
()
privPSP
.
Spec
.
Privileged
=
true
privPSP
.
Spec
.
Privileged
=
true
privPod
:=
defaultPod
()
privPod
:=
defaultPod
()
...
@@ -591,6 +622,10 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
...
@@ -591,6 +622,10 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
pod
:
seLinuxPod
,
pod
:
seLinuxPod
,
psp
:
seLinuxPSP
,
psp
:
seLinuxPSP
,
},
},
"pass AppArmor allowed profiles"
:
{
pod
:
appArmorPod
,
psp
:
appArmorPSP
,
},
"pass priv validating PSP"
:
{
"pass priv validating PSP"
:
{
pod
:
privPod
,
pod
:
privPod
,
psp
:
privPSP
,
psp
:
privPSP
,
...
@@ -632,7 +667,7 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
...
@@ -632,7 +667,7 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) {
}
}
errs
:=
provider
.
ValidateContainerSecurityContext
(
v
.
pod
,
&
v
.
pod
.
Spec
.
Containers
[
0
],
field
.
NewPath
(
""
))
errs
:=
provider
.
ValidateContainerSecurityContext
(
v
.
pod
,
&
v
.
pod
.
Spec
.
Containers
[
0
],
field
.
NewPath
(
""
))
if
len
(
errs
)
!=
0
{
if
len
(
errs
)
!=
0
{
t
.
Errorf
(
"%s expected validation pass but received errors %v
"
,
k
,
errs
)
t
.
Errorf
(
"%s expected validation pass but received errors %v
\n
%s"
,
k
,
errs
,
spew
.
Sdump
(
v
.
pod
.
ObjectMeta
)
)
continue
continue
}
}
}
}
...
@@ -748,6 +783,7 @@ func defaultPod() *api.Pod {
...
@@ -748,6 +783,7 @@ func defaultPod() *api.Pod {
},
},
Containers
:
[]
api
.
Container
{
Containers
:
[]
api
.
Container
{
{
{
Name
:
defaultContainerName
,
SecurityContext
:
&
api
.
SecurityContext
{
SecurityContext
:
&
api
.
SecurityContext
{
// expected to be set by defaulting mechanisms
// expected to be set by defaulting mechanisms
Privileged
:
&
notPriv
,
Privileged
:
&
notPriv
,
...
...
pkg/security/podsecuritypolicy/types.go
View file @
293770ef
...
@@ -19,6 +19,7 @@ package podsecuritypolicy
...
@@ -19,6 +19,7 @@ package podsecuritypolicy
import
(
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/apparmor"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/capabilities"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/capabilities"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/group"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/group"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/selinux"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/selinux"
...
@@ -58,6 +59,7 @@ type StrategyFactory interface {
...
@@ -58,6 +59,7 @@ type StrategyFactory interface {
type
ProviderStrategies
struct
{
type
ProviderStrategies
struct
{
RunAsUserStrategy
user
.
RunAsUserStrategy
RunAsUserStrategy
user
.
RunAsUserStrategy
SELinuxStrategy
selinux
.
SELinuxStrategy
SELinuxStrategy
selinux
.
SELinuxStrategy
AppArmorStrategy
apparmor
.
Strategy
FSGroupStrategy
group
.
GroupStrategy
FSGroupStrategy
group
.
GroupStrategy
SupplementalGroupStrategy
group
.
GroupStrategy
SupplementalGroupStrategy
group
.
GroupStrategy
CapabilitiesStrategy
capabilities
.
Strategy
CapabilitiesStrategy
capabilities
.
Strategy
...
...
plugin/pkg/admission/security/podsecuritypolicy/admission_test.go
View file @
293770ef
...
@@ -22,6 +22,8 @@ import (
...
@@ -22,6 +22,8 @@ import (
"strings"
"strings"
"testing"
"testing"
"github.com/stretchr/testify/assert"
kadmission
"k8s.io/kubernetes/pkg/admission"
kadmission
"k8s.io/kubernetes/pkg/admission"
kapi
"k8s.io/kubernetes/pkg/api"
kapi
"k8s.io/kubernetes/pkg/api"
extensions
"k8s.io/kubernetes/pkg/apis/extensions"
extensions
"k8s.io/kubernetes/pkg/apis/extensions"
...
@@ -29,11 +31,14 @@ import (
...
@@ -29,11 +31,14 @@ import (
"k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/client/cache"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
clientsetfake
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
clientsetfake
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/security/apparmor"
kpsp
"k8s.io/kubernetes/pkg/security/podsecuritypolicy"
kpsp
"k8s.io/kubernetes/pkg/security/podsecuritypolicy"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
diff
"k8s.io/kubernetes/pkg/util/diff"
diff
"k8s.io/kubernetes/pkg/util/diff"
)
)
const
defaultContainerName
=
"test-c"
func
NewTestAdmission
(
store
cache
.
Store
,
kclient
clientset
.
Interface
)
kadmission
.
Interface
{
func
NewTestAdmission
(
store
cache
.
Store
,
kclient
clientset
.
Interface
)
kadmission
.
Interface
{
return
&
podSecurityPolicyPlugin
{
return
&
podSecurityPolicyPlugin
{
Handler
:
kadmission
.
NewHandler
(
kadmission
.
Create
),
Handler
:
kadmission
.
NewHandler
(
kadmission
.
Create
),
...
@@ -610,6 +615,85 @@ func TestAdmitSELinux(t *testing.T) {
...
@@ -610,6 +615,85 @@ func TestAdmitSELinux(t *testing.T) {
}
}
}
}
func
TestAdmitAppArmor
(
t
*
testing
.
T
)
{
createPodWithAppArmor
:=
func
(
profile
string
)
*
kapi
.
Pod
{
pod
:=
goodPod
()
apparmor
.
SetProfileName
(
pod
,
defaultContainerName
,
profile
)
return
pod
}
unconstrainedPSP
:=
restrictivePSP
()
defaultedPSP
:=
restrictivePSP
()
defaultedPSP
.
Annotations
=
map
[
string
]
string
{
apparmor
.
DefaultProfileAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
,
}
appArmorPSP
:=
restrictivePSP
()
appArmorPSP
.
Annotations
=
map
[
string
]
string
{
apparmor
.
AllowedProfilesAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
,
}
appArmorDefaultPSP
:=
restrictivePSP
()
appArmorDefaultPSP
.
Annotations
=
map
[
string
]
string
{
apparmor
.
DefaultProfileAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
,
apparmor
.
AllowedProfilesAnnotationKey
:
apparmor
.
ProfileRuntimeDefault
+
","
+
apparmor
.
ProfileNamePrefix
+
"foo"
,
}
tests
:=
map
[
string
]
struct
{
pod
*
kapi
.
Pod
psp
*
extensions
.
PodSecurityPolicy
shouldPass
bool
expectedProfile
string
}{
"unconstrained with no profile"
:
{
pod
:
goodPod
(),
psp
:
unconstrainedPSP
,
shouldPass
:
true
,
expectedProfile
:
""
,
},
"unconstrained with profile"
:
{
pod
:
createPodWithAppArmor
(
apparmor
.
ProfileRuntimeDefault
),
psp
:
unconstrainedPSP
,
shouldPass
:
true
,
expectedProfile
:
apparmor
.
ProfileRuntimeDefault
,
},
"unconstrained with default profile"
:
{
pod
:
goodPod
(),
psp
:
defaultedPSP
,
shouldPass
:
true
,
expectedProfile
:
apparmor
.
ProfileRuntimeDefault
,
},
"AppArmor enforced with no profile"
:
{
pod
:
goodPod
(),
psp
:
appArmorPSP
,
shouldPass
:
false
,
},
"AppArmor enforced with default profile"
:
{
pod
:
goodPod
(),
psp
:
appArmorDefaultPSP
,
shouldPass
:
true
,
expectedProfile
:
apparmor
.
ProfileRuntimeDefault
,
},
"AppArmor enforced with good profile"
:
{
pod
:
createPodWithAppArmor
(
apparmor
.
ProfileNamePrefix
+
"foo"
),
psp
:
appArmorDefaultPSP
,
shouldPass
:
true
,
expectedProfile
:
apparmor
.
ProfileNamePrefix
+
"foo"
,
},
"AppArmor enforced with local profile"
:
{
pod
:
createPodWithAppArmor
(
apparmor
.
ProfileNamePrefix
+
"bar"
),
psp
:
appArmorPSP
,
shouldPass
:
false
,
},
}
for
k
,
v
:=
range
tests
{
testPSPAdmit
(
k
,
[]
*
extensions
.
PodSecurityPolicy
{
v
.
psp
},
v
.
pod
,
v
.
shouldPass
,
v
.
psp
.
Name
,
t
)
if
v
.
shouldPass
{
assert
.
Equal
(
t
,
v
.
expectedProfile
,
apparmor
.
GetProfileName
(
v
.
pod
,
defaultContainerName
),
k
)
}
}
}
func
TestAdmitRunAsUser
(
t
*
testing
.
T
)
{
func
TestAdmitRunAsUser
(
t
*
testing
.
T
)
{
createPodWithRunAsUser
:=
func
(
user
int64
)
*
kapi
.
Pod
{
createPodWithRunAsUser
:=
func
(
user
int64
)
*
kapi
.
Pod
{
pod
:=
goodPod
()
pod
:=
goodPod
()
...
@@ -1212,6 +1296,7 @@ func goodPod() *kapi.Pod {
...
@@ -1212,6 +1296,7 @@ func goodPod() *kapi.Pod {
SecurityContext
:
&
kapi
.
PodSecurityContext
{},
SecurityContext
:
&
kapi
.
PodSecurityContext
{},
Containers
:
[]
kapi
.
Container
{
Containers
:
[]
kapi
.
Container
{
{
{
Name
:
defaultContainerName
,
SecurityContext
:
&
kapi
.
SecurityContext
{},
SecurityContext
:
&
kapi
.
SecurityContext
{},
},
},
},
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment