mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 16:29:21 +00:00
Merge pull request #101943 from saschagrunert/seccomp-default
Add kubelet `SeccompDefault` alpha feature
This commit is contained in:
commit
2e93b3924a
@ -166,6 +166,9 @@ type KubeletFlags struct {
|
|||||||
// This flag, if set, instructs the kubelet to keep volumes from terminated pods mounted to the node.
|
// This flag, if set, instructs the kubelet to keep volumes from terminated pods mounted to the node.
|
||||||
// This can be useful for debugging volume related issues.
|
// This can be useful for debugging volume related issues.
|
||||||
KeepTerminatedPodVolumes bool
|
KeepTerminatedPodVolumes bool
|
||||||
|
// SeccompDefault enables the use of `RuntimeDefault` as the default seccomp profile for all workloads on the node.
|
||||||
|
// To use this flag, the corresponding SeccompDefault feature gate must be enabled.
|
||||||
|
SeccompDefault bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKubeletFlags will create a new KubeletFlags with default values
|
// NewKubeletFlags will create a new KubeletFlags with default values
|
||||||
@ -211,6 +214,10 @@ func ValidateKubeletFlags(f *KubeletFlags) error {
|
|||||||
return fmt.Errorf("unknown 'kubernetes.io' or 'k8s.io' labels specified with --node-labels: %v\n--node-labels in the 'kubernetes.io' namespace must begin with an allowed prefix (%s) or be in the specifically allowed set (%s)", unknownLabels.List(), strings.Join(kubeletapis.KubeletLabelNamespaces(), ", "), strings.Join(kubeletapis.KubeletLabels(), ", "))
|
return fmt.Errorf("unknown 'kubernetes.io' or 'k8s.io' labels specified with --node-labels: %v\n--node-labels in the 'kubernetes.io' namespace must begin with an allowed prefix (%s) or be in the specifically allowed set (%s)", unknownLabels.List(), strings.Join(kubeletapis.KubeletLabelNamespaces(), ", "), strings.Join(kubeletapis.KubeletLabels(), ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.SeccompDefault && !utilfeature.DefaultFeatureGate.Enabled(features.SeccompDefault) {
|
||||||
|
return fmt.Errorf("the SeccompDefault feature gate must be enabled in order to use the --seccomp-default flag")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,6 +353,7 @@ func (f *KubeletFlags) AddFlags(mainfs *pflag.FlagSet) {
|
|||||||
fs.Var(&bindableNodeLabels, "node-labels", fmt.Sprintf("<Warning: Alpha feature> Labels to add when registering the node in the cluster. Labels must be key=value pairs separated by ','. Labels in the 'kubernetes.io' namespace must begin with an allowed prefix (%s) or be in the specifically allowed set (%s)", strings.Join(kubeletapis.KubeletLabelNamespaces(), ", "), strings.Join(kubeletapis.KubeletLabels(), ", ")))
|
fs.Var(&bindableNodeLabels, "node-labels", fmt.Sprintf("<Warning: Alpha feature> Labels to add when registering the node in the cluster. Labels must be key=value pairs separated by ','. Labels in the 'kubernetes.io' namespace must begin with an allowed prefix (%s) or be in the specifically allowed set (%s)", strings.Join(kubeletapis.KubeletLabelNamespaces(), ", "), strings.Join(kubeletapis.KubeletLabels(), ", ")))
|
||||||
fs.StringVar(&f.LockFilePath, "lock-file", f.LockFilePath, "<Warning: Alpha feature> The path to file for kubelet to use as a lock file.")
|
fs.StringVar(&f.LockFilePath, "lock-file", f.LockFilePath, "<Warning: Alpha feature> The path to file for kubelet to use as a lock file.")
|
||||||
fs.BoolVar(&f.ExitOnLockContention, "exit-on-lock-contention", f.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.")
|
fs.BoolVar(&f.ExitOnLockContention, "exit-on-lock-contention", f.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.")
|
||||||
|
fs.BoolVar(&f.SeccompDefault, "seccomp-default", f.SeccompDefault, "<Warning: Alpha feature> Enable the use of `RuntimeDefault` as the default seccomp profile for all workloads. The SeccompDefault feature gate must be enabled to allow this flag, which is disabled per default.")
|
||||||
|
|
||||||
// DEPRECATED FLAGS
|
// DEPRECATED FLAGS
|
||||||
fs.StringVar(&f.BootstrapKubeconfig, "experimental-bootstrap-kubeconfig", f.BootstrapKubeconfig, "")
|
fs.StringVar(&f.BootstrapKubeconfig, "experimental-bootstrap-kubeconfig", f.BootstrapKubeconfig, "")
|
||||||
|
@ -1135,6 +1135,10 @@ func RunKubelet(kubeServer *options.KubeletServer, kubeDeps *kubelet.Dependencie
|
|||||||
kubeDeps.OSInterface = kubecontainer.RealOS{}
|
kubeDeps.OSInterface = kubecontainer.RealOS{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if kubeServer.KubeletConfiguration.SeccompDefault && !utilfeature.DefaultFeatureGate.Enabled(features.SeccompDefault) {
|
||||||
|
return fmt.Errorf("the SeccompDefault feature gate must be enabled in order to use the SeccompDefault configuration")
|
||||||
|
}
|
||||||
|
|
||||||
k, err := createAndInitKubelet(&kubeServer.KubeletConfiguration,
|
k, err := createAndInitKubelet(&kubeServer.KubeletConfiguration,
|
||||||
kubeDeps,
|
kubeDeps,
|
||||||
&kubeServer.ContainerRuntimeOptions,
|
&kubeServer.ContainerRuntimeOptions,
|
||||||
@ -1164,7 +1168,9 @@ func RunKubelet(kubeServer *options.KubeletServer, kubeDeps *kubelet.Dependencie
|
|||||||
kubeServer.KeepTerminatedPodVolumes,
|
kubeServer.KeepTerminatedPodVolumes,
|
||||||
kubeServer.NodeLabels,
|
kubeServer.NodeLabels,
|
||||||
kubeServer.SeccompProfileRoot,
|
kubeServer.SeccompProfileRoot,
|
||||||
kubeServer.NodeStatusMaxImages)
|
kubeServer.NodeStatusMaxImages,
|
||||||
|
kubeServer.KubeletFlags.SeccompDefault || kubeServer.KubeletConfiguration.SeccompDefault,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create kubelet: %w", err)
|
return fmt.Errorf("failed to create kubelet: %w", err)
|
||||||
}
|
}
|
||||||
@ -1238,7 +1244,9 @@ func createAndInitKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||||||
keepTerminatedPodVolumes bool,
|
keepTerminatedPodVolumes bool,
|
||||||
nodeLabels map[string]string,
|
nodeLabels map[string]string,
|
||||||
seccompProfileRoot string,
|
seccompProfileRoot string,
|
||||||
nodeStatusMaxImages int32) (k kubelet.Bootstrap, err error) {
|
nodeStatusMaxImages int32,
|
||||||
|
seccompDefault bool,
|
||||||
|
) (k kubelet.Bootstrap, err error) {
|
||||||
// TODO: block until all sources have delivered at least one update to the channel, or break the sync loop
|
// TODO: block until all sources have delivered at least one update to the channel, or break the sync loop
|
||||||
// up into "per source" synchronizations
|
// up into "per source" synchronizations
|
||||||
|
|
||||||
@ -1271,7 +1279,9 @@ func createAndInitKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||||||
keepTerminatedPodVolumes,
|
keepTerminatedPodVolumes,
|
||||||
nodeLabels,
|
nodeLabels,
|
||||||
seccompProfileRoot,
|
seccompProfileRoot,
|
||||||
nodeStatusMaxImages)
|
nodeStatusMaxImages,
|
||||||
|
seccompDefault,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -714,6 +714,12 @@ const (
|
|||||||
//
|
//
|
||||||
// Enables apiserver and kubelet to allow up to 32 DNSSearchPaths and up to 2048 DNSSearchListChars.
|
// Enables apiserver and kubelet to allow up to 32 DNSSearchPaths and up to 2048 DNSSearchListChars.
|
||||||
ExpandedDNSConfig featuregate.Feature = "ExpandedDNSConfig"
|
ExpandedDNSConfig featuregate.Feature = "ExpandedDNSConfig"
|
||||||
|
|
||||||
|
// owner: @saschagrunert
|
||||||
|
// alpha: v1.22
|
||||||
|
//
|
||||||
|
// Enables the use of `RuntimeDefault` as the default seccomp profile for all workloads.
|
||||||
|
SeccompDefault featuregate.Feature = "SeccompDefault"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -821,6 +827,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
DisableCloudProviders: {Default: false, PreRelease: featuregate.Alpha},
|
DisableCloudProviders: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
StatefulSetMinReadySeconds: {Default: false, PreRelease: featuregate.Alpha},
|
StatefulSetMinReadySeconds: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
ExpandedDNSConfig: {Default: false, PreRelease: featuregate.Alpha},
|
ExpandedDNSConfig: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
SeccompDefault: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
|
||||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||||
// unintentionally on either side:
|
// unintentionally on either side:
|
||||||
|
@ -234,6 +234,7 @@ var (
|
|||||||
"ReservedSystemCPUs",
|
"ReservedSystemCPUs",
|
||||||
"RuntimeRequestTimeout.Duration",
|
"RuntimeRequestTimeout.Duration",
|
||||||
"RunOnce",
|
"RunOnce",
|
||||||
|
"SeccompDefault",
|
||||||
"SerializeImagePulls",
|
"SerializeImagePulls",
|
||||||
"ShowHiddenMetricsForVersion",
|
"ShowHiddenMetricsForVersion",
|
||||||
"StreamingConnectionIdleTimeout.Duration",
|
"StreamingConnectionIdleTimeout.Duration",
|
||||||
|
@ -69,6 +69,7 @@ registryBurst: 10
|
|||||||
registryPullQPS: 5
|
registryPullQPS: 5
|
||||||
resolvConf: /etc/resolv.conf
|
resolvConf: /etc/resolv.conf
|
||||||
runtimeRequestTimeout: 2m0s
|
runtimeRequestTimeout: 2m0s
|
||||||
|
seccompDefault: false
|
||||||
serializeImagePulls: true
|
serializeImagePulls: true
|
||||||
shutdownGracePeriod: 0s
|
shutdownGracePeriod: 0s
|
||||||
shutdownGracePeriodCriticalPods: 0s
|
shutdownGracePeriodCriticalPods: 0s
|
||||||
|
@ -69,6 +69,7 @@ registryBurst: 10
|
|||||||
registryPullQPS: 5
|
registryPullQPS: 5
|
||||||
resolvConf: /etc/resolv.conf
|
resolvConf: /etc/resolv.conf
|
||||||
runtimeRequestTimeout: 2m0s
|
runtimeRequestTimeout: 2m0s
|
||||||
|
seccompDefault: false
|
||||||
serializeImagePulls: true
|
serializeImagePulls: true
|
||||||
shutdownGracePeriod: 0s
|
shutdownGracePeriod: 0s
|
||||||
shutdownGracePeriodCriticalPods: 0s
|
shutdownGracePeriodCriticalPods: 0s
|
||||||
|
@ -407,6 +407,8 @@ type KubeletConfiguration struct {
|
|||||||
EnableProfilingHandler bool
|
EnableProfilingHandler bool
|
||||||
// EnableDebugFlagsHandler enables/debug/flags/v handler.
|
// EnableDebugFlagsHandler enables/debug/flags/v handler.
|
||||||
EnableDebugFlagsHandler bool
|
EnableDebugFlagsHandler bool
|
||||||
|
// SeccompDefault enables the use of `RuntimeDefault` as the default seccomp profile for all workloads.
|
||||||
|
SeccompDefault bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeletAuthorizationMode denotes the authorization mode for the kubelet
|
// KubeletAuthorizationMode denotes the authorization mode for the kubelet
|
||||||
|
@ -252,4 +252,7 @@ func SetDefaults_KubeletConfiguration(obj *kubeletconfigv1beta1.KubeletConfigura
|
|||||||
if obj.EnableDebugFlagsHandler == nil {
|
if obj.EnableDebugFlagsHandler == nil {
|
||||||
obj.EnableDebugFlagsHandler = utilpointer.BoolPtr(true)
|
obj.EnableDebugFlagsHandler = utilpointer.BoolPtr(true)
|
||||||
}
|
}
|
||||||
|
if obj.SeccompDefault == nil {
|
||||||
|
obj.SeccompDefault = utilpointer.BoolPtr(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,6 +371,9 @@ func autoConvert_v1beta1_KubeletConfiguration_To_config_KubeletConfiguration(in
|
|||||||
if err := v1.Convert_Pointer_bool_To_bool(&in.EnableDebugFlagsHandler, &out.EnableDebugFlagsHandler, s); err != nil {
|
if err := v1.Convert_Pointer_bool_To_bool(&in.EnableDebugFlagsHandler, &out.EnableDebugFlagsHandler, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := v1.Convert_Pointer_bool_To_bool(&in.SeccompDefault, &out.SeccompDefault, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,6 +535,9 @@ func autoConvert_config_KubeletConfiguration_To_v1beta1_KubeletConfiguration(in
|
|||||||
if err := v1.Convert_bool_To_Pointer_bool(&in.EnableDebugFlagsHandler, &out.EnableDebugFlagsHandler, s); err != nil {
|
if err := v1.Convert_bool_To_Pointer_bool(&in.EnableDebugFlagsHandler, &out.EnableDebugFlagsHandler, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := v1.Convert_bool_To_Pointer_bool(&in.SeccompDefault, &out.SeccompDefault, s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +367,9 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||||||
keepTerminatedPodVolumes bool,
|
keepTerminatedPodVolumes bool,
|
||||||
nodeLabels map[string]string,
|
nodeLabels map[string]string,
|
||||||
seccompProfileRoot string,
|
seccompProfileRoot string,
|
||||||
nodeStatusMaxImages int32) (*Kubelet, error) {
|
nodeStatusMaxImages int32,
|
||||||
|
seccompDefault bool,
|
||||||
|
) (*Kubelet, error) {
|
||||||
if rootDirectory == "" {
|
if rootDirectory == "" {
|
||||||
return nil, fmt.Errorf("invalid root directory %q", rootDirectory)
|
return nil, fmt.Errorf("invalid root directory %q", rootDirectory)
|
||||||
}
|
}
|
||||||
@ -649,6 +651,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||||||
kubeDeps.dockerLegacyService,
|
kubeDeps.dockerLegacyService,
|
||||||
klet.containerLogManager,
|
klet.containerLogManager,
|
||||||
klet.runtimeClassManager,
|
klet.runtimeClassManager,
|
||||||
|
seccompDefault,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -202,8 +202,11 @@ func toKubeRuntimeStatus(status *runtimeapi.RuntimeStatus) *kubecontainer.Runtim
|
|||||||
return &kubecontainer.RuntimeStatus{Conditions: conditions}
|
return &kubecontainer.RuntimeStatus{Conditions: conditions}
|
||||||
}
|
}
|
||||||
|
|
||||||
func fieldProfile(scmp *v1.SeccompProfile, profileRootPath string) string {
|
func fieldProfile(scmp *v1.SeccompProfile, profileRootPath string, fallbackToRuntimeDefault bool) string {
|
||||||
if scmp == nil {
|
if scmp == nil {
|
||||||
|
if fallbackToRuntimeDefault {
|
||||||
|
return v1.SeccompProfileRuntimeDefault
|
||||||
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if scmp.Type == v1.SeccompProfileTypeRuntimeDefault {
|
if scmp.Type == v1.SeccompProfileTypeRuntimeDefault {
|
||||||
@ -216,6 +219,10 @@ func fieldProfile(scmp *v1.SeccompProfile, profileRootPath string) string {
|
|||||||
if scmp.Type == v1.SeccompProfileTypeUnconfined {
|
if scmp.Type == v1.SeccompProfileTypeUnconfined {
|
||||||
return v1.SeccompProfileNameUnconfined
|
return v1.SeccompProfileNameUnconfined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fallbackToRuntimeDefault {
|
||||||
|
return v1.SeccompProfileRuntimeDefault
|
||||||
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,10 +236,10 @@ func annotationProfile(profile, profileRootPath string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string]string, containerName string,
|
func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string]string, containerName string,
|
||||||
podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext) string {
|
podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext, fallbackToRuntimeDefault bool) string {
|
||||||
// container fields are applied first
|
// container fields are applied first
|
||||||
if containerSecContext != nil && containerSecContext.SeccompProfile != nil {
|
if containerSecContext != nil && containerSecContext.SeccompProfile != nil {
|
||||||
return fieldProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot)
|
return fieldProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot, fallbackToRuntimeDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if container field does not exist, try container annotation (deprecated)
|
// if container field does not exist, try container annotation (deprecated)
|
||||||
@ -244,7 +251,7 @@ func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string
|
|||||||
|
|
||||||
// when container seccomp is not defined, try to apply from pod field
|
// when container seccomp is not defined, try to apply from pod field
|
||||||
if podSecContext != nil && podSecContext.SeccompProfile != nil {
|
if podSecContext != nil && podSecContext.SeccompProfile != nil {
|
||||||
return fieldProfile(podSecContext.SeccompProfile, m.seccompProfileRoot)
|
return fieldProfile(podSecContext.SeccompProfile, m.seccompProfileRoot, fallbackToRuntimeDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
// as last resort, try to apply pod annotation (deprecated)
|
// as last resort, try to apply pod annotation (deprecated)
|
||||||
@ -252,13 +259,20 @@ func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string
|
|||||||
return annotationProfile(profile, m.seccompProfileRoot)
|
return annotationProfile(profile, m.seccompProfileRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fallbackToRuntimeDefault {
|
||||||
|
return v1.SeccompProfileRuntimeDefault
|
||||||
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func fieldSeccompProfile(scmp *v1.SeccompProfile, profileRootPath string) *runtimeapi.SecurityProfile {
|
func fieldSeccompProfile(scmp *v1.SeccompProfile, profileRootPath string, fallbackToRuntimeDefault bool) *runtimeapi.SecurityProfile {
|
||||||
// TODO: Move to RuntimeDefault as the default instead of Unconfined after discussion
|
|
||||||
// with sig-node.
|
|
||||||
if scmp == nil {
|
if scmp == nil {
|
||||||
|
if fallbackToRuntimeDefault {
|
||||||
|
return &runtimeapi.SecurityProfile{
|
||||||
|
ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
|
||||||
|
}
|
||||||
|
}
|
||||||
return &runtimeapi.SecurityProfile{
|
return &runtimeapi.SecurityProfile{
|
||||||
ProfileType: runtimeapi.SecurityProfile_Unconfined,
|
ProfileType: runtimeapi.SecurityProfile_Unconfined,
|
||||||
}
|
}
|
||||||
@ -281,15 +295,21 @@ func fieldSeccompProfile(scmp *v1.SeccompProfile, profileRootPath string) *runti
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *kubeGenericRuntimeManager) getSeccompProfile(annotations map[string]string, containerName string,
|
func (m *kubeGenericRuntimeManager) getSeccompProfile(annotations map[string]string, containerName string,
|
||||||
podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext) *runtimeapi.SecurityProfile {
|
podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext, fallbackToRuntimeDefault bool) *runtimeapi.SecurityProfile {
|
||||||
// container fields are applied first
|
// container fields are applied first
|
||||||
if containerSecContext != nil && containerSecContext.SeccompProfile != nil {
|
if containerSecContext != nil && containerSecContext.SeccompProfile != nil {
|
||||||
return fieldSeccompProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot)
|
return fieldSeccompProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot, fallbackToRuntimeDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
// when container seccomp is not defined, try to apply from pod field
|
// when container seccomp is not defined, try to apply from pod field
|
||||||
if podSecContext != nil && podSecContext.SeccompProfile != nil {
|
if podSecContext != nil && podSecContext.SeccompProfile != nil {
|
||||||
return fieldSeccompProfile(podSecContext.SeccompProfile, m.seccompProfileRoot)
|
return fieldSeccompProfile(podSecContext.SeccompProfile, m.seccompProfileRoot, fallbackToRuntimeDefault)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fallbackToRuntimeDefault {
|
||||||
|
return &runtimeapi.SecurityProfile{
|
||||||
|
ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &runtimeapi.SecurityProfile{
|
return &runtimeapi.SecurityProfile{
|
||||||
|
@ -210,7 +210,7 @@ func TestFieldProfile(t *testing.T) {
|
|||||||
expectedProfile: "unconfined",
|
expectedProfile: "unconfined",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "SeccompProfileTypeLocalhost should return unconfined",
|
description: "SeccompProfileTypeLocalhost should return localhost",
|
||||||
scmpProfile: &v1.SeccompProfile{
|
scmpProfile: &v1.SeccompProfile{
|
||||||
Type: v1.SeccompProfileTypeLocalhost,
|
Type: v1.SeccompProfileTypeLocalhost,
|
||||||
LocalhostProfile: utilpointer.StringPtr("profile.json"),
|
LocalhostProfile: utilpointer.StringPtr("profile.json"),
|
||||||
@ -221,7 +221,63 @@ func TestFieldProfile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
seccompProfile := fieldProfile(test.scmpProfile, test.rootPath)
|
seccompProfile := fieldProfile(test.scmpProfile, test.rootPath, false)
|
||||||
|
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFieldProfileDefaultSeccomp(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
description string
|
||||||
|
scmpProfile *v1.SeccompProfile
|
||||||
|
rootPath string
|
||||||
|
expectedProfile string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "no seccompProfile should return runtime/default",
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "type localhost without profile should return runtime/default",
|
||||||
|
scmpProfile: &v1.SeccompProfile{
|
||||||
|
Type: v1.SeccompProfileTypeLocalhost,
|
||||||
|
},
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "unknown type should return runtime/default",
|
||||||
|
scmpProfile: &v1.SeccompProfile{
|
||||||
|
Type: "",
|
||||||
|
},
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "SeccompProfileTypeRuntimeDefault should return runtime/default",
|
||||||
|
scmpProfile: &v1.SeccompProfile{
|
||||||
|
Type: v1.SeccompProfileTypeRuntimeDefault,
|
||||||
|
},
|
||||||
|
expectedProfile: "runtime/default",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "SeccompProfileTypeUnconfined should return unconfined",
|
||||||
|
scmpProfile: &v1.SeccompProfile{
|
||||||
|
Type: v1.SeccompProfileTypeUnconfined,
|
||||||
|
},
|
||||||
|
expectedProfile: "unconfined",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "SeccompProfileTypeLocalhost should return localhost",
|
||||||
|
scmpProfile: &v1.SeccompProfile{
|
||||||
|
Type: v1.SeccompProfileTypeLocalhost,
|
||||||
|
LocalhostProfile: utilpointer.StringPtr("profile.json"),
|
||||||
|
},
|
||||||
|
rootPath: "/test/",
|
||||||
|
expectedProfile: "localhost//test/profile.json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
seccompProfile := fieldProfile(test.scmpProfile, test.rootPath, true)
|
||||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -411,7 +467,197 @@ func TestGetSeccompProfilePath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc)
|
seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, false)
|
||||||
|
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) {
|
||||||
|
_, _, m, err := createTestRuntimeManager()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
description string
|
||||||
|
annotation map[string]string
|
||||||
|
podSc *v1.PodSecurityContext
|
||||||
|
containerSc *v1.SecurityContext
|
||||||
|
containerName string
|
||||||
|
expectedProfile string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "no seccomp should return runtime/default",
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: no seccomp with containerName should return runtime/default",
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: pod runtime/default seccomp profile should return runtime/default",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: pod docker/default seccomp profile should return docker/default",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault,
|
||||||
|
},
|
||||||
|
expectedProfile: "docker/default",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: pod runtime/default seccomp profile with containerName should return runtime/default",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: pod docker/default seccomp profile with containerName should return docker/default",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault,
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: "docker/default",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: pod unconfined seccomp profile should return unconfined",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined,
|
||||||
|
},
|
||||||
|
expectedProfile: "unconfined",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: pod unconfined seccomp profile with containerName should return unconfined",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined,
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: "unconfined",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: pod localhost seccomp profile should return local profile path",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: "localhost/chmod.json",
|
||||||
|
},
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "chmod.json"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: pod localhost seccomp profile with containerName should return local profile path",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: "localhost/chmod.json",
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "chmod.json"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: container localhost seccomp profile with containerName should return local profile path",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "chmod.json"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: container localhost seccomp profile should override pod profile",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined,
|
||||||
|
v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "chmod.json"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "annotations: container localhost seccomp profile with unmatched containerName should return runtime/default",
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
|
||||||
|
},
|
||||||
|
containerName: "container2",
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||||
|
expectedProfile: "unconfined",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "container seccomp profile set to unconfined returns unconfined",
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||||
|
expectedProfile: "unconfined",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||||
|
expectedProfile: "runtime/default",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||||
|
expectedProfile: "runtime/default",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "filename"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns runtime/default",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns runtime/default",
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||||
|
expectedProfile: v1.SeccompProfileRuntimeDefault,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "filename2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "prioritise container field over pod field",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||||
|
expectedProfile: "runtime/default",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "prioritise container field over container annotation, pod field and pod annotation",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}},
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json",
|
||||||
|
v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json",
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "field-cont-profile.json"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "prioritise container annotation over pod field",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json",
|
||||||
|
v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json",
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "annota-cont-profile.json"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "prioritise pod field over pod annotation",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
|
||||||
|
annotation: map[string]string{
|
||||||
|
v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json",
|
||||||
|
},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "field-pod-profile.json"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, true)
|
||||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -505,7 +751,101 @@ func TestGetSeccompProfile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc)
|
seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, false)
|
||||||
|
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetSeccompProfileDefaultSeccomp(t *testing.T) {
|
||||||
|
_, _, m, err := createTestRuntimeManager()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
unconfinedProfile := &runtimeapi.SecurityProfile{
|
||||||
|
ProfileType: runtimeapi.SecurityProfile_Unconfined,
|
||||||
|
}
|
||||||
|
|
||||||
|
runtimeDefaultProfile := &runtimeapi.SecurityProfile{
|
||||||
|
ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
description string
|
||||||
|
annotation map[string]string
|
||||||
|
podSc *v1.PodSecurityContext
|
||||||
|
containerSc *v1.SecurityContext
|
||||||
|
containerName string
|
||||||
|
expectedProfile *runtimeapi.SecurityProfile
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
description: "no seccomp should return RuntimeDefault",
|
||||||
|
expectedProfile: runtimeDefaultProfile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "pod seccomp profile set to unconfined returns unconfined",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||||
|
expectedProfile: unconfinedProfile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "container seccomp profile set to unconfined returns unconfined",
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||||
|
expectedProfile: unconfinedProfile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "pod seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||||
|
expectedProfile: runtimeDefaultProfile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "container seccomp profile set to SeccompProfileTypeRuntimeDefault returns runtime/default",
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||||
|
expectedProfile: runtimeDefaultProfile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "pod seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename")}},
|
||||||
|
expectedProfile: &runtimeapi.SecurityProfile{
|
||||||
|
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||||
|
LocalhostRef: filepath.Join(fakeSeccompProfileRoot, "filename"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||||
|
expectedProfile: unconfinedProfile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
|
||||||
|
expectedProfile: unconfinedProfile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("filename2")}},
|
||||||
|
expectedProfile: &runtimeapi.SecurityProfile{
|
||||||
|
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||||
|
LocalhostRef: filepath.Join(fakeSeccompProfileRoot, "filename2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "prioritise container field over pod field",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
|
||||||
|
expectedProfile: runtimeDefaultProfile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "prioritise container field over pod field",
|
||||||
|
podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
|
||||||
|
containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}},
|
||||||
|
containerName: "container1",
|
||||||
|
expectedProfile: &runtimeapi.SecurityProfile{
|
||||||
|
ProfileType: runtimeapi.SecurityProfile_Localhost,
|
||||||
|
LocalhostRef: filepath.Join(fakeSeccompProfileRoot, "field-cont-profile.json"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, true)
|
||||||
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,9 @@ type kubeGenericRuntimeManager struct {
|
|||||||
|
|
||||||
// PodState provider instance
|
// PodState provider instance
|
||||||
podStateProvider podStateProvider
|
podStateProvider podStateProvider
|
||||||
|
|
||||||
|
// Use RuntimeDefault as the default seccomp profile for all workloads.
|
||||||
|
seccompDefault bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeGenericRuntime is a interface contains interfaces for container runtime and command.
|
// KubeGenericRuntime is a interface contains interfaces for container runtime and command.
|
||||||
@ -182,6 +185,7 @@ func NewKubeGenericRuntimeManager(
|
|||||||
legacyLogProvider LegacyLogProvider,
|
legacyLogProvider LegacyLogProvider,
|
||||||
logManager logs.ContainerLogManager,
|
logManager logs.ContainerLogManager,
|
||||||
runtimeClassManager *runtimeclass.Manager,
|
runtimeClassManager *runtimeclass.Manager,
|
||||||
|
seccompDefault bool,
|
||||||
) (KubeGenericRuntime, error) {
|
) (KubeGenericRuntime, error) {
|
||||||
kubeRuntimeManager := &kubeGenericRuntimeManager{
|
kubeRuntimeManager := &kubeGenericRuntimeManager{
|
||||||
recorder: recorder,
|
recorder: recorder,
|
||||||
@ -201,6 +205,7 @@ func NewKubeGenericRuntimeManager(
|
|||||||
logManager: logManager,
|
logManager: logManager,
|
||||||
runtimeClassManager: runtimeClassManager,
|
runtimeClassManager: runtimeClassManager,
|
||||||
logReduction: logreduction.NewLogReduction(identicalErrorDelay),
|
logReduction: logreduction.NewLogReduction(identicalErrorDelay),
|
||||||
|
seccompDefault: seccompDefault,
|
||||||
}
|
}
|
||||||
|
|
||||||
typedVersion, err := kubeRuntimeManager.getTypedVersion()
|
typedVersion, err := kubeRuntimeManager.getTypedVersion()
|
||||||
|
@ -36,9 +36,9 @@ func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Po
|
|||||||
|
|
||||||
// TODO: Deprecated, remove after we switch to Seccomp field
|
// TODO: Deprecated, remove after we switch to Seccomp field
|
||||||
// set SeccompProfilePath.
|
// set SeccompProfilePath.
|
||||||
synthesized.SeccompProfilePath = m.getSeccompProfilePath(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext)
|
synthesized.SeccompProfilePath = m.getSeccompProfilePath(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext, m.seccompDefault)
|
||||||
|
|
||||||
synthesized.Seccomp = m.getSeccompProfile(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext)
|
synthesized.Seccomp = m.getSeccompProfile(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext, m.seccompDefault)
|
||||||
|
|
||||||
// set ApparmorProfile.
|
// set ApparmorProfile.
|
||||||
synthesized.ApparmorProfile = apparmor.GetProfileNameFromPodAnnotations(pod.Annotations, container.Name)
|
synthesized.ApparmorProfile = apparmor.GetProfileNameFromPodAnnotations(pod.Annotations, container.Name)
|
||||||
|
@ -864,6 +864,11 @@ type KubeletConfiguration struct {
|
|||||||
// Default: true
|
// Default: true
|
||||||
// +optional
|
// +optional
|
||||||
EnableDebugFlagsHandler *bool `json:"enableDebugFlagsHandler,omitempty"`
|
EnableDebugFlagsHandler *bool `json:"enableDebugFlagsHandler,omitempty"`
|
||||||
|
// SeccompDefault enables the use of `RuntimeDefault` as the default seccomp profile for all workloads.
|
||||||
|
// This requires the corresponding SeccompDefault feature gate to be enabled as well.
|
||||||
|
// Default: false
|
||||||
|
// +optional
|
||||||
|
SeccompDefault *bool `json:"seccompDefault,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KubeletAuthorizationMode string
|
type KubeletAuthorizationMode string
|
||||||
|
@ -321,6 +321,11 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
|||||||
*out = new(bool)
|
*out = new(bool)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
|
if in.SeccompDefault != nil {
|
||||||
|
in, out := &in.SeccompDefault, &out.SeccompDefault
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user