Merge pull request #89225 from andrewsykim/apparmor-api

move apparmor annotation constants to k8s.io/api/core/v1
This commit is contained in:
Kubernetes Prow Robot 2020-04-12 19:11:50 -07:00 committed by GitHub
commit 6239abe698
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 131 additions and 147 deletions

View File

@ -13,7 +13,7 @@ go_library(
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/security/apparmor:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
], ],
@ -39,7 +39,7 @@ go_test(
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/security/apparmor:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",

View File

@ -19,11 +19,11 @@ package pod
import ( import (
"strings" "strings"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/security/apparmor"
) )
// ContainerType signifies container type // ContainerType signifies container type
@ -363,7 +363,7 @@ func dropDisabledFields(
if !utilfeature.DefaultFeatureGate.Enabled(features.AppArmor) && !appArmorInUse(oldPodAnnotations) { if !utilfeature.DefaultFeatureGate.Enabled(features.AppArmor) && !appArmorInUse(oldPodAnnotations) {
for k := range podAnnotations { for k := range podAnnotations {
if strings.HasPrefix(k, apparmor.ContainerAnnotationKeyPrefix) { if strings.HasPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
delete(podAnnotations, k) delete(podAnnotations, k)
} }
} }
@ -590,7 +590,7 @@ func procMountInUse(podSpec *api.PodSpec) bool {
// appArmorInUse returns true if the pod has apparmor related information // appArmorInUse returns true if the pod has apparmor related information
func appArmorInUse(podAnnotations map[string]string) bool { func appArmorInUse(podAnnotations map[string]string) bool {
for k := range podAnnotations { for k := range podAnnotations {
if strings.HasPrefix(k, apparmor.ContainerAnnotationKeyPrefix) { if strings.HasPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
return true return true
} }
} }

View File

@ -23,6 +23,8 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
@ -32,7 +34,6 @@ import (
featuregatetesting "k8s.io/component-base/featuregate/testing" featuregatetesting "k8s.io/component-base/featuregate/testing"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/security/apparmor"
) )
func TestVisitContainers(t *testing.T) { func TestVisitContainers(t *testing.T) {
@ -1026,7 +1027,7 @@ func TestDropEmptyDirSizeLimit(t *testing.T) {
func TestDropAppArmor(t *testing.T) { func TestDropAppArmor(t *testing.T) {
podWithAppArmor := func() *api.Pod { podWithAppArmor := func() *api.Pod {
return &api.Pod{ return &api.Pod{
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"a": "1", apparmor.ContainerAnnotationKeyPrefix + "foo": "default"}}, ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"a": "1", v1.AppArmorBetaContainerAnnotationKeyPrefix + "foo": "default"}},
Spec: api.PodSpec{}, Spec: api.PodSpec{},
} }
} }

View File

@ -56,7 +56,6 @@ go_test(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/capabilities:go_default_library", "//pkg/capabilities:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/security/apparmor:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -173,7 +173,7 @@ func ValidatePodSpecificAnnotationUpdates(newPod, oldPod *core.Pod, fldPath *fie
if newVal, exists := newAnnotations[k]; exists && newVal == oldVal { if newVal, exists := newAnnotations[k]; exists && newVal == oldVal {
continue // No change. continue // No change.
} }
if strings.HasPrefix(k, apparmor.ContainerAnnotationKeyPrefix) { if strings.HasPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "may not remove or update AppArmor annotations")) allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "may not remove or update AppArmor annotations"))
} }
if k == core.MirrorPodAnnotationKey { if k == core.MirrorPodAnnotationKey {
@ -185,7 +185,7 @@ func ValidatePodSpecificAnnotationUpdates(newPod, oldPod *core.Pod, fldPath *fie
if _, ok := oldAnnotations[k]; ok { if _, ok := oldAnnotations[k]; ok {
continue // No change. continue // No change.
} }
if strings.HasPrefix(k, apparmor.ContainerAnnotationKeyPrefix) { if strings.HasPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "may not add AppArmor annotations")) allErrs = append(allErrs, field.Forbidden(fldPath.Key(k), "may not add AppArmor annotations"))
} }
if k == core.MirrorPodAnnotationKey { if k == core.MirrorPodAnnotationKey {
@ -3572,10 +3572,10 @@ func ValidateSeccompPodAnnotations(annotations map[string]string, fldPath *field
func ValidateAppArmorPodAnnotations(annotations map[string]string, spec *core.PodSpec, fldPath *field.Path) field.ErrorList { func ValidateAppArmorPodAnnotations(annotations map[string]string, spec *core.PodSpec, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
for k, p := range annotations { for k, p := range annotations {
if !strings.HasPrefix(k, apparmor.ContainerAnnotationKeyPrefix) { if !strings.HasPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
continue continue
} }
containerName := strings.TrimPrefix(k, apparmor.ContainerAnnotationKeyPrefix) containerName := strings.TrimPrefix(k, v1.AppArmorBetaContainerAnnotationKeyPrefix)
if !podSpecHasContainer(spec, containerName) { if !podSpecHasContainer(spec, containerName) {
allErrs = append(allErrs, field.Invalid(fldPath.Key(k), containerName, "container not found")) allErrs = append(allErrs, field.Invalid(fldPath.Key(k), containerName, "container not found"))
} }

View File

@ -35,7 +35,6 @@ import (
"k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/capabilities" "k8s.io/kubernetes/pkg/capabilities"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/security/apparmor"
utilpointer "k8s.io/utils/pointer" utilpointer "k8s.io/utils/pointer"
) )
@ -7293,7 +7292,7 @@ func TestValidatePod(t *testing.T) {
Name: "123", Name: "123",
Namespace: "ns", Namespace: "ns",
Annotations: map[string]string{ Annotations: map[string]string{
apparmor.ContainerAnnotationKeyPrefix + "ctr": apparmor.ProfileRuntimeDefault, v1.AppArmorBetaContainerAnnotationKeyPrefix + "ctr": v1.AppArmorBetaProfileRuntimeDefault,
}, },
}, },
Spec: validPodSpec(nil), Spec: validPodSpec(nil),
@ -7303,7 +7302,7 @@ func TestValidatePod(t *testing.T) {
Name: "123", Name: "123",
Namespace: "ns", Namespace: "ns",
Annotations: map[string]string{ Annotations: map[string]string{
apparmor.ContainerAnnotationKeyPrefix + "init-ctr": apparmor.ProfileRuntimeDefault, v1.AppArmorBetaContainerAnnotationKeyPrefix + "init-ctr": v1.AppArmorBetaProfileRuntimeDefault,
}, },
}, },
Spec: core.PodSpec{ Spec: core.PodSpec{
@ -7318,7 +7317,7 @@ func TestValidatePod(t *testing.T) {
Name: "123", Name: "123",
Namespace: "ns", Namespace: "ns",
Annotations: map[string]string{ Annotations: map[string]string{
apparmor.ContainerAnnotationKeyPrefix + "ctr": apparmor.ProfileNamePrefix + "foo", v1.AppArmorBetaContainerAnnotationKeyPrefix + "ctr": v1.AppArmorBetaProfileNamePrefix + "foo",
}, },
}, },
Spec: validPodSpec(nil), Spec: validPodSpec(nil),
@ -8017,9 +8016,9 @@ func TestValidatePod(t *testing.T) {
Name: "123", Name: "123",
Namespace: "ns", Namespace: "ns",
Annotations: map[string]string{ Annotations: map[string]string{
apparmor.ContainerAnnotationKeyPrefix + "ctr": apparmor.ProfileRuntimeDefault, v1.AppArmorBetaContainerAnnotationKeyPrefix + "ctr": v1.AppArmorBetaProfileRuntimeDefault,
apparmor.ContainerAnnotationKeyPrefix + "init-ctr": apparmor.ProfileRuntimeDefault, v1.AppArmorBetaContainerAnnotationKeyPrefix + "init-ctr": v1.AppArmorBetaProfileRuntimeDefault,
apparmor.ContainerAnnotationKeyPrefix + "fake-ctr": apparmor.ProfileRuntimeDefault, v1.AppArmorBetaContainerAnnotationKeyPrefix + "fake-ctr": v1.AppArmorBetaProfileRuntimeDefault,
}, },
}, },
Spec: core.PodSpec{ Spec: core.PodSpec{
@ -8037,7 +8036,7 @@ func TestValidatePod(t *testing.T) {
Name: "123", Name: "123",
Namespace: "ns", Namespace: "ns",
Annotations: map[string]string{ Annotations: map[string]string{
apparmor.ContainerAnnotationKeyPrefix + "ctr": "bad-name", v1.AppArmorBetaContainerAnnotationKeyPrefix + "ctr": "bad-name",
}, },
}, },
Spec: validPodSpec(nil), Spec: validPodSpec(nil),
@ -8050,7 +8049,7 @@ func TestValidatePod(t *testing.T) {
Name: "123", Name: "123",
Namespace: "ns", Namespace: "ns",
Annotations: map[string]string{ Annotations: map[string]string{
apparmor.ContainerAnnotationKeyPrefix + "ctr": "runtime/foo", v1.AppArmorBetaContainerAnnotationKeyPrefix + "ctr": "runtime/foo",
}, },
}, },
Spec: validPodSpec(nil), Spec: validPodSpec(nil),

View File

@ -18,6 +18,7 @@ go_library(
"//pkg/security/apparmor:go_default_library", "//pkg/security/apparmor:go_default_library",
"//pkg/security/podsecuritypolicy/seccomp:go_default_library", "//pkg/security/podsecuritypolicy/seccomp:go_default_library",
"//pkg/security/podsecuritypolicy/util:go_default_library", "//pkg/security/podsecuritypolicy/util:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
@ -32,9 +33,9 @@ go_test(
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/policy:go_default_library", "//pkg/apis/policy:go_default_library",
"//pkg/security/apparmor:go_default_library",
"//pkg/security/podsecuritypolicy/seccomp:go_default_library", "//pkg/security/podsecuritypolicy/seccomp:go_default_library",
"//pkg/security/podsecuritypolicy/util:go_default_library", "//pkg/security/podsecuritypolicy/util:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",

View File

@ -22,6 +22,7 @@ import (
"regexp" "regexp"
"strings" "strings"
"k8s.io/api/core/v1"
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
@ -129,15 +130,15 @@ func ValidatePodSecurityPolicySpec(spec *policy.PodSecurityPolicySpec, fldPath *
func ValidatePodSecurityPolicySpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { func ValidatePodSecurityPolicySpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if p := annotations[apparmor.DefaultProfileAnnotationKey]; p != "" { if p := annotations[v1.AppArmorBetaDefaultProfileAnnotationKey]; p != "" {
if err := apparmor.ValidateProfileFormat(p); err != nil { if err := apparmor.ValidateProfileFormat(p); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Key(apparmor.DefaultProfileAnnotationKey), p, err.Error())) allErrs = append(allErrs, field.Invalid(fldPath.Key(v1.AppArmorBetaDefaultProfileAnnotationKey), p, err.Error()))
} }
} }
if allowed := annotations[apparmor.AllowedProfilesAnnotationKey]; allowed != "" { if allowed := annotations[v1.AppArmorBetaAllowedProfilesAnnotationKey]; allowed != "" {
for _, p := range strings.Split(allowed, ",") { for _, p := range strings.Split(allowed, ",") {
if err := apparmor.ValidateProfileFormat(p); err != nil { if err := apparmor.ValidateProfileFormat(p); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Key(apparmor.AllowedProfilesAnnotationKey), allowed, err.Error())) allErrs = append(allErrs, field.Invalid(fldPath.Key(v1.AppArmorBetaAllowedProfilesAnnotationKey), allowed, err.Error()))
} }
} }
} }

View File

@ -21,12 +21,12 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/security/apparmor"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp" "k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp"
psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util" psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
"k8s.io/utils/pointer" "k8s.io/utils/pointer"
@ -223,11 +223,11 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
invalidAppArmorDefault := validPSP() invalidAppArmorDefault := validPSP()
invalidAppArmorDefault.Annotations = map[string]string{ invalidAppArmorDefault.Annotations = map[string]string{
apparmor.DefaultProfileAnnotationKey: "not-good", v1.AppArmorBetaDefaultProfileAnnotationKey: "not-good",
} }
invalidAppArmorAllowed := validPSP() invalidAppArmorAllowed := validPSP()
invalidAppArmorAllowed.Annotations = map[string]string{ invalidAppArmorAllowed.Annotations = map[string]string{
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault + ",not-good", v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault + ",not-good",
} }
invalidAllowedUnsafeSysctlPattern := validPSP() invalidAllowedUnsafeSysctlPattern := validPSP()
@ -521,8 +521,8 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
validAppArmor := validPSP() validAppArmor := validPSP()
validAppArmor.Annotations = map[string]string{ validAppArmor.Annotations = map[string]string{
apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaDefaultProfileAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault + "," + apparmor.ProfileNamePrefix + "foo", v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault + "," + v1.AppArmorBetaProfileNamePrefix + "foo",
} }
withForbiddenSysctl := validPSP() withForbiddenSysctl := validPSP()

View File

@ -55,7 +55,6 @@ go_library(
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types:go_default_library",
"//pkg/kubelet/util/cache:go_default_library", "//pkg/kubelet/util/cache:go_default_library",
"//pkg/kubelet/util/ioutils:go_default_library", "//pkg/kubelet/util/ioutils:go_default_library",
"//pkg/security/apparmor:go_default_library",
"//pkg/util/parsers:go_default_library", "//pkg/util/parsers:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
@ -111,7 +110,7 @@ go_test(
"//pkg/kubelet/dockershim/network/testing:go_default_library", "//pkg/kubelet/dockershim/network/testing:go_default_library",
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types:go_default_library",
"//pkg/kubelet/util/cache:go_default_library", "//pkg/kubelet/util/cache:go_default_library",
"//pkg/security/apparmor:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
"//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library", "//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library",
"//vendor/github.com/blang/semver:go_default_library", "//vendor/github.com/blang/semver:go_default_library",
@ -123,12 +122,6 @@ go_test(
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library",
] + select({ ] + select({
"@io_bazel_rules_go//go/platform:android": [
"//staging/src/k8s.io/api/core/v1:go_default_library",
],
"@io_bazel_rules_go//go/platform:linux": [
"//staging/src/k8s.io/api/core/v1:go_default_library",
],
"@io_bazel_rules_go//go/platform:windows": [ "@io_bazel_rules_go//go/platform:windows": [
"//vendor/golang.org/x/sys/windows/registry:go_default_library", "//vendor/golang.org/x/sys/windows/registry:go_default_library",
], ],

View File

@ -31,12 +31,12 @@ import (
dockernat "github.com/docker/go-connections/nat" dockernat "github.com/docker/go-connections/nat"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/api/core/v1"
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/credentialprovider" "k8s.io/kubernetes/pkg/credentialprovider"
"k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker" "k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker"
"k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/security/apparmor"
"k8s.io/kubernetes/pkg/util/parsers" "k8s.io/kubernetes/pkg/util/parsers"
) )
@ -361,18 +361,18 @@ func ensureSandboxImageExists(client libdocker.Interface, image string) error {
} }
func getAppArmorOpts(profile string) ([]dockerOpt, error) { func getAppArmorOpts(profile string) ([]dockerOpt, error) {
if profile == "" || profile == apparmor.ProfileRuntimeDefault { if profile == "" || profile == v1.AppArmorBetaProfileRuntimeDefault {
// The docker applies the default profile by default. // The docker applies the default profile by default.
return nil, nil return nil, nil
} }
// Return unconfined profile explicitly // Return unconfined profile explicitly
if profile == apparmor.ProfileNameUnconfined { if profile == v1.AppArmorBetaProfileNameUnconfined {
return []dockerOpt{{"apparmor", apparmor.ProfileNameUnconfined, ""}}, nil return []dockerOpt{{"apparmor", v1.AppArmorBetaProfileNameUnconfined, ""}}, nil
} }
// Assume validation has already happened. // Assume validation has already happened.
profileName := strings.TrimPrefix(profile, apparmor.ProfileNamePrefix) profileName := strings.TrimPrefix(profile, v1.AppArmorBetaProfileNamePrefix)
return []dockerOpt{{"apparmor", profileName, ""}}, nil return []dockerOpt{{"apparmor", profileName, ""}}, nil
} }

View File

@ -28,9 +28,9 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"k8s.io/api/core/v1"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker" "k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker"
"k8s.io/kubernetes/pkg/security/apparmor"
) )
func TestLabelsAndAnnotationsRoundTrip(t *testing.T) { func TestLabelsAndAnnotationsRoundTrip(t *testing.T) {
@ -66,7 +66,7 @@ func TestGetApparmorSecurityOpts(t *testing.T) {
expectedOpts: []string{}, expectedOpts: []string{},
}, { }, {
msg: "AppArmor local profile", msg: "AppArmor local profile",
config: makeConfig(apparmor.ProfileNamePrefix + "foo"), config: makeConfig(v1.AppArmorBetaProfileNamePrefix + "foo"),
expectedOpts: []string{"apparmor=foo"}, expectedOpts: []string{"apparmor=foo"},
}} }}

View File

@ -22,29 +22,11 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
) )
// TODO: Move these values into the API package.
const (
// The prefix to an annotation key specifying a container profile.
ContainerAnnotationKeyPrefix = "container.apparmor.security.beta.kubernetes.io/"
// The annotation key specifying the default AppArmor profile.
DefaultProfileAnnotationKey = "apparmor.security.beta.kubernetes.io/defaultProfileName"
// The annotation key specifying the allowed AppArmor profiles.
AllowedProfilesAnnotationKey = "apparmor.security.beta.kubernetes.io/allowedProfileNames"
// The profile specifying the runtime default.
ProfileRuntimeDefault = "runtime/default"
// The prefix for specifying profiles loaded on the node.
ProfileNamePrefix = "localhost/"
// Unconfined profile
ProfileNameUnconfined = "unconfined"
)
// Checks whether app armor is required for pod to be run. // Checks whether app armor is required for pod to be run.
func isRequired(pod *v1.Pod) bool { func isRequired(pod *v1.Pod) bool {
for key, value := range pod.Annotations { for key, value := range pod.Annotations {
if strings.HasPrefix(key, ContainerAnnotationKeyPrefix) { if strings.HasPrefix(key, v1.AppArmorBetaContainerAnnotationKeyPrefix) {
return value != ProfileNameUnconfined return value != v1.AppArmorBetaProfileNameUnconfined
} }
} }
return false return false
@ -58,7 +40,7 @@ func GetProfileName(pod *v1.Pod, containerName string) string {
// GetProfileNameFromPodAnnotations gets the name of the profile to use with container from // GetProfileNameFromPodAnnotations gets the name of the profile to use with container from
// pod annotations // pod annotations
func GetProfileNameFromPodAnnotations(annotations map[string]string, containerName string) string { func GetProfileNameFromPodAnnotations(annotations map[string]string, containerName string) string {
return annotations[ContainerAnnotationKeyPrefix+containerName] return annotations[v1.AppArmorBetaContainerAnnotationKeyPrefix+containerName]
} }
// SetProfileName sets the name of the profile to use with the container. // SetProfileName sets the name of the profile to use with the container.
@ -66,7 +48,7 @@ func SetProfileName(pod *v1.Pod, containerName, profileName string) error {
if pod.Annotations == nil { if pod.Annotations == nil {
pod.Annotations = map[string]string{} pod.Annotations = map[string]string{}
} }
pod.Annotations[ContainerAnnotationKeyPrefix+containerName] = profileName pod.Annotations[v1.AppArmorBetaContainerAnnotationKeyPrefix+containerName] = profileName
return nil return nil
} }
@ -75,6 +57,6 @@ func SetProfileNameFromPodAnnotations(annotations map[string]string, containerNa
if annotations == nil { if annotations == nil {
return nil return nil
} }
annotations[ContainerAnnotationKeyPrefix+containerName] = profileName annotations[v1.AppArmorBetaContainerAnnotationKeyPrefix+containerName] = profileName
return nil return nil
} }

View File

@ -125,8 +125,8 @@ func validateProfile(profile string, loadedProfiles map[string]bool) error {
return err return err
} }
if strings.HasPrefix(profile, ProfileNamePrefix) { if strings.HasPrefix(profile, v1.AppArmorBetaProfileNamePrefix) {
profileName := strings.TrimPrefix(profile, ProfileNamePrefix) profileName := strings.TrimPrefix(profile, v1.AppArmorBetaProfileNamePrefix)
if !loadedProfiles[profileName] { if !loadedProfiles[profileName] {
return fmt.Errorf("profile %q is not loaded", profileName) return fmt.Errorf("profile %q is not loaded", profileName)
} }
@ -137,10 +137,10 @@ func validateProfile(profile string, loadedProfiles map[string]bool) error {
// ValidateProfileFormat checks the format of the profile. // ValidateProfileFormat checks the format of the profile.
func ValidateProfileFormat(profile string) error { func ValidateProfileFormat(profile string) error {
if profile == "" || profile == ProfileRuntimeDefault || profile == ProfileNameUnconfined { if profile == "" || profile == v1.AppArmorBetaProfileRuntimeDefault || profile == v1.AppArmorBetaProfileNameUnconfined {
return nil return nil
} }
if !strings.HasPrefix(profile, ProfileNamePrefix) { if !strings.HasPrefix(profile, v1.AppArmorBetaProfileNamePrefix) {
return fmt.Errorf("invalid AppArmor profile name: %q", profile) return fmt.Errorf("invalid AppArmor profile name: %q", profile)
} }
return nil return nil

View File

@ -62,13 +62,13 @@ func TestValidateProfile(t *testing.T) {
expectValid bool expectValid bool
}{ }{
{"", true}, {"", true},
{ProfileRuntimeDefault, true}, {v1.AppArmorBetaProfileRuntimeDefault, true},
{ProfileNameUnconfined, true}, {v1.AppArmorBetaProfileNameUnconfined, true},
{"baz", false}, // Missing local prefix. {"baz", false}, // Missing local prefix.
{ProfileNamePrefix + "/usr/sbin/ntpd", true}, {v1.AppArmorBetaProfileNamePrefix + "/usr/sbin/ntpd", true},
{ProfileNamePrefix + "foo-bar", true}, {v1.AppArmorBetaProfileNamePrefix + "foo-bar", true},
{ProfileNamePrefix + "unloaded", false}, // Not loaded. {v1.AppArmorBetaProfileNamePrefix + "unloaded", false}, // Not loaded.
{ProfileNamePrefix + "", false}, {v1.AppArmorBetaProfileNamePrefix + "", false},
} }
for _, test := range tests { for _, test := range tests {
@ -92,8 +92,8 @@ func TestValidateBadHost(t *testing.T) {
expectValid bool expectValid bool
}{ }{
{"", true}, {"", true},
{ProfileRuntimeDefault, false}, {v1.AppArmorBetaProfileRuntimeDefault, false},
{ProfileNamePrefix + "docker-default", false}, {v1.AppArmorBetaProfileNamePrefix + "docker-default", false},
} }
for _, test := range tests { for _, test := range tests {
@ -116,13 +116,13 @@ func TestValidateValidHost(t *testing.T) {
expectValid bool expectValid bool
}{ }{
{"", true}, {"", true},
{ProfileRuntimeDefault, true}, {v1.AppArmorBetaProfileRuntimeDefault, true},
{ProfileNamePrefix + "docker-default", true}, {v1.AppArmorBetaProfileNamePrefix + "docker-default", true},
{ProfileNamePrefix + "foo-container", true}, {v1.AppArmorBetaProfileNamePrefix + "foo-container", true},
{ProfileNamePrefix + "/usr/sbin/ntpd", true}, {v1.AppArmorBetaProfileNamePrefix + "/usr/sbin/ntpd", true},
{"docker-default", false}, {"docker-default", false},
{ProfileNamePrefix + "foo", false}, {v1.AppArmorBetaProfileNamePrefix + "foo", false},
{ProfileNamePrefix + "", false}, {v1.AppArmorBetaProfileNamePrefix + "", false},
} }
for _, test := range tests { for _, test := range tests {
@ -138,9 +138,9 @@ func TestValidateValidHost(t *testing.T) {
pod := &v1.Pod{ pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{ Annotations: map[string]string{
ContainerAnnotationKeyPrefix + "init": ProfileNamePrefix + "foo-container", v1.AppArmorBetaContainerAnnotationKeyPrefix + "init": v1.AppArmorBetaProfileNamePrefix + "foo-container",
ContainerAnnotationKeyPrefix + "test1": ProfileRuntimeDefault, v1.AppArmorBetaContainerAnnotationKeyPrefix + "test1": v1.AppArmorBetaProfileRuntimeDefault,
ContainerAnnotationKeyPrefix + "test2": ProfileNamePrefix + "docker-default", v1.AppArmorBetaContainerAnnotationKeyPrefix + "test2": v1.AppArmorBetaProfileNamePrefix + "docker-default",
}, },
}, },
Spec: v1.PodSpec{ Spec: v1.PodSpec{
@ -176,7 +176,7 @@ func TestParseProfileName(t *testing.T) {
func getPodWithProfile(profile string) *v1.Pod { func getPodWithProfile(profile string) *v1.Pod {
annotations := map[string]string{ annotations := map[string]string{
ContainerAnnotationKeyPrefix + "test": profile, v1.AppArmorBetaContainerAnnotationKeyPrefix + "test": profile,
} }
if profile == "" { if profile == "" {
annotations = map[string]string{ annotations = map[string]string{

View File

@ -14,6 +14,7 @@ go_library(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/security/apparmor:go_default_library", "//pkg/security/apparmor:go_default_library",
"//pkg/util/maps:go_default_library", "//pkg/util/maps:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
], ],
) )
@ -24,8 +25,8 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/security/apparmor:go_default_library",
"//pkg/util/maps:go_default_library", "//pkg/util/maps:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/github.com/davecgh/go-spew/spew:go_default_library", "//vendor/github.com/davecgh/go-spew/spew:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/security/apparmor" "k8s.io/kubernetes/pkg/security/apparmor"
@ -47,7 +48,7 @@ var _ Strategy = &strategy{}
// NewStrategy creates a new strategy that enforces AppArmor profile constraints. // NewStrategy creates a new strategy that enforces AppArmor profile constraints.
func NewStrategy(pspAnnotations map[string]string) Strategy { func NewStrategy(pspAnnotations map[string]string) Strategy {
var allowedProfiles map[string]bool var allowedProfiles map[string]bool
if allowed, ok := pspAnnotations[apparmor.AllowedProfilesAnnotationKey]; ok { if allowed, ok := pspAnnotations[v1.AppArmorBetaAllowedProfilesAnnotationKey]; ok {
profiles := strings.Split(allowed, ",") profiles := strings.Split(allowed, ",")
allowedProfiles = make(map[string]bool, len(profiles)) allowedProfiles = make(map[string]bool, len(profiles))
for _, p := range profiles { for _, p := range profiles {
@ -55,16 +56,16 @@ func NewStrategy(pspAnnotations map[string]string) Strategy {
} }
} }
return &strategy{ return &strategy{
defaultProfile: pspAnnotations[apparmor.DefaultProfileAnnotationKey], defaultProfile: pspAnnotations[v1.AppArmorBetaDefaultProfileAnnotationKey],
allowedProfiles: allowedProfiles, allowedProfiles: allowedProfiles,
allowedProfilesString: pspAnnotations[apparmor.AllowedProfilesAnnotationKey], allowedProfilesString: pspAnnotations[v1.AppArmorBetaAllowedProfilesAnnotationKey],
} }
} }
func (s *strategy) Generate(annotations map[string]string, container *api.Container) (map[string]string, error) { func (s *strategy) Generate(annotations map[string]string, container *api.Container) (map[string]string, error) {
copy := maps.CopySS(annotations) copy := maps.CopySS(annotations)
if annotations[apparmor.ContainerAnnotationKeyPrefix+container.Name] != "" { if annotations[v1.AppArmorBetaContainerAnnotationKeyPrefix+container.Name] != "" {
// Profile already set, nothing to do. // Profile already set, nothing to do.
return copy, nil return copy, nil
} }
@ -78,7 +79,7 @@ func (s *strategy) Generate(annotations map[string]string, container *api.Contai
copy = map[string]string{} copy = map[string]string{}
} }
// Add the default profile. // Add the default profile.
copy[apparmor.ContainerAnnotationKeyPrefix+container.Name] = s.defaultProfile copy[v1.AppArmorBetaContainerAnnotationKeyPrefix+container.Name] = s.defaultProfile
return copy, nil return copy, nil
} }
@ -90,7 +91,7 @@ func (s *strategy) Validate(pod *api.Pod, container *api.Container) field.ErrorL
} }
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
fieldPath := field.NewPath("pod", "metadata", "annotations").Key(apparmor.ContainerAnnotationKeyPrefix + container.Name) fieldPath := field.NewPath("pod", "metadata", "annotations").Key(v1.AppArmorBetaContainerAnnotationKeyPrefix + container.Name)
profile := apparmor.GetProfileNameFromPodAnnotations(pod.Annotations, container.Name) profile := apparmor.GetProfileNameFromPodAnnotations(pod.Annotations, container.Name)
if profile == "" { if profile == "" {

View File

@ -22,9 +22,9 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/security/apparmor"
"k8s.io/kubernetes/pkg/util/maps" "k8s.io/kubernetes/pkg/util/maps"
) )
@ -36,29 +36,29 @@ var (
withoutAppArmor = map[string]string{"foo": "bar"} withoutAppArmor = map[string]string{"foo": "bar"}
withDefault = map[string]string{ withDefault = map[string]string{
"foo": "bar", "foo": "bar",
apparmor.ContainerAnnotationKeyPrefix + containerName: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaContainerAnnotationKeyPrefix + containerName: v1.AppArmorBetaProfileRuntimeDefault,
} }
withLocal = map[string]string{ withLocal = map[string]string{
"foo": "bar", "foo": "bar",
apparmor.ContainerAnnotationKeyPrefix + containerName: apparmor.ProfileNamePrefix + "foo", v1.AppArmorBetaContainerAnnotationKeyPrefix + containerName: v1.AppArmorBetaProfileNamePrefix + "foo",
} }
withDisallowed = map[string]string{ withDisallowed = map[string]string{
"foo": "bar", "foo": "bar",
apparmor.ContainerAnnotationKeyPrefix + containerName: apparmor.ProfileNamePrefix + "bad", v1.AppArmorBetaContainerAnnotationKeyPrefix + containerName: v1.AppArmorBetaProfileNamePrefix + "bad",
} }
noAppArmor = map[string]string{"foo": "bar"} noAppArmor = map[string]string{"foo": "bar"}
unconstrainedWithDefault = map[string]string{ unconstrainedWithDefault = map[string]string{
apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaDefaultProfileAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
} }
constrained = map[string]string{ constrained = map[string]string{
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault + "," + v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault + "," +
apparmor.ProfileNamePrefix + "foo", v1.AppArmorBetaProfileNamePrefix + "foo",
} }
constrainedWithDefault = map[string]string{ constrainedWithDefault = map[string]string{
apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaDefaultProfileAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault + "," + v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault + "," +
apparmor.ProfileNamePrefix + "foo", v1.AppArmorBetaProfileNamePrefix + "foo",
} }
container = api.Container{ container = api.Container{

View File

@ -546,13 +546,13 @@ func TestValidateContainerFailures(t *testing.T) {
failNilAppArmorPod := defaultPod() failNilAppArmorPod := defaultPod()
v1FailInvalidAppArmorPod := defaultV1Pod() v1FailInvalidAppArmorPod := defaultV1Pod()
apparmor.SetProfileName(v1FailInvalidAppArmorPod, defaultContainerName, apparmor.ProfileNamePrefix+"foo") apparmor.SetProfileName(v1FailInvalidAppArmorPod, defaultContainerName, v1.AppArmorBetaProfileNamePrefix+"foo")
failInvalidAppArmorPod := &api.Pod{} failInvalidAppArmorPod := &api.Pod{}
k8s_api_v1.Convert_v1_Pod_To_core_Pod(v1FailInvalidAppArmorPod, failInvalidAppArmorPod, nil) k8s_api_v1.Convert_v1_Pod_To_core_Pod(v1FailInvalidAppArmorPod, failInvalidAppArmorPod, nil)
failAppArmorPSP := defaultPSP() failAppArmorPSP := defaultPSP()
failAppArmorPSP.Annotations = map[string]string{ failAppArmorPSP.Annotations = map[string]string{
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
} }
failPrivPod := defaultPod() failPrivPod := defaultPod()
@ -1033,10 +1033,10 @@ func TestValidateContainerSuccess(t *testing.T) {
appArmorPSP := defaultPSP() appArmorPSP := defaultPSP()
appArmorPSP.Annotations = map[string]string{ appArmorPSP.Annotations = map[string]string{
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
} }
v1AppArmorPod := defaultV1Pod() v1AppArmorPod := defaultV1Pod()
apparmor.SetProfileName(v1AppArmorPod, defaultContainerName, apparmor.ProfileRuntimeDefault) apparmor.SetProfileName(v1AppArmorPod, defaultContainerName, v1.AppArmorBetaProfileRuntimeDefault)
appArmorPod := &api.Pod{} appArmorPod := &api.Pod{}
k8s_api_v1.Convert_v1_Pod_To_core_Pod(v1AppArmorPod, appArmorPod, nil) k8s_api_v1.Convert_v1_Pod_To_core_Pod(v1AppArmorPod, appArmorPod, nil)

View File

@ -1115,16 +1115,16 @@ func TestAdmitAppArmor(t *testing.T) {
unconstrainedPSP := restrictivePSP() unconstrainedPSP := restrictivePSP()
defaultedPSP := restrictivePSP() defaultedPSP := restrictivePSP()
defaultedPSP.Annotations = map[string]string{ defaultedPSP.Annotations = map[string]string{
apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaDefaultProfileAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
} }
appArmorPSP := restrictivePSP() appArmorPSP := restrictivePSP()
appArmorPSP.Annotations = map[string]string{ appArmorPSP.Annotations = map[string]string{
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
} }
appArmorDefaultPSP := restrictivePSP() appArmorDefaultPSP := restrictivePSP()
appArmorDefaultPSP.Annotations = map[string]string{ appArmorDefaultPSP.Annotations = map[string]string{
apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaDefaultProfileAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault + "," + apparmor.ProfileNamePrefix + "foo", v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault + "," + v1.AppArmorBetaProfileNamePrefix + "foo",
} }
tests := map[string]struct { tests := map[string]struct {
@ -1142,18 +1142,18 @@ func TestAdmitAppArmor(t *testing.T) {
expectedProfile: "", expectedProfile: "",
}, },
"unconstrained with profile": { "unconstrained with profile": {
pod: createPodWithAppArmor(apparmor.ProfileRuntimeDefault), pod: createPodWithAppArmor(v1.AppArmorBetaProfileRuntimeDefault),
psp: unconstrainedPSP, psp: unconstrainedPSP,
shouldPassAdmit: true, shouldPassAdmit: true,
shouldPassValidate: true, shouldPassValidate: true,
expectedProfile: apparmor.ProfileRuntimeDefault, expectedProfile: v1.AppArmorBetaProfileRuntimeDefault,
}, },
"unconstrained with default profile": { "unconstrained with default profile": {
pod: goodPod(), pod: goodPod(),
psp: defaultedPSP, psp: defaultedPSP,
shouldPassAdmit: true, shouldPassAdmit: true,
shouldPassValidate: true, shouldPassValidate: true,
expectedProfile: apparmor.ProfileRuntimeDefault, expectedProfile: v1.AppArmorBetaProfileRuntimeDefault,
}, },
"AppArmor enforced with no profile": { "AppArmor enforced with no profile": {
pod: goodPod(), pod: goodPod(),
@ -1166,17 +1166,17 @@ func TestAdmitAppArmor(t *testing.T) {
psp: appArmorDefaultPSP, psp: appArmorDefaultPSP,
shouldPassAdmit: true, shouldPassAdmit: true,
shouldPassValidate: true, shouldPassValidate: true,
expectedProfile: apparmor.ProfileRuntimeDefault, expectedProfile: v1.AppArmorBetaProfileRuntimeDefault,
}, },
"AppArmor enforced with good profile": { "AppArmor enforced with good profile": {
pod: createPodWithAppArmor(apparmor.ProfileNamePrefix + "foo"), pod: createPodWithAppArmor(v1.AppArmorBetaProfileNamePrefix + "foo"),
psp: appArmorDefaultPSP, psp: appArmorDefaultPSP,
shouldPassAdmit: true, shouldPassAdmit: true,
shouldPassValidate: true, shouldPassValidate: true,
expectedProfile: apparmor.ProfileNamePrefix + "foo", expectedProfile: v1.AppArmorBetaProfileNamePrefix + "foo",
}, },
"AppArmor enforced with local profile": { "AppArmor enforced with local profile": {
pod: createPodWithAppArmor(apparmor.ProfileNamePrefix + "bar"), pod: createPodWithAppArmor(v1.AppArmorBetaProfileNamePrefix + "bar"),
psp: appArmorPSP, psp: appArmorPSP,
shouldPassAdmit: false, shouldPassAdmit: false,
shouldPassValidate: false, shouldPassValidate: false,

View File

@ -48,6 +48,22 @@ const (
// SeccompProfileRuntimeDefault represents the default seccomp profile used by container runtime. // SeccompProfileRuntimeDefault represents the default seccomp profile used by container runtime.
SeccompProfileRuntimeDefault string = "runtime/default" SeccompProfileRuntimeDefault string = "runtime/default"
// AppArmorBetaContainerAnnotationKeyPrefix is the prefix to an annotation key specifying a container's apparmor profile.
AppArmorBetaContainerAnnotationKeyPrefix = "container.apparmor.security.beta.kubernetes.io/"
// AppArmorBetaDefaultProfileAnnotatoinKey is the annotation key specifying the default AppArmor profile.
AppArmorBetaDefaultProfileAnnotationKey = "apparmor.security.beta.kubernetes.io/defaultProfileName"
// AppArmorBetaAllowedProfileAnnotationKey is the annotation key specifying the allowed AppArmor profiles.
AppArmorBetaAllowedProfilesAnnotationKey = "apparmor.security.beta.kubernetes.io/allowedProfileNames"
// AppArmorBetaProfileRuntimeDefault is the profile specifying the runtime default.
AppArmorBetaProfileRuntimeDefault = "runtime/default"
// AppArmorBetaProfileNamePrefix is the prefix for specifying profiles loaded on the node.
AppArmorBetaProfileNamePrefix = "localhost/"
// AppArmorBetaProfileNameUnconfined is the Unconfined AppArmor profile
AppArmorBetaProfileNameUnconfined = "unconfined"
// DeprecatedSeccompProfileDockerDefault represents the default seccomp profile used by docker. // DeprecatedSeccompProfileDockerDefault represents the default seccomp profile used by docker.
// This is now deprecated and should be replaced by SeccompProfileRuntimeDefault. // This is now deprecated and should be replaced by SeccompProfileRuntimeDefault.
DeprecatedSeccompProfileDockerDefault string = "docker/default" DeprecatedSeccompProfileDockerDefault string = "docker/default"

View File

@ -17,7 +17,6 @@ go_library(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//pkg/master/ports:go_default_library", "//pkg/master/ports:go_default_library",
"//pkg/security/apparmor:go_default_library",
"//pkg/security/podsecuritypolicy/seccomp:go_default_library", "//pkg/security/podsecuritypolicy/seccomp:go_default_library",
"//pkg/security/podsecuritypolicy/util:go_default_library", "//pkg/security/podsecuritypolicy/util:go_default_library",
"//plugin/pkg/admission/serviceaccount:go_default_library", "//plugin/pkg/admission/serviceaccount:go_default_library",

View File

@ -29,7 +29,6 @@ import (
"k8s.io/apiserver/pkg/authentication/serviceaccount" "k8s.io/apiserver/pkg/authentication/serviceaccount"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/security/apparmor"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp" "k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp"
psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util" psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
@ -173,7 +172,7 @@ func testPrivilegedPods(tester func(pod *v1.Pod)) {
ginkgo.By("Running a custom AppArmor profile pod", func() { ginkgo.By("Running a custom AppArmor profile pod", func() {
aa := restrictedPod("apparmor") aa := restrictedPod("apparmor")
// Every node is expected to have the docker-default profile. // Every node is expected to have the docker-default profile.
aa.Annotations[apparmor.ContainerAnnotationKeyPrefix+"pause"] = "localhost/docker-default" aa.Annotations[v1.AppArmorBetaContainerAnnotationKeyPrefix+"pause"] = "localhost/docker-default"
tester(aa) tester(aa)
}) })
} }
@ -256,8 +255,8 @@ func restrictedPod(name string) *v1.Pod {
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: name, Name: name,
Annotations: map[string]string{ Annotations: map[string]string{
v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault, v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault,
apparmor.ContainerAnnotationKeyPrefix + "pause": apparmor.ProfileRuntimeDefault, v1.AppArmorBetaContainerAnnotationKeyPrefix + "pause": v1.AppArmorBetaProfileRuntimeDefault,
}, },
}, },
Spec: v1.PodSpec{ Spec: v1.PodSpec{
@ -316,10 +315,10 @@ func restrictedPSP(name string) *policyv1beta1.PodSecurityPolicy {
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: name, Name: name,
Annotations: map[string]string{ Annotations: map[string]string{
seccomp.AllowedProfilesAnnotationKey: v1.SeccompProfileRuntimeDefault, seccomp.AllowedProfilesAnnotationKey: v1.SeccompProfileRuntimeDefault,
seccomp.DefaultProfileAnnotationKey: v1.SeccompProfileRuntimeDefault, seccomp.DefaultProfileAnnotationKey: v1.SeccompProfileRuntimeDefault,
apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaAllowedProfilesAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, v1.AppArmorBetaDefaultProfileAnnotationKey: v1.AppArmorBetaProfileRuntimeDefault,
}, },
}, },
Spec: policyv1beta1.PodSecurityPolicySpec{ Spec: policyv1beta1.PodSecurityPolicySpec{

View File

@ -36,14 +36,6 @@ const (
loaderLabelKey = "name" loaderLabelKey = "name"
loaderLabelValue = "e2e-apparmor-loader" loaderLabelValue = "e2e-apparmor-loader"
// TODO: import this from the k8s.io/api once it's moved there (ref: https://github.com/kubernetes/kubernetes/pull/89198)
// Unconfined profile
profileNameUnconfined = "unconfined"
// TODO: import this from the k8s.io/api once it's moved there (ref: https://github.com/kubernetes/kubernetes/pull/89198)
// The prefix to an annotation key specifying a container profile.
containerAnnotationKeyPrefix = "container.apparmor.security.beta.kubernetes.io/"
) )
// LoadAppArmorProfiles creates apparmor-profiles ConfigMap and apparmor-loader ReplicationController. // LoadAppArmorProfiles creates apparmor-profiles ConfigMap and apparmor-loader ReplicationController.
@ -71,7 +63,7 @@ elif [[ $(< /proc/self/attr/current) != "%[3]s" ]]; then
fi`, appArmorDeniedPath, appArmorAllowedPath, appArmorProfilePrefix+nsName) fi`, appArmorDeniedPath, appArmorAllowedPath, appArmorProfilePrefix+nsName)
if unconfined { if unconfined {
profile = profileNameUnconfined profile = v1.AppArmorBetaProfileNameUnconfined
testCmd = ` testCmd = `
if cat /proc/sysrq-trigger 2>&1 | grep 'Permission denied'; then if cat /proc/sysrq-trigger 2>&1 | grep 'Permission denied'; then
echo 'FAILURE: reading /proc/sysrq-trigger should be allowed' echo 'FAILURE: reading /proc/sysrq-trigger should be allowed'
@ -105,7 +97,7 @@ done`, testCmd)
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
GenerateName: "test-apparmor-", GenerateName: "test-apparmor-",
Annotations: map[string]string{ Annotations: map[string]string{
containerAnnotationKeyPrefix + "test": profile, v1.AppArmorBetaContainerAnnotationKeyPrefix + "test": profile,
}, },
Labels: map[string]string{ Labels: map[string]string{
"test": "apparmor", "test": "apparmor",

View File

@ -53,11 +53,11 @@ var _ = framework.KubeDescribe("AppArmor [Feature:AppArmor][NodeFeature:AppArmor
f := framework.NewDefaultFramework("apparmor-test") f := framework.NewDefaultFramework("apparmor-test")
ginkgo.It("should reject an unloaded profile", func() { ginkgo.It("should reject an unloaded profile", func() {
status := runAppArmorTest(f, false, apparmor.ProfileNamePrefix+"non-existent-profile") status := runAppArmorTest(f, false, v1.AppArmorBetaProfileNamePrefix+"non-existent-profile")
expectSoftRejection(status) expectSoftRejection(status)
}) })
ginkgo.It("should enforce a profile blocking writes", func() { ginkgo.It("should enforce a profile blocking writes", func() {
status := runAppArmorTest(f, true, apparmor.ProfileNamePrefix+apparmorProfilePrefix+"deny-write") status := runAppArmorTest(f, true, v1.AppArmorBetaProfileNamePrefix+apparmorProfilePrefix+"deny-write")
if len(status.ContainerStatuses) == 0 { if len(status.ContainerStatuses) == 0 {
framework.Failf("Unexpected pod status: %s", spew.Sdump(status)) framework.Failf("Unexpected pod status: %s", spew.Sdump(status))
return return
@ -68,7 +68,7 @@ var _ = framework.KubeDescribe("AppArmor [Feature:AppArmor][NodeFeature:AppArmor
}) })
ginkgo.It("should enforce a permissive profile", func() { ginkgo.It("should enforce a permissive profile", func() {
status := runAppArmorTest(f, true, apparmor.ProfileNamePrefix+apparmorProfilePrefix+"audit-write") status := runAppArmorTest(f, true, v1.AppArmorBetaProfileNamePrefix+apparmorProfilePrefix+"audit-write")
if len(status.ContainerStatuses) == 0 { if len(status.ContainerStatuses) == 0 {
framework.Failf("Unexpected pod status: %s", spew.Sdump(status)) framework.Failf("Unexpected pod status: %s", spew.Sdump(status))
return return
@ -83,7 +83,7 @@ var _ = framework.KubeDescribe("AppArmor [Feature:AppArmor][NodeFeature:AppArmor
f := framework.NewDefaultFramework("apparmor-test") f := framework.NewDefaultFramework("apparmor-test")
ginkgo.It("should reject a pod with an AppArmor profile", func() { ginkgo.It("should reject a pod with an AppArmor profile", func() {
status := runAppArmorTest(f, false, apparmor.ProfileRuntimeDefault) status := runAppArmorTest(f, false, v1.AppArmorBetaProfileRuntimeDefault)
expectSoftRejection(status) expectSoftRejection(status)
}) })
}) })
@ -180,7 +180,7 @@ func createPodWithAppArmor(f *framework.Framework, profile string) *v1.Pod {
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("test-apparmor-%s", strings.Replace(profile, "/", "-", -1)), Name: fmt.Sprintf("test-apparmor-%s", strings.Replace(profile, "/", "-", -1)),
Annotations: map[string]string{ Annotations: map[string]string{
apparmor.ContainerAnnotationKeyPrefix + "test": profile, v1.AppArmorBetaContainerAnnotationKeyPrefix + "test": profile,
}, },
}, },
Spec: v1.PodSpec{ Spec: v1.PodSpec{