Add the OCI seccomp profile type behind SecurityProfileOCI

Add seccompProfile.type OCI with the oci field (a digest-pinned ref and an
optional RuntimeDefault or Localhost baseProfile) and the alpha
SecurityProfileOCI feature gate, as described in KEP-6061. The oci field
is validated declaratively, with custom validators for the reference and
the base profile path; the gate check and the rule that privileged
containers cannot use an OCI profile stay handwritten. While the gate is
disabled the type is rejected unless the old object already uses it.
PodSecurity baseline and restricted keep rejecting OCI. The
SecurityProfileOCI node declared feature keeps pods with OCI profiles on
nodes whose kubelet has the gate enabled and a runtime that supports OCI
seccomp profiles. The field is named ref instead of the KEP's reference,
following the kube-api-linter naming convention for new fields.

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
This commit is contained in:
Sascha Grunert committed 2026-11-04 07:21:35 +01:00
1 parent 19ba403c46
commit 44dfc921ce
112 files changed
+5177 -103

No files matched your search

+49 -2
View File
@@ -12239,8 +12239,12 @@
"description": "localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"type": "string"
},
"oci": {
"$ref": "#/definitions/io.k8s.api.core.v1.SecurityProfileOCI",
"description": "oci specifies a seccomp profile stored as an artifact in an OCI registry. The container runtime merges the profile with a base profile, so the effective profile permits an operation only if both permit it. Must be set if type is \"OCI\". Must NOT be set for any other type. This is an alpha field and requires enabling the SecurityProfileOCI feature gate."
},
"type": {
"description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.",
"description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. OCI - a profile pulled from an OCI registry should be used, merged with a base profile (see oci.baseProfile). Privileged containers cannot use it, whether it is set on the container or inherited from the pod. This is an alpha value and requires enabling the SecurityProfileOCI feature gate.",
"type": "string"
}
},
@@ -12252,7 +12256,8 @@
{
"discriminator": "type",
"fields-to-discriminateBy": {
"localhostProfile": "LocalhostProfile"
"localhostProfile": "LocalhostProfile",
"oci": "OCI"
}
}
]
@@ -12501,6 +12506,48 @@
},
"type": "object"
},
"io.k8s.api.core.v1.SecurityProfileOCI": {
"description": "SecurityProfileOCI references a security profile stored as an artifact in an OCI registry, with an optional base profile.",
"properties": {
"baseProfile": {
"$ref": "#/definitions/io.k8s.api.core.v1.SecurityProfileOCIBase",
"description": "baseProfile optionally specifies the base profile that the container runtime merges with the OCI profile. The effective profile permits an operation only if both permit it. When omitted, the container runtime default profile is the base; a Localhost base profile takes its place."
},
"ref": {
"description": "ref is the OCI reference of the profile. It must be a digest-pinned reference in canonical form, registry/repository@<algorithm>:<digest>, with the registry spelled out (for example docker.io/library/profile, not profile or docker.io/profile). Tags are rejected. The digest algorithm must be sha256, sha384, or sha512. The maximum length is 1024 characters. Pull secrets are assembled in the same way as for the container image by looking up node credentials, service account image pull secrets, and pod spec image pull secrets.",
"type": "string"
}
},
"required": [
"ref"
],
"type": "object"
},
"io.k8s.api.core.v1.SecurityProfileOCIBase": {
"description": "SecurityProfileOCIBase specifies the base profile of an OCI security profile.",
"properties": {
"localhostProfile": {
"description": "localhostProfile indicates a base profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location, of at most 4096 characters. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"type": "string"
},
"type": {
"description": "type indicates which kind of base profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used.",
"type": "string"
}
},
"required": [
"type"
],
"type": "object",
"x-kubernetes-unions": [
{
"discriminator": "type",
"fields-to-discriminateBy": {
"localhostProfile": "LocalhostProfile"
}
}
]
},
"io.k8s.api.core.v1.Service": {
"description": "Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy.",
"properties": {
+59 -2
View File
@@ -7198,9 +7198,17 @@
"description": "localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"type": "string"
},
"oci": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SecurityProfileOCI"
}
],
"description": "oci specifies a seccomp profile stored as an artifact in an OCI registry. The container runtime merges the profile with a base profile, so the effective profile permits an operation only if both permit it. Must be set if type is \"OCI\". Must NOT be set for any other type. This is an alpha field and requires enabling the SecurityProfileOCI feature gate."
},
"type": {
"default": "",
"description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.",
"description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. OCI - a profile pulled from an OCI registry should be used, merged with a base profile (see oci.baseProfile). Privileged containers cannot use it, whether it is set on the container or inherited from the pod. This is an alpha value and requires enabling the SecurityProfileOCI feature gate.",
"type": "string"
}
},
@@ -7212,7 +7220,8 @@
{
"discriminator": "type",
"fields-to-discriminateBy": {
"localhostProfile": "LocalhostProfile"
"localhostProfile": "LocalhostProfile",
"oci": "OCI"
}
}
]
@@ -7495,6 +7504,54 @@
},
"type": "object"
},
"io.k8s.api.core.v1.SecurityProfileOCI": {
"description": "SecurityProfileOCI references a security profile stored as an artifact in an OCI registry, with an optional base profile.",
"properties": {
"baseProfile": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SecurityProfileOCIBase"
}
],
"description": "baseProfile optionally specifies the base profile that the container runtime merges with the OCI profile. The effective profile permits an operation only if both permit it. When omitted, the container runtime default profile is the base; a Localhost base profile takes its place."
},
"ref": {
"default": "",
"description": "ref is the OCI reference of the profile. It must be a digest-pinned reference in canonical form, registry/repository@<algorithm>:<digest>, with the registry spelled out (for example docker.io/library/profile, not profile or docker.io/profile). Tags are rejected. The digest algorithm must be sha256, sha384, or sha512. The maximum length is 1024 characters. Pull secrets are assembled in the same way as for the container image by looking up node credentials, service account image pull secrets, and pod spec image pull secrets.",
"type": "string"
}
},
"required": [
"ref"
],
"type": "object"
},
"io.k8s.api.core.v1.SecurityProfileOCIBase": {
"description": "SecurityProfileOCIBase specifies the base profile of an OCI security profile.",
"properties": {
"localhostProfile": {
"description": "localhostProfile indicates a base profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location, of at most 4096 characters. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"type": "string"
},
"type": {
"default": "",
"description": "type indicates which kind of base profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used.",
"type": "string"
}
},
"required": [
"type"
],
"type": "object",
"x-kubernetes-unions": [
{
"discriminator": "type",
"fields-to-discriminateBy": {
"localhostProfile": "LocalhostProfile"
}
}
]
},
"io.k8s.api.core.v1.Service": {
"description": "Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy.",
"properties": {
+59 -2
View File
@@ -4466,9 +4466,17 @@
"description": "localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"type": "string"
},
"oci": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SecurityProfileOCI"
}
],
"description": "oci specifies a seccomp profile stored as an artifact in an OCI registry. The container runtime merges the profile with a base profile, so the effective profile permits an operation only if both permit it. Must be set if type is \"OCI\". Must NOT be set for any other type. This is an alpha field and requires enabling the SecurityProfileOCI feature gate."
},
"type": {
"default": "",
"description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.",
"description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. OCI - a profile pulled from an OCI registry should be used, merged with a base profile (see oci.baseProfile). Privileged containers cannot use it, whether it is set on the container or inherited from the pod. This is an alpha value and requires enabling the SecurityProfileOCI feature gate.",
"type": "string"
}
},
@@ -4480,7 +4488,8 @@
{
"discriminator": "type",
"fields-to-discriminateBy": {
"localhostProfile": "LocalhostProfile"
"localhostProfile": "LocalhostProfile",
"oci": "OCI"
}
}
]
@@ -4655,6 +4664,54 @@
},
"type": "object"
},
"io.k8s.api.core.v1.SecurityProfileOCI": {
"description": "SecurityProfileOCI references a security profile stored as an artifact in an OCI registry, with an optional base profile.",
"properties": {
"baseProfile": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SecurityProfileOCIBase"
}
],
"description": "baseProfile optionally specifies the base profile that the container runtime merges with the OCI profile. The effective profile permits an operation only if both permit it. When omitted, the container runtime default profile is the base; a Localhost base profile takes its place."
},
"ref": {
"default": "",
"description": "ref is the OCI reference of the profile. It must be a digest-pinned reference in canonical form, registry/repository@<algorithm>:<digest>, with the registry spelled out (for example docker.io/library/profile, not profile or docker.io/profile). Tags are rejected. The digest algorithm must be sha256, sha384, or sha512. The maximum length is 1024 characters. Pull secrets are assembled in the same way as for the container image by looking up node credentials, service account image pull secrets, and pod spec image pull secrets.",
"type": "string"
}
},
"required": [
"ref"
],
"type": "object"
},
"io.k8s.api.core.v1.SecurityProfileOCIBase": {
"description": "SecurityProfileOCIBase specifies the base profile of an OCI security profile.",
"properties": {
"localhostProfile": {
"description": "localhostProfile indicates a base profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location, of at most 4096 characters. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"type": "string"
},
"type": {
"default": "",
"description": "type indicates which kind of base profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used.",
"type": "string"
}
},
"required": [
"type"
],
"type": "object",
"x-kubernetes-unions": [
{
"discriminator": "type",
"fields-to-discriminateBy": {
"localhostProfile": "LocalhostProfile"
}
}
]
},
"io.k8s.api.core.v1.ServiceAccountTokenProjection": {
"description": "ServiceAccountTokenProjection represents a projected service account token volume. This projection can be used to insert a service account token into the pods runtime filesystem for use against APIs (Kubernetes API Server or otherwise).",
"properties": {
+59 -2
View File
@@ -3728,9 +3728,17 @@
"description": "localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"type": "string"
},
"oci": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SecurityProfileOCI"
}
],
"description": "oci specifies a seccomp profile stored as an artifact in an OCI registry. The container runtime merges the profile with a base profile, so the effective profile permits an operation only if both permit it. Must be set if type is \"OCI\". Must NOT be set for any other type. This is an alpha field and requires enabling the SecurityProfileOCI feature gate."
},
"type": {
"default": "",
"description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.",
"description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. OCI - a profile pulled from an OCI registry should be used, merged with a base profile (see oci.baseProfile). Privileged containers cannot use it, whether it is set on the container or inherited from the pod. This is an alpha value and requires enabling the SecurityProfileOCI feature gate.",
"type": "string"
}
},
@@ -3742,7 +3750,8 @@
{
"discriminator": "type",
"fields-to-discriminateBy": {
"localhostProfile": "LocalhostProfile"
"localhostProfile": "LocalhostProfile",
"oci": "OCI"
}
}
]
@@ -3917,6 +3926,54 @@
},
"type": "object"
},
"io.k8s.api.core.v1.SecurityProfileOCI": {
"description": "SecurityProfileOCI references a security profile stored as an artifact in an OCI registry, with an optional base profile.",
"properties": {
"baseProfile": {
"allOf": [
{
"$ref": "#/components/schemas/io.k8s.api.core.v1.SecurityProfileOCIBase"
}
],
"description": "baseProfile optionally specifies the base profile that the container runtime merges with the OCI profile. The effective profile permits an operation only if both permit it. When omitted, the container runtime default profile is the base; a Localhost base profile takes its place."
},
"ref": {
"default": "",
"description": "ref is the OCI reference of the profile. It must be a digest-pinned reference in canonical form, registry/repository@<algorithm>:<digest>, with the registry spelled out (for example docker.io/library/profile, not profile or docker.io/profile). Tags are rejected. The digest algorithm must be sha256, sha384, or sha512. The maximum length is 1024 characters. Pull secrets are assembled in the same way as for the container image by looking up node credentials, service account image pull secrets, and pod spec image pull secrets.",
"type": "string"
}
},
"required": [
"ref"
],
"type": "object"
},
"io.k8s.api.core.v1.SecurityProfileOCIBase": {
"description": "SecurityProfileOCIBase specifies the base profile of an OCI security profile.",
"properties": {
"localhostProfile": {
"description": "localhostProfile indicates a base profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location, of at most 4096 characters. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"type": "string"
},
"type": {
"default": "",
"description": "type indicates which kind of base profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used.",
"type": "string"
}
},
"required": [
"type"
],
"type": "object",
"x-kubernetes-unions": [
{
"discriminator": "type",
"fields-to-discriminateBy": {
"localhostProfile": "LocalhostProfile"
}
}
]
},
"io.k8s.api.core.v1.ServiceAccountTokenProjection": {
"description": "ServiceAccountTokenProjection represents a projected service account token volume. This projection can be used to insert a service account token into the pods runtime filesystem for use against APIs (Kubernetes API Server or otherwise).",
"properties": {
+6
View File
@@ -343,6 +343,12 @@ linters:
# EvictionResponder.Priority reserves priorities 0-999 for *.k8s.io responders.
- text: 'forbiddenmarkers: field EvictionResponder.Priority has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# SecurityProfileOCI.Ref must be a canonical, digest-pinned OCI reference without a tag.
- text: 'forbiddenmarkers: field SecurityProfileOCI.Ref has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# SecurityProfileOCIBase.LocalhostProfile must be a relative path without ".." elements.
- text: 'forbiddenmarkers: field SecurityProfileOCIBase.LocalhostProfile has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# EvictionRequestSpec.Requester has the same reserved-domain rule as EvictionResponder.Name.
- text: 'forbiddenmarkers: field EvictionRequestSpec.Requester has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/lifecycle/v1alpha1/types.go"
+6
View File
@@ -365,6 +365,12 @@ linters:
# EvictionResponder.Priority reserves priorities 0-999 for *.k8s.io responders.
- text: 'forbiddenmarkers: field EvictionResponder.Priority has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# SecurityProfileOCI.Ref must be a canonical, digest-pinned OCI reference without a tag.
- text: 'forbiddenmarkers: field SecurityProfileOCI.Ref has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# SecurityProfileOCIBase.LocalhostProfile must be a relative path without ".." elements.
- text: 'forbiddenmarkers: field SecurityProfileOCIBase.LocalhostProfile has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# EvictionRequestSpec.Requester has the same reserved-domain rule as EvictionResponder.Name.
- text: 'forbiddenmarkers: field EvictionRequestSpec.Requester has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/lifecycle/v1alpha1/types.go"
+6
View File
@@ -199,6 +199,12 @@
# EvictionResponder.Priority reserves priorities 0-999 for *.k8s.io responders.
- text: 'forbiddenmarkers: field EvictionResponder.Priority has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# SecurityProfileOCI.Ref must be a canonical, digest-pinned OCI reference without a tag.
- text: 'forbiddenmarkers: field SecurityProfileOCI.Ref has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# SecurityProfileOCIBase.LocalhostProfile must be a relative path without ".." elements.
- text: 'forbiddenmarkers: field SecurityProfileOCIBase.LocalhostProfile has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/core/v1/types.go"
# EvictionRequestSpec.Requester has the same reserved-domain rule as EvictionResponder.Name.
- text: 'forbiddenmarkers: field EvictionRequestSpec.Requester has forbidden marker "k8s:customValidation"'
path: "staging/src/k8s.io/api/lifecycle/v1alpha1/types.go"
+27
View File
@@ -435,6 +435,7 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
AllowExistingRestartContainerForNonSidecarInitContainer: hasRestartContainerForNonSidecarInitContainer(oldPodSpec),
AllowSysAdminWhenPrivilegeEscalationFalse: false,
AllowMLDSAPodCertificateKeyTypes: utilfeature.DefaultFeatureGate.Enabled(features.PodCertificateMLDSA),
AllowSecurityProfileOCI: utilfeature.DefaultFeatureGate.Enabled(features.SecurityProfileOCI),
}
// If old spec uses relaxed validation or enabled the RelaxedEnvironmentVariableValidation feature gate,
@@ -494,6 +495,9 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
// If old spec has a projected pod certificate requesting an ML-DSA key type, allow it
opts.AllowMLDSAPodCertificateKeyTypes = opts.AllowMLDSAPodCertificateKeyTypes || hasMLDSAPodCertificateProjection(oldPodSpec.Volumes)
// If old spec uses a seccomp profile of type OCI, allow it
opts.AllowSecurityProfileOCI = opts.AllowSecurityProfileOCI || seccompProfileOCIInUse(oldPodSpec)
}
if oldPodMeta != nil && !opts.AllowInvalidPodDeletionCost {
// This is an update, so validate only if the existing object was valid.
@@ -1401,6 +1405,29 @@ func procMountInUse(podSpec *api.PodSpec) bool {
return inUse
}
// seccompProfileOCIInUse returns true if the pod spec or any of its containers
// uses a seccomp profile of type OCI.
func seccompProfileOCIInUse(podSpec *api.PodSpec) bool {
if podSpec == nil {
return false
}
usesOCI := func(p *api.SeccompProfile) bool {
return p != nil && p.Type == api.SeccompProfileTypeOCI
}
if podSpec.SecurityContext != nil && usesOCI(podSpec.SecurityContext.SeccompProfile) {
return true
}
var inUse bool
VisitContainers(podSpec, AllContainers, func(c *api.Container, containerType ContainerType) bool {
if c.SecurityContext != nil && usesOCI(c.SecurityContext.SeccompProfile) {
inUse = true
return false
}
return true
})
return inUse
}
func clusterTrustBundleProjectionInUse(podSpec *api.PodSpec) bool {
if podSpec == nil {
return false
+75
View File
@@ -7362,3 +7362,78 @@ func TestGetValidationOptionsAllowMLDSAPodCertificateKeyTypes(t *testing.T) {
})
}
}
// TestSecurityProfileOCIValidationOption checks that nothing drops the oci
// field and that the option follows the gate or the old pod's use of OCI.
func TestSecurityProfileOCIValidationOption(t *testing.T) {
ociProfile := func() *api.SeccompProfile {
return &api.SeccompProfile{
Type: api.SeccompProfileTypeOCI,
OCI: &api.SecurityProfileOCI{Ref: "registry.example.com/profile@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"},
}
}
podWithPodOCI := func() *api.Pod {
return &api.Pod{Spec: api.PodSpec{
SecurityContext: &api.PodSecurityContext{SeccompProfile: ociProfile()},
Containers: []api.Container{{Name: "c"}},
}}
}
podWithContainerOCI := func() *api.Pod {
return &api.Pod{Spec: api.PodSpec{
InitContainers: []api.Container{{Name: "init", SecurityContext: &api.SecurityContext{SeccompProfile: ociProfile()}}},
Containers: []api.Container{{Name: "c", SecurityContext: &api.SecurityContext{SeccompProfile: ociProfile()}}},
}}
}
podWithoutOCI := func() *api.Pod {
return &api.Pod{Spec: api.PodSpec{
SecurityContext: &api.PodSecurityContext{SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault}},
Containers: []api.Container{{Name: "c"}},
}}
}
pods := map[string]struct {
pod func() *api.Pod
hasOCI bool
}{
"pod-level OCI": {pod: podWithPodOCI, hasOCI: true},
"container-level OCI": {pod: podWithContainerOCI, hasOCI: true},
"no OCI": {pod: podWithoutOCI},
"nil": {pod: func() *api.Pod { return nil }},
}
for _, enabled := range []bool{true, false} {
for oldName, oldInfo := range pods {
for newName, newInfo := range pods {
if newName == "nil" {
continue
}
t.Run(fmt.Sprintf("enabled=%v, old=%s, new=%s", enabled, oldName, newName), func(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SecurityProfileOCI, enabled)
oldPod := oldInfo.pod()
newPod := newInfo.pod()
DropDisabledPodFields(newPod, oldPod)
// The old pod is never changed.
if oldPod != nil && !reflect.DeepEqual(oldPod, oldInfo.pod()) {
t.Errorf("old pod changed: %v", cmp.Diff(oldInfo.pod(), oldPod))
}
if !reflect.DeepEqual(newPod, newInfo.pod()) {
t.Errorf("new pod changed: %v", cmp.Diff(newInfo.pod(), newPod))
}
keep := enabled || oldInfo.hasOCI
var oldSpec *api.PodSpec
if oldPod != nil {
oldSpec = &oldPod.Spec
}
opts := GetValidationOptionsFromPodSpecAndMeta(&newPod.Spec, oldSpec, nil, nil)
if opts.AllowSecurityProfileOCI != keep {
t.Errorf("expected AllowSecurityProfileOCI=%v, got %v", keep, opts.AllowSecurityProfileOCI)
}
})
}
}
}
}
+39
View File
@@ -4572,8 +4572,45 @@ type SeccompProfile struct {
// LocalhostProfile cannot be an absolute nor a descending path.
// +optional
LocalhostProfile *string
// Use a profile stored as an artifact in an OCI registry.
// +featureGate=SecurityProfileOCI
// +optional
OCI *SecurityProfileOCI
}
// SecurityProfileOCI references a security profile stored as an artifact in an
// OCI registry, with an optional base profile.
type SecurityProfileOCI struct {
// Fully qualified, digest-pinned OCI reference of the profile.
Ref string
// Base profile that the container runtime merges with the OCI profile; the
// runtime default profile when omitted.
// +optional
BaseProfile *SecurityProfileOCIBase
}
// SecurityProfileOCIBase specifies the base profile of an OCI security profile.
// +union
type SecurityProfileOCIBase struct {
// +unionDiscriminator
Type SecurityProfileOCIBaseType
// Load a base profile defined in a static file on the node.
// LocalhostProfile must be a relative path without '..' elements.
// +optional
LocalhostProfile *string
}
// SecurityProfileOCIBaseType defines the supported base profile types of an
// OCI security profile.
type SecurityProfileOCIBaseType string
const (
// SecurityProfileOCIBaseTypeRuntimeDefault represents the default container runtime profile.
SecurityProfileOCIBaseTypeRuntimeDefault SecurityProfileOCIBaseType = "RuntimeDefault"
// SecurityProfileOCIBaseTypeLocalhost represents custom made profiles stored on the node's disk.
SecurityProfileOCIBaseTypeLocalhost SecurityProfileOCIBaseType = "Localhost"
)
// SeccompProfileType defines the supported seccomp profile types.
type SeccompProfileType string
@@ -4584,6 +4621,8 @@ const (
SeccompProfileTypeRuntimeDefault SeccompProfileType = "RuntimeDefault"
// SeccompProfileTypeLocalhost represents custom made profiles stored on the node's disk.
SeccompProfileTypeLocalhost SeccompProfileType = "Localhost"
// SeccompProfileTypeOCI represents profiles pulled from an OCI registry.
SeccompProfileTypeOCI SeccompProfileType = "OCI"
)
// AppArmorProfile defines a pod or container's AppArmor settings.
+70
View File
@@ -19,7 +19,12 @@ package v1
import (
"context"
"fmt"
"path"
"slices"
"strings"
"unicode/utf8"
"github.com/distribution/reference"
"k8s.io/apimachinery/pkg/api/operation"
"k8s.io/apimachinery/pkg/util/validation/field"
@@ -69,3 +74,68 @@ func ValidateForbiddenReservedDomainSuffixes(fldPath *field.Path, value string,
}
return allErrors
}
// The custom validators below return early for values longer than the
// +k8s:maxLength of their field, so that an oversized value is neither parsed
// nor echoed in an error; the maxLength rule reports it. Like that rule, they
// count characters, and the constants must match the tags in
// staging/src/k8s.io/api/core/v1/types.go.
const (
securityProfileOCIRefMaxLength = 1024
securityProfileOCIBaseLocalhostProfileMaxLength = 4096
)
// ValidateCustom_SecurityProfileOCI_Ref is wired into the generated declarative
// validation by +k8s:customValidation on corev1.SecurityProfileOCI.Ref. It
// requires a canonical, digest-pinned OCI reference without a tag, with a
// sha256, sha384, or sha512 digest. Empty and oversized values are left to
// +k8s:required and +k8s:maxLength.
func ValidateCustom_SecurityProfileOCI_Ref(ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *string) field.ErrorList {
if value == nil || len(*value) == 0 || utf8.RuneCountInString(*value) > securityProfileOCIRefMaxLength {
return nil
}
named, err := reference.ParseNamed(*value)
if err != nil {
return field.ErrorList{field.Invalid(fldPath, *value, fmt.Sprintf("must be a digest-pinned reference in canonical form (<registry>/<repository>@<algorithm>:<digest>): %v", err))}
}
if _, ok := named.(reference.Tagged); ok {
return field.ErrorList{field.Invalid(fldPath, *value, "must not contain a tag")}
}
digested, ok := named.(reference.Digested)
if !ok {
return field.ErrorList{field.Invalid(fldPath, *value, "must be pinned by digest (<registry>/<repository>@<algorithm>:<digest>)")}
}
// The parser accepts any algorithm registered with go-digest; the API
// documents these three.
switch string(digested.Digest().Algorithm()) {
case "sha256", "sha384", "sha512":
return nil
}
return field.ErrorList{field.Invalid(fldPath, *value, "digest algorithm must be sha256, sha384, or sha512")}
}
// ValidateCustom_SecurityProfileOCIBase_LocalhostProfile is wired into the
// generated declarative validation by +k8s:customValidation on
// corev1.SecurityProfileOCIBase.LocalhostProfile. It requires a non-empty
// relative path without ".." elements, like the localhostProfile of a seccomp
// profile of type Localhost. Only "/" separates path elements: seccomp is
// Linux-only and the kubelet resolves the path on the node, where a backslash
// is an ordinary file name character. Whether the field may be set is decided
// by the union with the base profile type, and oversized values are left to
// +k8s:maxLength.
func ValidateCustom_SecurityProfileOCIBase_LocalhostProfile(ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *string) field.ErrorList {
if value == nil || utf8.RuneCountInString(*value) > securityProfileOCIBaseLocalhostProfileMaxLength {
return nil
}
if len(*value) == 0 {
return field.ErrorList{field.Required(fldPath, "must not be empty")}
}
var allErrs field.ErrorList
if path.IsAbs(*value) {
allErrs = append(allErrs, field.Invalid(fldPath, *value, "must be a relative path"))
}
if slices.Contains(strings.Split(*value, "/"), "..") {
allErrs = append(allErrs, field.Invalid(fldPath, *value, "must not contain '..'"))
}
return allErrs
}
+80
View File
@@ -17,9 +17,11 @@ limitations under the License.
package v1
import (
"context"
"strings"
"testing"
"k8s.io/apimachinery/pkg/api/operation"
"k8s.io/apimachinery/pkg/util/validation/field"
)
@@ -78,3 +80,81 @@ func TestValidateForbiddenReservedSuffixes(t *testing.T) {
}
}
}
func TestValidateCustom_SecurityProfileOCI_Ref(t *testing.T) {
const digest = "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
validValues := []string{
"registry.example.com/profile@" + digest,
"localhost:5000/profile@" + digest,
"docker.io/library/profile@" + digest,
"registry.example.com/profile@sha512:" + strings.Repeat("0123456789abcdef", 8),
"registry.example.com/profile@sha384:" + strings.Repeat("0123456789abcdef", 6),
}
for _, value := range validValues {
if errs := ValidateCustom_SecurityProfileOCI_Ref(context.Background(), operation.Operation{}, field.NewPath("ref"), &value, nil); len(errs) != 0 {
t.Errorf("expected no errors for %q: %v", value, errs)
}
}
invalidValues := map[string]string{
"short name": "profile@" + digest,
"repository without registry": "profiles/seccomp@" + digest,
"docker.io without library": "docker.io/profile@" + digest,
"tag": "registry.example.com/profile:v1",
"tag and digest": "registry.example.com/profile:v1@" + digest,
"neither tag nor digest": "registry.example.com/profile",
"digest of the wrong length": "registry.example.com/profile@sha256:0123",
"unregistered digest algorithm": "registry.example.com/profile@md5:" + strings.Repeat("0", 32),
// Longer than the maximum in bytes but not in characters, so maxLength
// does not reject it and the format check must.
"multibyte within the maximum": "registry.example.com/" + strings.Repeat("ä", 900) + "@" + digest,
}
for name, value := range invalidValues {
errs := ValidateCustom_SecurityProfileOCI_Ref(context.Background(), operation.Operation{}, field.NewPath("ref"), &value, nil)
if len(errs) != 1 || errs[0].Type != field.ErrorTypeInvalid {
t.Errorf("%s: expected one invalid error for %q, got %v", name, value, errs)
}
}
// Unset, empty, and oversized values are left to +k8s:required and +k8s:maxLength.
empty := ""
tooLong := strings.Repeat("a", securityProfileOCIRefMaxLength+1)
for _, value := range []*string{nil, &empty, &tooLong} {
if errs := ValidateCustom_SecurityProfileOCI_Ref(context.Background(), operation.Operation{}, field.NewPath("ref"), value, nil); len(errs) != 0 {
t.Errorf("expected no errors for %v: %v", value, errs)
}
}
}
func TestValidateCustom_SecurityProfileOCIBase_LocalhostProfile(t *testing.T) {
// A backslash is not a path separator; "profiles\..\base.json" is one
// file name below the seccomp root on the node.
for _, value := range []string{"profile.json", "profiles/agentic.json", "./profile.json", "profiles\\..\\base.json"} {
if errs := ValidateCustom_SecurityProfileOCIBase_LocalhostProfile(context.Background(), operation.Operation{}, field.NewPath("localhostProfile"), &value, nil); len(errs) != 0 {
t.Errorf("expected no errors for %q: %v", value, errs)
}
}
invalidValues := map[string]struct {
value string
errType field.ErrorType
}{
"empty": {"", field.ErrorTypeRequired},
"absolute path": {"/etc/profile.json", field.ErrorTypeInvalid},
"backsteps": {"../profile.json", field.ErrorTypeInvalid},
}
for name, tc := range invalidValues {
errs := ValidateCustom_SecurityProfileOCIBase_LocalhostProfile(context.Background(), operation.Operation{}, field.NewPath("localhostProfile"), &tc.value, nil)
if len(errs) != 1 || errs[0].Type != tc.errType {
t.Errorf("%s: expected one %s error for %q, got %v", name, tc.errType, tc.value, errs)
}
}
// Unset and oversized values are left to the union and +k8s:maxLength.
tooLong := strings.Repeat("a", securityProfileOCIBaseLocalhostProfileMaxLength+1)
for _, value := range []*string{nil, &tooLong} {
if errs := ValidateCustom_SecurityProfileOCIBase_LocalhostProfile(context.Background(), operation.Operation{}, field.NewPath("localhostProfile"), value, nil); len(errs) != 0 {
t.Errorf("expected no errors for %v: %v", value, errs)
}
}
}
+60
View File
@@ -2105,6 +2105,26 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*corev1.SecurityProfileOCI)(nil), (*core.SecurityProfileOCI)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_SecurityProfileOCI_To_core_SecurityProfileOCI(a.(*corev1.SecurityProfileOCI), b.(*core.SecurityProfileOCI), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*core.SecurityProfileOCI)(nil), (*corev1.SecurityProfileOCI)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_core_SecurityProfileOCI_To_v1_SecurityProfileOCI(a.(*core.SecurityProfileOCI), b.(*corev1.SecurityProfileOCI), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*corev1.SecurityProfileOCIBase)(nil), (*core.SecurityProfileOCIBase)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_SecurityProfileOCIBase_To_core_SecurityProfileOCIBase(a.(*corev1.SecurityProfileOCIBase), b.(*core.SecurityProfileOCIBase), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*core.SecurityProfileOCIBase)(nil), (*corev1.SecurityProfileOCIBase)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_core_SecurityProfileOCIBase_To_v1_SecurityProfileOCIBase(a.(*core.SecurityProfileOCIBase), b.(*corev1.SecurityProfileOCIBase), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*corev1.SerializedReference)(nil), (*core.SerializedReference)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_SerializedReference_To_core_SerializedReference(a.(*corev1.SerializedReference), b.(*core.SerializedReference), scope)
}); err != nil {
@@ -7283,6 +7303,46 @@ func Convert_core_SecurityContext_To_v1_SecurityContext(in *core.SecurityContext
return autoConvert_core_SecurityContext_To_v1_SecurityContext(in, out, s)
}
func autoConvert_v1_SecurityProfileOCI_To_core_SecurityProfileOCI(in *corev1.SecurityProfileOCI, out *core.SecurityProfileOCI, s conversion.Scope) error {
*out = *(*core.SecurityProfileOCI)(unsafe.Pointer(in))
return nil
}
// Convert_v1_SecurityProfileOCI_To_core_SecurityProfileOCI is an autogenerated conversion function.
func Convert_v1_SecurityProfileOCI_To_core_SecurityProfileOCI(in *corev1.SecurityProfileOCI, out *core.SecurityProfileOCI, s conversion.Scope) error {
return autoConvert_v1_SecurityProfileOCI_To_core_SecurityProfileOCI(in, out, s)
}
func autoConvert_core_SecurityProfileOCI_To_v1_SecurityProfileOCI(in *core.SecurityProfileOCI, out *corev1.SecurityProfileOCI, s conversion.Scope) error {
*out = *(*corev1.SecurityProfileOCI)(unsafe.Pointer(in))
return nil
}
// Convert_core_SecurityProfileOCI_To_v1_SecurityProfileOCI is an autogenerated conversion function.
func Convert_core_SecurityProfileOCI_To_v1_SecurityProfileOCI(in *core.SecurityProfileOCI, out *corev1.SecurityProfileOCI, s conversion.Scope) error {
return autoConvert_core_SecurityProfileOCI_To_v1_SecurityProfileOCI(in, out, s)
}
func autoConvert_v1_SecurityProfileOCIBase_To_core_SecurityProfileOCIBase(in *corev1.SecurityProfileOCIBase, out *core.SecurityProfileOCIBase, s conversion.Scope) error {
*out = *(*core.SecurityProfileOCIBase)(unsafe.Pointer(in))
return nil
}
// Convert_v1_SecurityProfileOCIBase_To_core_SecurityProfileOCIBase is an autogenerated conversion function.
func Convert_v1_SecurityProfileOCIBase_To_core_SecurityProfileOCIBase(in *corev1.SecurityProfileOCIBase, out *core.SecurityProfileOCIBase, s conversion.Scope) error {
return autoConvert_v1_SecurityProfileOCIBase_To_core_SecurityProfileOCIBase(in, out, s)
}
func autoConvert_core_SecurityProfileOCIBase_To_v1_SecurityProfileOCIBase(in *core.SecurityProfileOCIBase, out *corev1.SecurityProfileOCIBase, s conversion.Scope) error {
*out = *(*corev1.SecurityProfileOCIBase)(unsafe.Pointer(in))
return nil
}
// Convert_core_SecurityProfileOCIBase_To_v1_SecurityProfileOCIBase is an autogenerated conversion function.
func Convert_core_SecurityProfileOCIBase_To_v1_SecurityProfileOCIBase(in *core.SecurityProfileOCIBase, out *corev1.SecurityProfileOCIBase, s conversion.Scope) error {
return autoConvert_core_SecurityProfileOCIBase_To_v1_SecurityProfileOCIBase(in, out, s)
}
func autoConvert_v1_SerializedReference_To_core_SerializedReference(in *corev1.SerializedReference, out *core.SerializedReference, s conversion.Scope) error {
if err := Convert_v1_ObjectReference_To_core_ObjectReference(&in.Reference, &out.Reference, s); err != nil {
return err
+633 -3
View File
@@ -306,6 +306,70 @@ func Validate_ConfigMap(
return errs
}
// Validate_Container validates an instance of Container according
// to declarative validation rules in the API schema.
func Validate_Container(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.Container) (errs field.ErrorList) {
// field corev1.Container.Name has no validation
// field corev1.Container.Image has no validation
// field corev1.Container.Command has no validation
// field corev1.Container.Args has no validation
// field corev1.Container.WorkingDir has no validation
// field corev1.Container.Ports has no validation
// field corev1.Container.EnvFrom has no validation
// field corev1.Container.Env has no validation
// field corev1.Container.Resources has no validation
// field corev1.Container.ResizePolicy has no validation
// field corev1.Container.RestartPolicy has no validation
// field corev1.Container.RestartPolicyRules has no validation
// field corev1.Container.VolumeMounts has no validation
// field corev1.Container.VolumeDevices has no validation
// field corev1.Container.LivenessProbe has no validation
// field corev1.Container.ReadinessProbe has no validation
// field corev1.Container.StartupProbe has no validation
// field corev1.Container.Lifecycle has no validation
// field corev1.Container.TerminationMessagePath has no validation
// field corev1.Container.TerminationMessagePolicy has no validation
// field corev1.Container.ImagePullPolicy has no validation
{ // field corev1.Container.SecurityContext
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.SecurityContext,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// call the type's validation function
errs = append(errs, Validate_SecurityContext(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.Container) *corev1.SecurityContext {
return oldObj.SecurityContext
})
errs = append(errs, fn(fldPath.Child("securityContext"), obj.SecurityContext, oldVal, oldObj != nil)...)
}
// field corev1.Container.Stdin has no validation
// field corev1.Container.StdinOnce has no validation
// field corev1.Container.TTY has no validation
return errs
}
// Validate_Endpoints validates an instance of Endpoints according
// to declarative validation rules in the API schema.
func Validate_Endpoints(
@@ -340,6 +404,102 @@ func Validate_Endpoints(
return errs
}
// Validate_EphemeralContainer validates an instance of EphemeralContainer according
// to declarative validation rules in the API schema.
func Validate_EphemeralContainer(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.EphemeralContainer) (errs field.ErrorList) {
{ // field corev1.EphemeralContainer.EphemeralContainerCommon
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.EphemeralContainerCommon,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call the type's validation function
errs = append(errs, Validate_EphemeralContainerCommon(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.EphemeralContainer) *corev1.EphemeralContainerCommon {
return &oldObj.EphemeralContainerCommon
})
errs = append(errs, fn(safe.Value(fldPath, func() *field.Path { return fldPath.Child("corev1.EphemeralContainerCommon") }), &obj.EphemeralContainerCommon, oldVal, oldObj != nil)...)
}
// field corev1.EphemeralContainer.TargetContainerName has no validation
return errs
}
// Validate_EphemeralContainerCommon validates an instance of EphemeralContainerCommon according
// to declarative validation rules in the API schema.
func Validate_EphemeralContainerCommon(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.EphemeralContainerCommon) (errs field.ErrorList) {
// field corev1.EphemeralContainerCommon.Name has no validation
// field corev1.EphemeralContainerCommon.Image has no validation
// field corev1.EphemeralContainerCommon.Command has no validation
// field corev1.EphemeralContainerCommon.Args has no validation
// field corev1.EphemeralContainerCommon.WorkingDir has no validation
// field corev1.EphemeralContainerCommon.Ports has no validation
// field corev1.EphemeralContainerCommon.EnvFrom has no validation
// field corev1.EphemeralContainerCommon.Env has no validation
// field corev1.EphemeralContainerCommon.Resources has no validation
// field corev1.EphemeralContainerCommon.ResizePolicy has no validation
// field corev1.EphemeralContainerCommon.RestartPolicy has no validation
// field corev1.EphemeralContainerCommon.RestartPolicyRules has no validation
// field corev1.EphemeralContainerCommon.VolumeMounts has no validation
// field corev1.EphemeralContainerCommon.VolumeDevices has no validation
// field corev1.EphemeralContainerCommon.LivenessProbe has no validation
// field corev1.EphemeralContainerCommon.ReadinessProbe has no validation
// field corev1.EphemeralContainerCommon.StartupProbe has no validation
// field corev1.EphemeralContainerCommon.Lifecycle has no validation
// field corev1.EphemeralContainerCommon.TerminationMessagePath has no validation
// field corev1.EphemeralContainerCommon.TerminationMessagePolicy has no validation
// field corev1.EphemeralContainerCommon.ImagePullPolicy has no validation
{ // field corev1.EphemeralContainerCommon.SecurityContext
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.SecurityContext,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// call the type's validation function
errs = append(errs, Validate_SecurityContext(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.EphemeralContainerCommon) *corev1.SecurityContext {
return oldObj.SecurityContext
})
errs = append(errs, fn(fldPath.Child("securityContext"), obj.SecurityContext, oldVal, oldObj != nil)...)
}
// field corev1.EphemeralContainerCommon.Stdin has no validation
// field corev1.EphemeralContainerCommon.StdinOnce has no validation
// field corev1.EphemeralContainerCommon.TTY has no validation
return errs
}
// Validate_Event validates an instance of Event according
// to declarative validation rules in the API schema.
func Validate_Event(
@@ -1297,6 +1457,58 @@ func Validate_Pod(
return errs
}
// Validate_PodSecurityContext validates an instance of PodSecurityContext according
// to declarative validation rules in the API schema.
func Validate_PodSecurityContext(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.PodSecurityContext) (errs field.ErrorList) {
// field corev1.PodSecurityContext.SELinuxOptions has no validation
// field corev1.PodSecurityContext.WindowsOptions has no validation
// field corev1.PodSecurityContext.RunAsUser has no validation
// field corev1.PodSecurityContext.RunAsGroup has no validation
// field corev1.PodSecurityContext.RunAsNonRoot has no validation
// field corev1.PodSecurityContext.SupplementalGroups has no validation
// field corev1.PodSecurityContext.SupplementalGroupsPolicy has no validation
// field corev1.PodSecurityContext.FSGroup has no validation
// field corev1.PodSecurityContext.Sysctls has no validation
// field corev1.PodSecurityContext.FSGroupChangePolicy has no validation
{ // field corev1.PodSecurityContext.SeccompProfile
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.SeccompProfile,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// call the type's validation function
errs = append(errs, Validate_SeccompProfile(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.PodSecurityContext) *corev1.SeccompProfile {
return oldObj.SeccompProfile
})
errs = append(errs, fn(fldPath.Child("seccompProfile"), obj.SeccompProfile, oldVal, oldObj != nil)...)
}
// field corev1.PodSecurityContext.AppArmorProfile has no validation
// field corev1.PodSecurityContext.SELinuxChangePolicy has no validation
return errs
}
// Validate_PodSpec validates an instance of PodSpec according
// to declarative validation rules in the API schema.
func Validate_PodSpec(
@@ -1320,7 +1532,38 @@ func Validate_PodSpec(
}
// field corev1.PodSpec.Volumes has no validation
// field corev1.PodSpec.InitContainers has no validation
{ // field corev1.PodSpec.InitContainers
fn := func(
fldPath *field.Path,
obj, oldObj []corev1.Container,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// iterate the list and call the type's validation function
if e := validate.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Container); len(e) != 0 {
errs = append(errs, e...)
}
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.PodSpec) []corev1.Container {
return oldObj.InitContainers
})
errs = append(errs, fn(fldPath.Child("initContainers"), obj.InitContainers, oldVal, oldObj != nil)...)
}
{ // field corev1.PodSpec.Containers
fn := func(
@@ -1342,6 +1585,10 @@ func Validate_PodSpec(
if earlyReturn {
return // do not proceed
}
// iterate the list and call the type's validation function
if e := validate.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Container); len(e) != 0 {
errs = append(errs, e...)
}
return
}
oldVal := safe.Field(oldObj,
@@ -1351,7 +1598,38 @@ func Validate_PodSpec(
errs = append(errs, fn(fldPath.Child("containers"), obj.Containers, oldVal, oldObj != nil)...)
}
// field corev1.PodSpec.EphemeralContainers has no validation
{ // field corev1.PodSpec.EphemeralContainers
fn := func(
fldPath *field.Path,
obj, oldObj []corev1.EphemeralContainer,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// iterate the list and call the type's validation function
if e := validate.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_EphemeralContainer); len(e) != 0 {
errs = append(errs, e...)
}
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.PodSpec) []corev1.EphemeralContainer {
return oldObj.EphemeralContainers
})
errs = append(errs, fn(fldPath.Child("ephemeralContainers"), obj.EphemeralContainers, oldVal, oldObj != nil)...)
}
// field corev1.PodSpec.RestartPolicy has no validation
// field corev1.PodSpec.TerminationGracePeriodSeconds has no validation
@@ -1399,7 +1677,37 @@ func Validate_PodSpec(
// field corev1.PodSpec.HostPID has no validation
// field corev1.PodSpec.HostIPC has no validation
// field corev1.PodSpec.ShareProcessNamespace has no validation
// field corev1.PodSpec.SecurityContext has no validation
{ // field corev1.PodSpec.SecurityContext
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.PodSecurityContext,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// call the type's validation function
errs = append(errs, Validate_PodSecurityContext(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.PodSpec) *corev1.PodSecurityContext {
return oldObj.SecurityContext
})
errs = append(errs, fn(fldPath.Child("securityContext"), obj.SecurityContext, oldVal, oldObj != nil)...)
}
// field corev1.PodSpec.ImagePullSecrets has no validation
// field corev1.PodSpec.Hostname has no validation
// field corev1.PodSpec.Subdomain has no validation
@@ -2003,6 +2311,94 @@ func Validate_ResourceQuota(
return errs
}
var unionMembershipFor_k8s_io_api_core_v1_SeccompProfile_ = validate.NewDiscriminatedUnionMembership("type", validate.NewDiscriminatedUnionMember("oci", "OCI"))
// Validate_SeccompProfile validates an instance of SeccompProfile according
// to declarative validation rules in the API schema.
func Validate_SeccompProfile(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.SeccompProfile) (errs field.ErrorList) {
if e := validate.DiscriminatedUnion(ctx, op, fldPath, obj, oldObj, unionMembershipFor_k8s_io_api_core_v1_SeccompProfile_,
func(obj *corev1.SeccompProfile) string {
if obj == nil {
return ""
}
return string(obj.Type)
},
func(obj *corev1.SeccompProfile) bool {
if obj == nil {
return false
}
return obj.OCI != nil
}); len(e) != 0 {
errs = append(errs, e...)
}
{ // field corev1.SeccompProfile.Type
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.SeccompProfileType,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.SeccompProfile) *corev1.SeccompProfileType {
return &oldObj.Type
})
errs = append(errs, fn(fldPath.Child("type"), &obj.Type, oldVal, oldObj != nil)...)
}
// field corev1.SeccompProfile.LocalhostProfile has no validation
{ // field corev1.SeccompProfile.OCI
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.SecurityProfileOCI,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// call the type's validation function
errs = append(errs, Validate_SecurityProfileOCI(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.SeccompProfile) *corev1.SecurityProfileOCI {
return oldObj.OCI
})
errs = append(errs, fn(fldPath.Child("oci"), obj.OCI, oldVal, oldObj != nil)...)
}
return errs
}
// Validate_Secret validates an instance of Secret according
// to declarative validation rules in the API schema.
func Validate_Secret(
@@ -2072,6 +2468,240 @@ func Validate_Secret(
return errs
}
// Validate_SecurityContext validates an instance of SecurityContext according
// to declarative validation rules in the API schema.
func Validate_SecurityContext(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.SecurityContext) (errs field.ErrorList) {
// field corev1.SecurityContext.Capabilities has no validation
// field corev1.SecurityContext.Privileged has no validation
// field corev1.SecurityContext.SELinuxOptions has no validation
// field corev1.SecurityContext.WindowsOptions has no validation
// field corev1.SecurityContext.RunAsUser has no validation
// field corev1.SecurityContext.RunAsGroup has no validation
// field corev1.SecurityContext.RunAsNonRoot has no validation
// field corev1.SecurityContext.ReadOnlyRootFilesystem has no validation
// field corev1.SecurityContext.AllowPrivilegeEscalation has no validation
// field corev1.SecurityContext.ProcMount has no validation
{ // field corev1.SecurityContext.SeccompProfile
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.SeccompProfile,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// call the type's validation function
errs = append(errs, Validate_SeccompProfile(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.SecurityContext) *corev1.SeccompProfile {
return oldObj.SeccompProfile
})
errs = append(errs, fn(fldPath.Child("seccompProfile"), obj.SeccompProfile, oldVal, oldObj != nil)...)
}
// field corev1.SecurityContext.AppArmorProfile has no validation
return errs
}
// Validate_SecurityProfileOCI validates an instance of SecurityProfileOCI according
// to declarative validation rules in the API schema.
func Validate_SecurityProfileOCI(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.SecurityProfileOCI) (errs field.ErrorList) {
{ // field corev1.SecurityProfileOCI.Ref
fn := func(
fldPath *field.Path,
obj, oldObj *string,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// custom validation
if e := ValidateCustom_SecurityProfileOCI_Ref(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
}
if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 1024); len(e) != 0 {
errs = append(errs, e...)
}
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.SecurityProfileOCI) *string {
return &oldObj.Ref
})
errs = append(errs, fn(fldPath.Child("ref"), &obj.Ref, oldVal, oldObj != nil)...)
}
{ // field corev1.SecurityProfileOCI.BaseProfile
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.SecurityProfileOCIBase,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if validate.SemanticDeepEqual(obj, oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// call the type's validation function
errs = append(errs, Validate_SecurityProfileOCIBase(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.SecurityProfileOCI) *corev1.SecurityProfileOCIBase {
return oldObj.BaseProfile
})
errs = append(errs, fn(fldPath.Child("baseProfile"), obj.BaseProfile, oldVal, oldObj != nil)...)
}
return errs
}
var unionMembershipFor_k8s_io_api_core_v1_SecurityProfileOCIBase_ = validate.NewDiscriminatedUnionMembership("type", validate.NewDiscriminatedUnionMember("localhostProfile", "Localhost"))
// Validate_SecurityProfileOCIBase validates an instance of SecurityProfileOCIBase according
// to declarative validation rules in the API schema.
func Validate_SecurityProfileOCIBase(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.SecurityProfileOCIBase) (errs field.ErrorList) {
if e := validate.DiscriminatedUnion(ctx, op, fldPath, obj, oldObj, unionMembershipFor_k8s_io_api_core_v1_SecurityProfileOCIBase_,
func(obj *corev1.SecurityProfileOCIBase) string {
if obj == nil {
return ""
}
return string(obj.Type)
},
func(obj *corev1.SecurityProfileOCIBase) bool {
if obj == nil {
return false
}
return obj.LocalhostProfile != nil
}); len(e) != 0 {
errs = append(errs, e...)
}
{ // field corev1.SecurityProfileOCIBase.Type
fn := func(
fldPath *field.Path,
obj, oldObj *corev1.SecurityProfileOCIBaseType,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// call the type's validation function
errs = append(errs, Validate_SecurityProfileOCIBaseType(ctx, op, fldPath, obj, oldObj)...)
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.SecurityProfileOCIBase) *corev1.SecurityProfileOCIBaseType {
return &oldObj.Type
})
errs = append(errs, fn(fldPath.Child("type"), &obj.Type, oldVal, oldObj != nil)...)
}
{ // field corev1.SecurityProfileOCIBase.LocalhostProfile
fn := func(
fldPath *field.Path,
obj, oldObj *string,
oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update {
if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) {
return nil
}
}
// call field-attached validations
earlyReturn := false
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
// custom validation
if e := ValidateCustom_SecurityProfileOCIBase_LocalhostProfile(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
}
if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 4096); len(e) != 0 {
errs = append(errs, e...)
}
return
}
oldVal := safe.Field(oldObj,
func(oldObj *corev1.SecurityProfileOCIBase) *string {
return oldObj.LocalhostProfile
})
errs = append(errs, fn(fldPath.Child("localhostProfile"), obj.LocalhostProfile, oldVal, oldObj != nil)...)
}
return errs
}
var symbolsForSecurityProfileOCIBaseType = sets.New(corev1.SecurityProfileOCIBaseTypeLocalhost, corev1.SecurityProfileOCIBaseTypeRuntimeDefault)
// Validate_SecurityProfileOCIBaseType validates an instance of SecurityProfileOCIBaseType according
// to declarative validation rules in the API schema.
func Validate_SecurityProfileOCIBaseType(
ctx context.Context, op operation.Operation, fldPath *field.Path,
obj, oldObj *corev1.SecurityProfileOCIBaseType) (errs field.ErrorList) {
if e := validate.Enum(ctx, op, fldPath, obj, oldObj, symbolsForSecurityProfileOCIBaseType, nil); len(e) != 0 {
errs = append(errs, e...)
}
return errs
}
// Validate_Service validates an instance of Service according
// to declarative validation rules in the API schema.
func Validate_Service(
+57 -10
View File
@@ -4042,7 +4042,7 @@ func validateContainerCommon(ctr *core.Container, volumes map[string]core.Volume
allErrs = append(allErrs, validatePullPolicy(ctr.ImagePullPolicy, path.Child("imagePullPolicy"))...)
allErrs = append(allErrs, ValidateContainerResourceRequirements(&ctr.Resources, podClaimNames, path.Child("resources"), opts)...)
allErrs = append(allErrs, validateResizePolicy(ctr.ResizePolicy, path.Child("resizePolicy"), podRestartPolicy)...)
allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, path.Child("securityContext"), hostUsers, opts.AllowSysAdminWhenPrivilegeEscalationFalse)...)
allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, path.Child("securityContext"), hostUsers, opts.AllowSysAdminWhenPrivilegeEscalationFalse, opts.AllowSecurityProfileOCI)...)
return allErrs
}
@@ -4640,6 +4640,8 @@ type PodValidationOptions struct {
AllowEmptyImageVolumeReference bool
// Allow containers to have CAP_SYS_ADMIN even if AllowPrivilegeEscalation is false
AllowSysAdminWhenPrivilegeEscalationFalse bool
// Allow seccomp profiles of type OCI
AllowSecurityProfileOCI bool
// Allow podCertificate volumes to specify ML-DSA algorithms in the keyType field
AllowMLDSAPodCertificateKeyTypes bool
}
@@ -4814,6 +4816,9 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi
allErrs = append(allErrs, validateDNSPolicy(&spec.DNSPolicy, fldPath.Child("dnsPolicy"))...)
allErrs = append(allErrs, unversionedvalidation.ValidateLabels(spec.NodeSelector, fldPath.Child("nodeSelector"))...)
allErrs = append(allErrs, validatePodSpecSecurityContext(spec.SecurityContext, spec, fldPath, fldPath.Child("securityContext"), opts)...)
if opts.AllowSecurityProfileOCI {
allErrs = append(allErrs, validatePrivilegedContainersSeccompOCI(spec, fldPath)...)
}
allErrs = append(allErrs, validateShareProcessNamespace(spec, fldPath)...)
allErrs = append(allErrs, validateImagePullSecrets(spec.ImagePullSecrets, fldPath.Child("imagePullSecrets"))...)
allErrs = append(allErrs, validateAffinity(spec.Affinity, opts, fldPath.Child("affinity"))...)
@@ -5413,16 +5418,18 @@ func validatePodAffinity(podAffinity *core.PodAffinity, allowInvalidLabelValueIn
return allErrs
}
func validateSeccompProfileField(sp *core.SeccompProfile, fldPath *field.Path) field.ErrorList {
func validateSeccompProfileField(sp *core.SeccompProfile, fldPath *field.Path, allowOCI bool) field.ErrorList {
allErrs := field.ErrorList{}
if sp == nil {
return allErrs
}
if err := validateSeccompProfileType(fldPath.Child("type"), sp.Type); err != nil {
if err := validateSeccompProfileType(fldPath.Child("type"), sp.Type, allowOCI); err != nil {
allErrs = append(allErrs, err)
}
// The oci field is validated declaratively.
if sp.Type == core.SeccompProfileTypeLocalhost {
if sp.LocalhostProfile == nil {
allErrs = append(allErrs, field.Required(fldPath.Child("localhostProfile"), "must be set when seccomp type is Localhost"))
@@ -5438,6 +5445,35 @@ func validateSeccompProfileField(sp *core.SeccompProfile, fldPath *field.Path) f
return allErrs
}
// validatePrivilegedContainersSeccompOCI rejects privileged containers whose
// effective seccomp profile is of type OCI. Container runtimes do not apply
// seccomp profiles to privileged containers, so the profile would be ignored.
func validatePrivilegedContainersSeccompOCI(spec *core.PodSpec, specPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
var podProfile *core.SeccompProfile
if spec.SecurityContext != nil {
podProfile = spec.SecurityContext.SeccompProfile
}
podshelper.VisitContainersWithPath(spec, specPath, func(c *core.Container, cFldPath *field.Path) bool {
sc := c.SecurityContext
if sc == nil || sc.Privileged == nil || !*sc.Privileged {
return true
}
profile := podProfile
if sc.SeccompProfile != nil {
profile = sc.SeccompProfile
}
if profile != nil && profile.Type == core.SeccompProfileTypeOCI {
allErrs = append(allErrs, field.Forbidden(cFldPath.Child("securityContext", "privileged"), "privileged containers cannot use a seccomp profile of type OCI; set a seccompProfile of another type on the container"))
}
return true
})
return allErrs
}
func ValidateSeccompProfile(p string, fldPath *field.Path) field.ErrorList {
if p == core.SeccompProfileRuntimeDefault || p == core.DeprecatedSeccompProfileDockerDefault {
return nil
@@ -5466,15 +5502,22 @@ func ValidateSeccompPodAnnotations(annotations map[string]string, fldPath *field
}
// ValidateSeccompProfileType tests that the argument is a valid SeccompProfileType.
func validateSeccompProfileType(fldPath *field.Path, seccompProfileType core.SeccompProfileType) *field.Error {
func validateSeccompProfileType(fldPath *field.Path, seccompProfileType core.SeccompProfileType, allowOCI bool) *field.Error {
switch seccompProfileType {
case core.SeccompProfileTypeLocalhost, core.SeccompProfileTypeRuntimeDefault, core.SeccompProfileTypeUnconfined:
return nil
case core.SeccompProfileTypeOCI:
if allowOCI {
return nil
}
case "":
return field.Required(fldPath, "type is required when seccompProfile is set")
default:
return field.NotSupported(fldPath, seccompProfileType, []core.SeccompProfileType{core.SeccompProfileTypeLocalhost, core.SeccompProfileTypeRuntimeDefault, core.SeccompProfileTypeUnconfined})
return field.Required(fldPath, "type is required when seccompProfile is set").MarkCoveredByDeclarative()
}
supported := []core.SeccompProfileType{core.SeccompProfileTypeLocalhost, core.SeccompProfileTypeRuntimeDefault, core.SeccompProfileTypeUnconfined}
if allowOCI {
supported = append(supported, core.SeccompProfileTypeOCI)
}
return field.NotSupported(fldPath, seccompProfileType, supported)
}
func ValidateAppArmorProfileField(profile *core.AppArmorProfile, fldPath *field.Path) field.ErrorList {
@@ -5729,7 +5772,7 @@ func validatePodSpecSecurityContext(securityContext *core.PodSecurityContext, sp
allErrs = append(allErrs, validateFSGroupChangePolicy(securityContext.FSGroupChangePolicy, fldPath.Child("fsGroupChangePolicy"))...)
}
allErrs = append(allErrs, validateSeccompProfileField(securityContext.SeccompProfile, fldPath.Child("seccompProfile"))...)
allErrs = append(allErrs, validateSeccompProfileField(securityContext.SeccompProfile, fldPath.Child("seccompProfile"), opts.AllowSecurityProfileOCI)...)
allErrs = append(allErrs, validateWindowsSecurityContextOptions(securityContext.WindowsOptions, fldPath.Child("windowsOptions"))...)
allErrs = append(allErrs, ValidateAppArmorProfileField(securityContext.AppArmorProfile, fldPath.Child("appArmorProfile"))...)
@@ -5853,6 +5896,10 @@ func validateSeccompAnnotationsAndFieldsMatch(annotationValue string, seccompFie
} else if seccompField.LocalhostProfile == nil || strings.TrimPrefix(annotationValue, v1.SeccompLocalhostProfileNamePrefix) != *seccompField.LocalhostProfile {
return field.Forbidden(fldPath.Child("localhostProfile"), "seccomp profile in annotation and field must match")
}
case core.SeccompProfileTypeOCI:
// No annotation value represents an OCI profile.
return field.Forbidden(fldPath.Child("type"), "seccomp type in annotation and field must match")
}
return nil
@@ -8841,7 +8888,7 @@ func validateEndpointPort(port *core.EndpointPort, requireName bool, fldPath *fi
}
// ValidateSecurityContext ensures the security context contains valid settings
func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path, hostUsers, allowSysAdminWhenPrivilegeEscalationFalse bool) field.ErrorList {
func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path, hostUsers, allowSysAdminWhenPrivilegeEscalationFalse, allowSecurityProfileOCI bool) field.ErrorList {
allErrs := field.ErrorList{}
// this should only be true for testing since SecurityContext is defaulted by the core
if sc == nil {
@@ -8875,7 +8922,7 @@ func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path, host
}
}
allErrs = append(allErrs, validateSeccompProfileField(sc.SeccompProfile, fldPath.Child("seccompProfile"))...)
allErrs = append(allErrs, validateSeccompProfileField(sc.SeccompProfile, fldPath.Child("seccompProfile"), allowSecurityProfileOCI)...)
if sc.AllowPrivilegeEscalation != nil && !*sc.AllowPrivilegeEscalation {
if sc.Privileged != nil && *sc.Privileged {
allErrs = append(allErrs, field.Invalid(fldPath, sc, "cannot set `allowPrivilegeEscalation` to false and `privileged` to true"))
+175 -2
View File
@@ -25239,7 +25239,7 @@ func TestValidateSecurityContext(t *testing.T) {
"sys admin without privilege escalation": {sysAdminPriv, false, true},
}
for k, v := range successCases {
if errs := ValidateSecurityContext(v.sc, field.NewPath("field"), v.hostUsers, v.allowSysAdmin); len(errs) != 0 {
if errs := ValidateSecurityContext(v.sc, field.NewPath("field"), v.hostUsers, v.allowSysAdmin, false); len(errs) != 0 {
t.Errorf("[%s] Expected success, got %v", k, errs)
}
}
@@ -25299,7 +25299,7 @@ func TestValidateSecurityContext(t *testing.T) {
})
// note the unconditional `true` here for hostUsers. The failure case to test for ProcMount only includes it being true,
// and the field is ignored if ProcMount isn't set. Thus, we can unconditionally set to `true` and simplify the test matrix setup.
if errs := ValidateSecurityContext(v.sc, field.NewPath("field"), true, false); len(errs) == 0 || errs[0].Type != v.errorType || !strings.Contains(errs[0].Detail, v.errorDetail) {
if errs := ValidateSecurityContext(v.sc, field.NewPath("field"), true, false, false); len(errs) == 0 || errs[0].Type != v.errorType || !strings.Contains(errs[0].Detail, v.errorDetail) {
t.Errorf("[%s] Expected error type %q with detail %q, got %v", k, v.errorType, v.errorDetail, errs)
}
}
@@ -27621,6 +27621,12 @@ func TestValidateSeccompAnnotationsAndFieldsMatch(t *testing.T) {
seccompField: &core.SeccompProfile{Type: core.SeccompProfileTypeRuntimeDefault},
fldPath: rootFld,
expectedErr: field.Forbidden(rootFld.Child("type"), "seccomp type in annotation and field must match"),
}, {
description: "runtime/default annotation and SeccompProfileTypeOCI should error",
annotationValue: "runtime/default",
seccompField: &core.SeccompProfile{Type: core.SeccompProfileTypeOCI, OCI: &core.SecurityProfileOCI{Ref: validOCIProfileReference}},
fldPath: rootFld,
expectedErr: field.Forbidden(rootFld.Child("type"), "seccomp type in annotation and field must match"),
},
}
@@ -33326,3 +33332,170 @@ func TestValidateBasicResource(t *testing.T) {
})
}
}
const validOCIProfileReference = "registry.example.com/profiles/seccomp@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
// TestValidateSeccompProfileFieldOCI covers the handwritten part; the oci
// field is validated declaratively (test/declarative_validation/core/pod).
func TestValidateSeccompProfileFieldOCI(t *testing.T) {
fldPath := field.NewPath("seccompProfile")
oci := &core.SeccompProfile{Type: core.SeccompProfileTypeOCI, OCI: &core.SecurityProfileOCI{Ref: validOCIProfileReference}}
tests := []struct {
name string
profile *core.SeccompProfile
disallowOCI bool
expectedErrs field.ErrorList
}{{
name: "type OCI",
profile: oci,
}, {
name: "type OCI with a Localhost base profile",
profile: &core.SeccompProfile{
Type: core.SeccompProfileTypeOCI,
OCI: &core.SecurityProfileOCI{
Ref: validOCIProfileReference,
BaseProfile: &core.SecurityProfileOCIBase{Type: core.SecurityProfileOCIBaseTypeLocalhost, LocalhostProfile: new("profiles/base.json")},
},
},
}, {
name: "type OCI with the feature disabled",
profile: oci,
disallowOCI: true,
expectedErrs: field.ErrorList{field.NotSupported(fldPath.Child("type"), core.SeccompProfileTypeOCI, []core.SeccompProfileType{core.SeccompProfileTypeLocalhost, core.SeccompProfileTypeRuntimeDefault, core.SeccompProfileTypeUnconfined})},
}, {
name: "type OCI with localhostProfile",
profile: &core.SeccompProfile{
Type: core.SeccompProfileTypeOCI,
LocalhostProfile: new("profile.json"),
OCI: &core.SecurityProfileOCI{Ref: validOCIProfileReference},
},
expectedErrs: field.ErrorList{field.Invalid(fldPath.Child("localhostProfile"), nil, "")},
}}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
errs := validateSeccompProfileField(tc.profile, fldPath, !tc.disallowOCI)
matcher := field.ErrorMatcher{}.ByType().ByField()
matcher.Test(t, tc.expectedErrs, errs)
})
}
}
func TestValidatePrivilegedContainersSeccompOCI(t *testing.T) {
specPath := field.NewPath("spec")
oci := &core.SeccompProfile{Type: core.SeccompProfileTypeOCI, OCI: &core.SecurityProfileOCI{Ref: validOCIProfileReference}}
runtimeDefault := &core.SeccompProfile{Type: core.SeccompProfileTypeRuntimeDefault}
container := func(name string, privileged bool, profile *core.SeccompProfile) core.Container {
return core.Container{Name: name, SecurityContext: &core.SecurityContext{Privileged: new(privileged), SeccompProfile: profile}}
}
tests := []struct {
name string
spec *core.PodSpec
expectedErrs field.ErrorList
}{{
name: "unprivileged container with OCI profile",
spec: &core.PodSpec{Containers: []core.Container{container("c", false, oci)}},
}, {
name: "privileged container with RuntimeDefault profile and pod-level OCI profile",
spec: &core.PodSpec{
SecurityContext: &core.PodSecurityContext{SeccompProfile: oci},
Containers: []core.Container{container("c", true, runtimeDefault)},
},
}, {
name: "privileged container with OCI profile",
spec: &core.PodSpec{Containers: []core.Container{container("c", true, oci)}},
expectedErrs: field.ErrorList{field.Forbidden(specPath.Child("containers").Index(0).Child("securityContext", "privileged"), "")},
}, {
name: "privileged containers inheriting a pod-level OCI profile",
spec: &core.PodSpec{
SecurityContext: &core.PodSecurityContext{SeccompProfile: oci},
InitContainers: []core.Container{container("init", true, nil)},
Containers: []core.Container{container("c", false, nil)},
EphemeralContainers: []core.EphemeralContainer{{
EphemeralContainerCommon: core.EphemeralContainerCommon{Name: "debug", SecurityContext: &core.SecurityContext{Privileged: new(true)}},
}},
},
expectedErrs: field.ErrorList{
field.Forbidden(specPath.Child("initContainers").Index(0).Child("securityContext", "privileged"), ""),
field.Forbidden(specPath.Child("ephemeralContainers").Index(0).Child("securityContext", "privileged"), ""),
},
}}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
errs := validatePrivilegedContainersSeccompOCI(tc.spec, specPath)
matcher := field.ErrorMatcher{}.ByType().ByField()
matcher.Test(t, tc.expectedErrs, errs)
})
}
}
// TestValidatePodSecurityProfileOCI runs pods with OCI seccomp profiles through
// the pod validation entry points, so that the feature gate option and the
// privileged container rule are covered where they are wired in.
func TestValidatePodSecurityProfileOCI(t *testing.T) {
capabilities.ResetForTest()
capabilities.Initialize(capabilities.Capabilities{AllowPrivileged: true})
t.Cleanup(capabilities.ResetForTest)
oci := &core.SeccompProfile{Type: core.SeccompProfileTypeOCI, OCI: &core.SecurityProfileOCI{Ref: validOCIProfileReference}}
specPath := field.NewPath("spec")
createTests := []struct {
name string
pod *core.Pod
allowOCI bool
expectedErrs field.ErrorList
}{{
name: "container-level OCI profile",
pod: podtest.MakePod("pod", podtest.SetContainers(podtest.MakeContainer("ctr", podtest.SetContainerSecurityContext(core.SecurityContext{SeccompProfile: oci})))),
allowOCI: true,
}, {
name: "container-level OCI profile with the feature disabled",
pod: podtest.MakePod("pod", podtest.SetContainers(podtest.MakeContainer("ctr", podtest.SetContainerSecurityContext(core.SecurityContext{SeccompProfile: oci})))),
expectedErrs: field.ErrorList{field.NotSupported(specPath.Child("containers").Index(0).Child("securityContext", "seccompProfile", "type"), core.SeccompProfileTypeOCI, []core.SeccompProfileType(nil))},
}, {
name: "pod-level OCI profile with the feature disabled",
pod: podtest.MakePod("pod", podtest.SetSecurityContext(&core.PodSecurityContext{SeccompProfile: oci})),
expectedErrs: field.ErrorList{field.NotSupported(specPath.Child("securityContext", "seccompProfile", "type"), core.SeccompProfileTypeOCI, []core.SeccompProfileType(nil))},
}, {
name: "privileged container with a pod-level OCI profile and the feature disabled",
pod: podtest.MakePod("pod",
podtest.SetSecurityContext(&core.PodSecurityContext{SeccompProfile: oci}),
podtest.SetContainers(podtest.MakeContainer("ctr", podtest.SetContainerSecurityContext(core.SecurityContext{Privileged: new(true)})))),
expectedErrs: field.ErrorList{field.NotSupported(specPath.Child("securityContext", "seccompProfile", "type"), core.SeccompProfileTypeOCI, []core.SeccompProfileType(nil))},
}, {
name: "privileged container inheriting a pod-level OCI profile",
pod: podtest.MakePod("pod",
podtest.SetSecurityContext(&core.PodSecurityContext{SeccompProfile: oci}),
podtest.SetContainers(podtest.MakeContainer("ctr", podtest.SetContainerSecurityContext(core.SecurityContext{Privileged: new(true)})))),
allowOCI: true,
expectedErrs: field.ErrorList{field.Forbidden(specPath.Child("containers").Index(0).Child("securityContext", "privileged"), "")},
}}
for _, tc := range createTests {
t.Run(tc.name, func(t *testing.T) {
errs := ValidatePodCreate(tc.pod, PodValidationOptions{AllowSecurityProfileOCI: tc.allowOCI})
field.ErrorMatcher{}.ByType().ByField().Test(t, tc.expectedErrs, errs)
})
}
t.Run("privileged ephemeral container inheriting a pod-level OCI profile", func(t *testing.T) {
oldPod := podtest.MakePod("pod",
podtest.SetObjectMeta(metav1.ObjectMeta{Name: "pod", Namespace: "ns", ResourceVersion: "1"}),
podtest.SetSecurityContext(&core.PodSecurityContext{SeccompProfile: oci}))
newPod := oldPod.DeepCopy()
newPod.Spec.EphemeralContainers = []core.EphemeralContainer{{
EphemeralContainerCommon: core.EphemeralContainerCommon{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
SecurityContext: &core.SecurityContext{Privileged: new(true)},
},
}}
errs := ValidatePodEphemeralContainersUpdate(newPod, oldPod, PodValidationOptions{AllowSecurityProfileOCI: true})
field.ErrorMatcher{}.ByType().ByField().Test(t, field.ErrorList{
field.Forbidden(specPath.Child("ephemeralContainers").Index(0).Child("securityContext", "privileged"), ""),
}, errs)
})
}
+47
View File
@@ -5798,6 +5798,11 @@ func (in *SeccompProfile) DeepCopyInto(out *SeccompProfile) {
*out = new(string)
**out = **in
}
if in.OCI != nil {
in, out := &in.OCI, &out.OCI
*out = new(SecurityProfileOCI)
(*in).DeepCopyInto(*out)
}
return
}
@@ -6093,6 +6098,48 @@ func (in *SecurityContext) DeepCopy() *SecurityContext {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecurityProfileOCI) DeepCopyInto(out *SecurityProfileOCI) {
*out = *in
if in.BaseProfile != nil {
in, out := &in.BaseProfile, &out.BaseProfile
*out = new(SecurityProfileOCIBase)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityProfileOCI.
func (in *SecurityProfileOCI) DeepCopy() *SecurityProfileOCI {
if in == nil {
return nil
}
out := new(SecurityProfileOCI)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecurityProfileOCIBase) DeepCopyInto(out *SecurityProfileOCIBase) {
*out = *in
if in.LocalhostProfile != nil {
in, out := &in.LocalhostProfile, &out.LocalhostProfile
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityProfileOCIBase.
func (in *SecurityProfileOCIBase) DeepCopy() *SecurityProfileOCIBase {
if in == nil {
return nil
}
out := new(SecurityProfileOCIBase)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SerializedReference) DeepCopyInto(out *SerializedReference) {
*out = *in
+13
View File
@@ -1028,6 +1028,13 @@ const (
// Enables PreQueueingHint extension point to narrow pod evaluation on events.
SchedulerPreQueueingHints featuregate.Feature = "SchedulerPreQueueingHints"
// owner: @saschagrunert
// kep: https://kep.k8s.io/6061
//
// Enables seccomp profiles of type OCI, pulled from OCI registries by the
// container runtime and merged with a base profile.
SecurityProfileOCI featuregate.Feature = "SecurityProfileOCI"
// owner: @aramase
// kep: https://kep.k8s.io/4412
//
@@ -1953,6 +1960,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
{Version: version.MustParse("1.38"), Default: true, PreRelease: featuregate.Beta},
},
SecurityProfileOCI: {
{Version: version.MustParse("1.38"), Default: false, PreRelease: featuregate.Alpha},
},
ServiceAccountNodeAudienceRestriction: {
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Beta},
{Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta},
@@ -2617,6 +2628,8 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature
SchedulerPopFromBackoffQ: {},
SchedulerPreQueueingHints: {},
SecurityProfileOCI: {},
ServiceAccountNodeAudienceRestriction: {},
ServiceCIDRStatusFieldWiping: {},
+85 -2
View File
@@ -693,6 +693,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
corev1.SecretReference{}.OpenAPIModelName(): schema_k8sio_api_core_v1_SecretReference(ref),
corev1.SecretVolumeSource{}.OpenAPIModelName(): schema_k8sio_api_core_v1_SecretVolumeSource(ref),
corev1.SecurityContext{}.OpenAPIModelName(): schema_k8sio_api_core_v1_SecurityContext(ref),
corev1.SecurityProfileOCI{}.OpenAPIModelName(): schema_k8sio_api_core_v1_SecurityProfileOCI(ref),
corev1.SecurityProfileOCIBase{}.OpenAPIModelName(): schema_k8sio_api_core_v1_SecurityProfileOCIBase(ref),
corev1.SerializedReference{}.OpenAPIModelName(): schema_k8sio_api_core_v1_SerializedReference(ref),
corev1.Service{}.OpenAPIModelName(): schema_k8sio_api_core_v1_Service(ref),
corev1.ServiceAccount{}.OpenAPIModelName(): schema_k8sio_api_core_v1_ServiceAccount(ref),
@@ -31602,11 +31604,11 @@ func schema_k8sio_api_core_v1_SeccompProfile(ref common.ReferenceCallback) commo
Properties: map[string]spec.Schema{
"type": {
SchemaProps: spec.SchemaProps{
Description: "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.\n\nPossible enum values:\n - `\"Localhost\"` indicates a profile defined in a file on the node should be used. The file's location relative to <kubelet-root-dir>/seccomp.\n - `\"RuntimeDefault\"` represents the default container runtime seccomp profile.\n - `\"Unconfined\"` indicates no seccomp profile is applied (A.K.A. unconfined).",
Description: "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. OCI - a profile pulled from an OCI registry should be used, merged with a base profile (see oci.baseProfile). Privileged containers cannot use it, whether it is set on the container or inherited from the pod. This is an alpha value and requires enabling the SecurityProfileOCI feature gate.\n\nPossible enum values:\n - `\"Localhost\"` indicates a profile defined in a file on the node should be used. The file's location relative to <kubelet-root-dir>/seccomp.\n - `\"OCI\"` indicates a profile pulled from an OCI registry should be used.\n - `\"RuntimeDefault\"` represents the default container runtime seccomp profile.\n - `\"Unconfined\"` indicates no seccomp profile is applied (A.K.A. unconfined).",
Default: "",
Type: []string{"string"},
Format: "",
Enum: []interface{}{"Localhost", "RuntimeDefault", "Unconfined"},
Enum: []interface{}{"Localhost", "OCI", "RuntimeDefault", "Unconfined"},
},
},
"localhostProfile": {
@@ -31616,6 +31618,12 @@ func schema_k8sio_api_core_v1_SeccompProfile(ref common.ReferenceCallback) commo
Format: "",
},
},
"oci": {
SchemaProps: spec.SchemaProps{
Description: "oci specifies a seccomp profile stored as an artifact in an OCI registry. The container runtime merges the profile with a base profile, so the effective profile permits an operation only if both permit it. Must be set if type is \"OCI\". Must NOT be set for any other type. This is an alpha field and requires enabling the SecurityProfileOCI feature gate.",
Ref: ref(corev1.SecurityProfileOCI{}.OpenAPIModelName()),
},
},
},
Required: []string{"type"},
},
@@ -31626,12 +31634,15 @@ func schema_k8sio_api_core_v1_SeccompProfile(ref common.ReferenceCallback) commo
"discriminator": "type",
"fields-to-discriminateBy": map[string]interface{}{
"localhostProfile": "LocalhostProfile",
"oci": "OCI",
},
},
},
},
},
},
Dependencies: []string{
corev1.SecurityProfileOCI{}.OpenAPIModelName()},
}
}
@@ -32071,6 +32082,78 @@ func schema_k8sio_api_core_v1_SecurityContext(ref common.ReferenceCallback) comm
}
}
func schema_k8sio_api_core_v1_SecurityProfileOCI(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "SecurityProfileOCI references a security profile stored as an artifact in an OCI registry, with an optional base profile.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"ref": {
SchemaProps: spec.SchemaProps{
Description: "ref is the OCI reference of the profile. It must be a digest-pinned reference in canonical form, registry/repository@<algorithm>:<digest>, with the registry spelled out (for example docker.io/library/profile, not profile or docker.io/profile). Tags are rejected. The digest algorithm must be sha256, sha384, or sha512. The maximum length is 1024 characters. Pull secrets are assembled in the same way as for the container image by looking up node credentials, service account image pull secrets, and pod spec image pull secrets.",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"baseProfile": {
SchemaProps: spec.SchemaProps{
Description: "baseProfile optionally specifies the base profile that the container runtime merges with the OCI profile. The effective profile permits an operation only if both permit it. When omitted, the container runtime default profile is the base; a Localhost base profile takes its place.",
Ref: ref(corev1.SecurityProfileOCIBase{}.OpenAPIModelName()),
},
},
},
Required: []string{"ref"},
},
},
Dependencies: []string{
corev1.SecurityProfileOCIBase{}.OpenAPIModelName()},
}
}
func schema_k8sio_api_core_v1_SecurityProfileOCIBase(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "SecurityProfileOCIBase specifies the base profile of an OCI security profile.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"type": {
SchemaProps: spec.SchemaProps{
Description: "type indicates which kind of base profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used.\n\nPossible enum values:\n - `\"Localhost\"` indicates a profile defined in a file on the node should be used. For seccomp, the file's location is relative to <kubelet-root-dir>/seccomp.\n - `\"RuntimeDefault\"` represents the default container runtime profile.",
Default: "",
Type: []string{"string"},
Format: "",
Enum: []interface{}{"Localhost", "RuntimeDefault"},
},
},
"localhostProfile": {
SchemaProps: spec.SchemaProps{
Description: "localhostProfile indicates a base profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location, of at most 4096 characters. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"type"},
},
VendorExtensible: spec.VendorExtensible{
Extensions: spec.Extensions{
"x-kubernetes-unions": []interface{}{
map[string]interface{}{
"discriminator": "type",
"fields-to-discriminateBy": map[string]interface{}{
"localhostProfile": "LocalhostProfile",
},
},
},
},
},
},
}
}
func schema_k8sio_api_core_v1_SerializedReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
+417
View File
@@ -456,6 +456,10 @@ func (m *SecretVolumeSource) Reset() { *m = SecretVolumeSource{} }
func (m *SecurityContext) Reset() { *m = SecurityContext{} }
func (m *SecurityProfileOCI) Reset() { *m = SecurityProfileOCI{} }
func (m *SecurityProfileOCIBase) Reset() { *m = SecurityProfileOCIBase{} }
func (m *SerializedReference) Reset() { *m = SerializedReference{} }
func (m *Service) Reset() { *m = Service{} }
@@ -12700,6 +12704,18 @@ func (m *SeccompProfile) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.OCI != nil {
{
size, err := m.OCI.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
if m.LocalhostProfile != nil {
i -= len(*m.LocalhostProfile)
copy(dAtA[i:], *m.LocalhostProfile)
@@ -13243,6 +13259,81 @@ func (m *SecurityContext) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *SecurityProfileOCI) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *SecurityProfileOCI) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *SecurityProfileOCI) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.BaseProfile != nil {
{
size, err := m.BaseProfile.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
i -= len(m.Ref)
copy(dAtA[i:], m.Ref)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Ref)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func (m *SecurityProfileOCIBase) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *SecurityProfileOCIBase) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *SecurityProfileOCIBase) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.LocalhostProfile != nil {
i -= len(*m.LocalhostProfile)
copy(dAtA[i:], *m.LocalhostProfile)
i = encodeVarintGenerated(dAtA, i, uint64(len(*m.LocalhostProfile)))
i--
dAtA[i] = 0x12
}
i -= len(m.Type)
copy(dAtA[i:], m.Type)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Type)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func (m *SerializedReference) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -20063,6 +20154,10 @@ func (m *SeccompProfile) Size() (n int) {
l = len(*m.LocalhostProfile)
n += 1 + l + sovGenerated(uint64(l))
}
if m.OCI != nil {
l = m.OCI.Size()
n += 1 + l + sovGenerated(uint64(l))
}
return n
}
@@ -20259,6 +20354,36 @@ func (m *SecurityContext) Size() (n int) {
return n
}
func (m *SecurityProfileOCI) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Ref)
n += 1 + l + sovGenerated(uint64(l))
if m.BaseProfile != nil {
l = m.BaseProfile.Size()
n += 1 + l + sovGenerated(uint64(l))
}
return n
}
func (m *SecurityProfileOCIBase) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Type)
n += 1 + l + sovGenerated(uint64(l))
if m.LocalhostProfile != nil {
l = len(*m.LocalhostProfile)
n += 1 + l + sovGenerated(uint64(l))
}
return n
}
func (m *SerializedReference) Size() (n int) {
if m == nil {
return 0
@@ -24509,6 +24634,7 @@ func (this *SeccompProfile) String() string {
s := strings.Join([]string{`&SeccompProfile{`,
`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
`LocalhostProfile:` + valueToStringGenerated(this.LocalhostProfile) + `,`,
`OCI:` + strings.Replace(this.OCI.String(), "SecurityProfileOCI", "SecurityProfileOCI", 1) + `,`,
`}`,
}, "")
return s
@@ -24654,6 +24780,28 @@ func (this *SecurityContext) String() string {
}, "")
return s
}
func (this *SecurityProfileOCI) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&SecurityProfileOCI{`,
`Ref:` + fmt.Sprintf("%v", this.Ref) + `,`,
`BaseProfile:` + strings.Replace(this.BaseProfile.String(), "SecurityProfileOCIBase", "SecurityProfileOCIBase", 1) + `,`,
`}`,
}, "")
return s
}
func (this *SecurityProfileOCIBase) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&SecurityProfileOCIBase{`,
`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
`LocalhostProfile:` + valueToStringGenerated(this.LocalhostProfile) + `,`,
`}`,
}, "")
return s
}
func (this *SerializedReference) String() string {
if this == nil {
return "nil"
@@ -64232,6 +64380,42 @@ func (m *SeccompProfile) Unmarshal(dAtA []byte) error {
s := string(dAtA[iNdEx:postIndex])
m.LocalhostProfile = &s
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field OCI", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.OCI == nil {
m.OCI = &SecurityProfileOCI{}
}
if err := m.OCI.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -65817,6 +66001,239 @@ func (m *SecurityContext) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *SecurityProfileOCI) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: SecurityProfileOCI: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: SecurityProfileOCI: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Ref", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Ref = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field BaseProfile", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.BaseProfile == nil {
m.BaseProfile = &SecurityProfileOCIBase{}
}
if err := m.BaseProfile.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *SecurityProfileOCIBase) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: SecurityProfileOCIBase: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: SecurityProfileOCIBase: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Type = SecurityProfileOCIBaseType(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field LocalhostProfile", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(dAtA[iNdEx:postIndex])
m.LocalhostProfile = &s
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *SerializedReference) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@@ -918,6 +918,7 @@ message Container {
// If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.
// More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
optional SecurityContext securityContext = 15;
// stdin indicates whether this container should allocate a buffer for stdin in the container runtime. If this
@@ -1712,6 +1713,7 @@ message EphemeralContainerCommon {
// securityContext is optional: SecurityContext defines the security options the ephemeral container should be run with.
// If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
optional SecurityContext securityContext = 15;
// stdin indicates whether this container should allocate a buffer for stdin in the container runtime. If this
@@ -4656,6 +4658,7 @@ message PodSecurityContext {
// seccompProfile is the seccomp options to use by the containers in this pod.
// Note that this field cannot be set when spec.os.name is windows.
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
optional SeccompProfile seccompProfile = 10;
// appArmorProfile is the AppArmor options to use by the containers in this pod.
@@ -4724,6 +4727,7 @@ message PodSpec {
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +k8s:alpha(since: "1.38")=+k8s:optional
repeated Container initContainers = 20;
// containers is the list of containers belonging to the pod.
@@ -4746,6 +4750,7 @@ message PodSpec {
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +k8s:alpha(since: "1.38")=+k8s:optional
repeated EphemeralContainer ephemeralContainers = 34;
// restartPolicy is the restart policy for all containers within the pod.
@@ -4843,6 +4848,7 @@ message PodSpec {
// securityContext holds pod-level security attributes and common container settings.
// Optional: Defaults to empty. See type description for default values of each field.
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
optional PodSecurityContext securityContext = 14;
// imagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
@@ -6188,7 +6194,13 @@ message SeccompProfile {
// Localhost - a profile defined in a file on the node should be used.
// RuntimeDefault - the container runtime default profile should be used.
// Unconfined - no profile should be applied.
// OCI - a profile pulled from an OCI registry should be used, merged with a
// base profile (see oci.baseProfile). Privileged containers cannot use it,
// whether it is set on the container or inherited from the pod. This is an
// alpha value and requires enabling the SecurityProfileOCI feature gate.
// +unionDiscriminator
// +k8s:alpha(since: "1.38")=+k8s:required
// +k8s:unionDiscriminator
optional string type = 1;
// localhostProfile indicates a profile defined in a file on the node should be used.
@@ -6197,6 +6209,17 @@ message SeccompProfile {
// Must be set if type is "Localhost". Must NOT be set for any other type.
// +optional
optional string localhostProfile = 2;
// oci specifies a seccomp profile stored as an artifact in an OCI registry.
// The container runtime merges the profile with a base profile, so the
// effective profile permits an operation only if both permit it.
// Must be set if type is "OCI". Must NOT be set for any other type.
// This is an alpha field and requires enabling the SecurityProfileOCI feature gate.
// +featureGate=SecurityProfileOCI
// +optional
// +k8s:optional
// +k8s:unionMember
optional SecurityProfileOCI oci = 3;
}
// Secret holds secret data of a certain type. The total bytes of the values in
@@ -6444,6 +6467,7 @@ message SecurityContext {
// override the pod options.
// Note that this field cannot be set when spec.os.name is windows.
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
optional SeccompProfile seccompProfile = 11;
// appArmorProfile is the AppArmor options to use by this container. If set, this profile
@@ -6453,6 +6477,59 @@ message SecurityContext {
optional AppArmorProfile appArmorProfile = 12;
}
// SecurityProfileOCI references a security profile stored as an artifact in an
// OCI registry, with an optional base profile.
message SecurityProfileOCI {
// ref is the OCI reference of the profile.
// It must be a digest-pinned reference in canonical form,
// registry/repository@<algorithm>:<digest>, with the registry spelled out
// (for example docker.io/library/profile, not profile or docker.io/profile).
// Tags are rejected. The digest algorithm must be sha256, sha384, or sha512.
// The maximum length is 1024 characters.
// Pull secrets are assembled in the same way as for the container image by
// looking up node credentials, service account image pull secrets, and pod spec image pull secrets.
// +required
// +k8s:required
// +k8s:maxLength=1024
// +k8s:customValidation
optional string ref = 1;
// baseProfile optionally specifies the base profile that the container
// runtime merges with the OCI profile. The effective profile permits an
// operation only if both permit it. When omitted, the container runtime
// default profile is the base; a Localhost base profile takes its place.
// +optional
// +k8s:optional
optional SecurityProfileOCIBase baseProfile = 2;
}
// SecurityProfileOCIBase specifies the base profile of an OCI security profile.
// +union
message SecurityProfileOCIBase {
// type indicates which kind of base profile will be applied.
// Valid options are:
//
// Localhost - a profile defined in a file on the node should be used.
// RuntimeDefault - the container runtime default profile should be used.
// +unionDiscriminator
// +required
// +k8s:required
// +k8s:unionDiscriminator
optional string type = 1;
// localhostProfile indicates a base profile defined in a file on the node
// should be used. The profile must be preconfigured on the node to work.
// Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location,
// of at most 4096 characters.
// Must be set if type is "Localhost". Must NOT be set for any other type.
// +optional
// +k8s:optional
// +k8s:unionMember(memberName: "Localhost")
// +k8s:maxLength=4096
// +k8s:customValidation
optional string localhostProfile = 2;
}
// SerializedReference is a reference to serialized object.
message SerializedReference {
// reference is the reference to an object in the system.
+90
View File
@@ -3432,6 +3432,7 @@ type Container struct {
// If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.
// More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
SecurityContext *SecurityContext `json:"securityContext,omitempty" protobuf:"bytes,15,opt,name=securityContext"`
// Variables for interactive containers, these have very specialized use-cases (e.g. debugging)
@@ -4521,6 +4522,7 @@ type PodSpec struct {
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +k8s:alpha(since: "1.38")=+k8s:optional
InitContainers []Container `json:"initContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,20,rep,name=initContainers"`
// containers is the list of containers belonging to the pod.
// Containers cannot currently be added or removed.
@@ -4541,6 +4543,7 @@ type PodSpec struct {
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +k8s:alpha(since: "1.38")=+k8s:optional
EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,34,rep,name=ephemeralContainers"`
// restartPolicy is the restart policy for all containers within the pod.
// One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted.
@@ -4626,6 +4629,7 @@ type PodSpec struct {
// securityContext holds pod-level security attributes and common container settings.
// Optional: Defaults to empty. See type description for default values of each field.
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
SecurityContext *PodSecurityContext `json:"securityContext,omitempty" protobuf:"bytes,14,opt,name=securityContext"`
// imagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
// If specified, these secrets will be passed to individual puller implementations for them to use.
@@ -5339,6 +5343,7 @@ type PodSecurityContext struct {
// seccompProfile is the seccomp options to use by the containers in this pod.
// Note that this field cannot be set when spec.os.name is windows.
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" protobuf:"bytes,10,opt,name=seccompProfile"`
// appArmorProfile is the AppArmor options to use by the containers in this pod.
// Note that this field cannot be set when spec.os.name is windows.
@@ -5379,7 +5384,13 @@ type SeccompProfile struct {
// Localhost - a profile defined in a file on the node should be used.
// RuntimeDefault - the container runtime default profile should be used.
// Unconfined - no profile should be applied.
// OCI - a profile pulled from an OCI registry should be used, merged with a
// base profile (see oci.baseProfile). Privileged containers cannot use it,
// whether it is set on the container or inherited from the pod. This is an
// alpha value and requires enabling the SecurityProfileOCI feature gate.
// +unionDiscriminator
// +k8s:alpha(since: "1.38")=+k8s:required
// +k8s:unionDiscriminator
Type SeccompProfileType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=SeccompProfileType"`
// localhostProfile indicates a profile defined in a file on the node should be used.
// The profile must be preconfigured on the node to work.
@@ -5387,8 +5398,83 @@ type SeccompProfile struct {
// Must be set if type is "Localhost". Must NOT be set for any other type.
// +optional
LocalhostProfile *string `json:"localhostProfile,omitempty" protobuf:"bytes,2,opt,name=localhostProfile"`
// oci specifies a seccomp profile stored as an artifact in an OCI registry.
// The container runtime merges the profile with a base profile, so the
// effective profile permits an operation only if both permit it.
// Must be set if type is "OCI". Must NOT be set for any other type.
// This is an alpha field and requires enabling the SecurityProfileOCI feature gate.
// +featureGate=SecurityProfileOCI
// +optional
// +k8s:optional
// +k8s:unionMember
OCI *SecurityProfileOCI `json:"oci,omitempty" protobuf:"bytes,3,opt,name=oci"`
}
// SecurityProfileOCI references a security profile stored as an artifact in an
// OCI registry, with an optional base profile.
type SecurityProfileOCI struct {
// ref is the OCI reference of the profile.
// It must be a digest-pinned reference in canonical form,
// registry/repository@<algorithm>:<digest>, with the registry spelled out
// (for example docker.io/library/profile, not profile or docker.io/profile).
// Tags are rejected. The digest algorithm must be sha256, sha384, or sha512.
// The maximum length is 1024 characters.
// Pull secrets are assembled in the same way as for the container image by
// looking up node credentials, service account image pull secrets, and pod spec image pull secrets.
// +required
// +k8s:required
// +k8s:maxLength=1024
// +k8s:customValidation
Ref string `json:"ref" protobuf:"bytes,1,opt,name=ref"`
// baseProfile optionally specifies the base profile that the container
// runtime merges with the OCI profile. The effective profile permits an
// operation only if both permit it. When omitted, the container runtime
// default profile is the base; a Localhost base profile takes its place.
// +optional
// +k8s:optional
BaseProfile *SecurityProfileOCIBase `json:"baseProfile,omitempty" protobuf:"bytes,2,opt,name=baseProfile"`
}
// SecurityProfileOCIBase specifies the base profile of an OCI security profile.
// +union
type SecurityProfileOCIBase struct {
// type indicates which kind of base profile will be applied.
// Valid options are:
//
// Localhost - a profile defined in a file on the node should be used.
// RuntimeDefault - the container runtime default profile should be used.
// +unionDiscriminator
// +required
// +k8s:required
// +k8s:unionDiscriminator
Type SecurityProfileOCIBaseType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=SecurityProfileOCIBaseType"`
// localhostProfile indicates a base profile defined in a file on the node
// should be used. The profile must be preconfigured on the node to work.
// Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location,
// of at most 4096 characters.
// Must be set if type is "Localhost". Must NOT be set for any other type.
// +optional
// +k8s:optional
// +k8s:unionMember(memberName: "Localhost")
// +k8s:maxLength=4096
// +k8s:customValidation
LocalhostProfile *string `json:"localhostProfile,omitempty" protobuf:"bytes,2,opt,name=localhostProfile"`
}
// SecurityProfileOCIBaseType defines the supported base profile types of an
// OCI security profile.
// +enum
// +k8s:enum
type SecurityProfileOCIBaseType string
const (
// SecurityProfileOCIBaseTypeRuntimeDefault represents the default container runtime profile.
SecurityProfileOCIBaseTypeRuntimeDefault SecurityProfileOCIBaseType = "RuntimeDefault"
// SecurityProfileOCIBaseTypeLocalhost indicates a profile defined in a file on the node should be used.
// For seccomp, the file's location is relative to <kubelet-root-dir>/seccomp.
SecurityProfileOCIBaseTypeLocalhost SecurityProfileOCIBaseType = "Localhost"
)
// SeccompProfileType defines the supported seccomp profile types.
// +enum
// +k8s:validation-gen-nolint
@@ -5402,6 +5488,8 @@ const (
// SeccompProfileTypeLocalhost indicates a profile defined in a file on the node should be used.
// The file's location relative to <kubelet-root-dir>/seccomp.
SeccompProfileTypeLocalhost SeccompProfileType = "Localhost"
// SeccompProfileTypeOCI indicates a profile pulled from an OCI registry should be used.
SeccompProfileTypeOCI SeccompProfileType = "OCI"
)
// AppArmorProfile defines a pod or container's AppArmor settings.
@@ -5639,6 +5727,7 @@ type EphemeralContainerCommon struct {
// securityContext is optional: SecurityContext defines the security options the ephemeral container should be run with.
// If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
SecurityContext *SecurityContext `json:"securityContext,omitempty" protobuf:"bytes,15,opt,name=securityContext"`
// Variables for interactive containers, these have very specialized use-cases (e.g. debugging)
@@ -8852,6 +8941,7 @@ type SecurityContext struct {
// override the pod options.
// Note that this field cannot be set when spec.os.name is windows.
// +optional
// +k8s:alpha(since: "1.38")=+k8s:optional
SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" protobuf:"bytes,11,opt,name=seccompProfile"`
// appArmorProfile is the AppArmor options to use by this container. If set, this profile
// overrides the pod's appArmorProfile.
+22 -1
View File
@@ -2457,8 +2457,9 @@ func (ScopedResourceSelectorRequirement) SwaggerDoc() map[string]string {
var map_SeccompProfile = map[string]string{
"": "SeccompProfile defines a pod/container's seccomp profile settings. Only one profile source may be set.",
"type": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.",
"type": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. OCI - a profile pulled from an OCI registry should be used, merged with a base profile (see oci.baseProfile). Privileged containers cannot use it, whether it is set on the container or inherited from the pod. This is an alpha value and requires enabling the SecurityProfileOCI feature gate.",
"localhostProfile": "localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
"oci": "oci specifies a seccomp profile stored as an artifact in an OCI registry. The container runtime merges the profile with a base profile, so the effective profile permits an operation only if both permit it. Must be set if type is \"OCI\". Must NOT be set for any other type. This is an alpha field and requires enabling the SecurityProfileOCI feature gate.",
}
func (SeccompProfile) SwaggerDoc() map[string]string {
@@ -2560,6 +2561,26 @@ func (SecurityContext) SwaggerDoc() map[string]string {
return map_SecurityContext
}
var map_SecurityProfileOCI = map[string]string{
"": "SecurityProfileOCI references a security profile stored as an artifact in an OCI registry, with an optional base profile.",
"ref": "ref is the OCI reference of the profile. It must be a digest-pinned reference in canonical form, registry/repository@<algorithm>:<digest>, with the registry spelled out (for example docker.io/library/profile, not profile or docker.io/profile). Tags are rejected. The digest algorithm must be sha256, sha384, or sha512. The maximum length is 1024 characters. Pull secrets are assembled in the same way as for the container image by looking up node credentials, service account image pull secrets, and pod spec image pull secrets.",
"baseProfile": "baseProfile optionally specifies the base profile that the container runtime merges with the OCI profile. The effective profile permits an operation only if both permit it. When omitted, the container runtime default profile is the base; a Localhost base profile takes its place.",
}
func (SecurityProfileOCI) SwaggerDoc() map[string]string {
return map_SecurityProfileOCI
}
var map_SecurityProfileOCIBase = map[string]string{
"": "SecurityProfileOCIBase specifies the base profile of an OCI security profile.",
"type": "type indicates which kind of base profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used.",
"localhostProfile": "localhostProfile indicates a base profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location, of at most 4096 characters. Must be set if type is \"Localhost\". Must NOT be set for any other type.",
}
func (SecurityProfileOCIBase) SwaggerDoc() map[string]string {
return map_SecurityProfileOCIBase
}
var map_SerializedReference = map[string]string{
"": "SerializedReference is a reference to serialized object.",
"reference": "reference is the reference to an object in the system.",
+47
View File
@@ -5796,6 +5796,11 @@ func (in *SeccompProfile) DeepCopyInto(out *SeccompProfile) {
*out = new(string)
**out = **in
}
if in.OCI != nil {
in, out := &in.OCI, &out.OCI
*out = new(SecurityProfileOCI)
(*in).DeepCopyInto(*out)
}
return
}
@@ -6098,6 +6103,48 @@ func (in *SecurityContext) DeepCopy() *SecurityContext {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecurityProfileOCI) DeepCopyInto(out *SecurityProfileOCI) {
*out = *in
if in.BaseProfile != nil {
in, out := &in.BaseProfile, &out.BaseProfile
*out = new(SecurityProfileOCIBase)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityProfileOCI.
func (in *SecurityProfileOCI) DeepCopy() *SecurityProfileOCI {
if in == nil {
return nil
}
out := new(SecurityProfileOCI)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SecurityProfileOCIBase) DeepCopyInto(out *SecurityProfileOCIBase) {
*out = *in
if in.LocalhostProfile != nil {
in, out := &in.LocalhostProfile, &out.LocalhostProfile
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityProfileOCIBase.
func (in *SecurityProfileOCIBase) DeepCopy() *SecurityProfileOCIBase {
if in == nil {
return nil
}
out := new(SecurityProfileOCIBase)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SerializedReference) DeepCopyInto(out *SerializedReference) {
*out = *in
@@ -1071,6 +1071,16 @@ func (in SecurityContext) OpenAPIModelName() string {
return "io.k8s.api.core.v1.SecurityContext"
}
// OpenAPIModelName returns the OpenAPI model name for this type.
func (in SecurityProfileOCI) OpenAPIModelName() string {
return "io.k8s.api.core.v1.SecurityProfileOCI"
}
// OpenAPIModelName returns the OpenAPI model name for this type.
func (in SecurityProfileOCIBase) OpenAPIModelName() string {
return "io.k8s.api.core.v1.SecurityProfileOCIBase"
}
// OpenAPIModelName returns the OpenAPI model name for this type.
func (in SerializedReference) OpenAPIModelName() string {
return "io.k8s.api.core.v1.SerializedReference"
+32 -4
View File
@@ -836,7 +836,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1161,7 +1168,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1486,7 +1500,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1544,7 +1565,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -385,6 +385,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -623,6 +628,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -867,6 +877,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -966,6 +981,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -837,7 +837,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1162,7 +1169,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1487,7 +1501,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1545,7 +1566,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -393,6 +393,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -631,6 +636,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -875,6 +885,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -974,6 +989,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -838,7 +838,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1163,7 +1170,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1488,7 +1502,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1546,7 +1567,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -385,6 +385,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -623,6 +628,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -867,6 +877,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -966,6 +981,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -837,7 +837,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1162,7 +1169,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1487,7 +1501,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1545,7 +1566,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -393,6 +393,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -631,6 +636,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -875,6 +885,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -974,6 +989,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -837,7 +837,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1162,7 +1169,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1487,7 +1501,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1545,7 +1566,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -395,6 +395,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -633,6 +638,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -877,6 +887,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -976,6 +991,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -837,7 +837,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1162,7 +1169,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1487,7 +1501,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1545,7 +1566,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -393,6 +393,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -631,6 +636,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -875,6 +885,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -974,6 +989,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -836,7 +836,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1161,7 +1168,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1486,7 +1500,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1544,7 +1565,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -385,6 +385,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -623,6 +628,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -867,6 +877,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -966,6 +981,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -837,7 +837,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1162,7 +1169,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1487,7 +1501,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1545,7 +1566,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -393,6 +393,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -631,6 +636,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -875,6 +885,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -974,6 +989,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -838,7 +838,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1163,7 +1170,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1488,7 +1502,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1546,7 +1567,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -385,6 +385,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -623,6 +628,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -867,6 +877,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -966,6 +981,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -837,7 +837,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1162,7 +1169,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1487,7 +1501,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1545,7 +1566,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -393,6 +393,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -631,6 +636,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -875,6 +885,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -974,6 +989,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
+32 -4
View File
@@ -920,7 +920,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1245,7 +1252,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1570,7 +1584,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1628,7 +1649,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -460,6 +460,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -698,6 +703,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -942,6 +952,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -1041,6 +1056,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
+32 -4
View File
@@ -871,7 +871,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1196,7 +1203,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1521,7 +1535,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1579,7 +1600,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
+20
View File
@@ -424,6 +424,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -662,6 +667,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -906,6 +916,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -1005,6 +1020,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -920,7 +920,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1245,7 +1252,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1570,7 +1584,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1628,7 +1649,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -460,6 +460,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -698,6 +703,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -942,6 +952,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -1041,6 +1056,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
+32 -4
View File
@@ -778,7 +778,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1103,7 +1110,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1428,7 +1442,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1486,7 +1507,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
+20
View File
@@ -341,6 +341,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -579,6 +584,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -823,6 +833,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -922,6 +937,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -821,7 +821,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1146,7 +1153,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1471,7 +1485,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1529,7 +1550,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
Binary file not shown.
@@ -374,6 +374,11 @@ template:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -612,6 +617,11 @@ template:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -856,6 +866,11 @@ template:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -955,6 +970,11 @@ template:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -827,7 +827,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1152,7 +1159,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1477,7 +1491,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1535,7 +1556,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -379,6 +379,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -617,6 +622,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -861,6 +871,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -960,6 +975,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -836,7 +836,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1161,7 +1168,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1486,7 +1500,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1544,7 +1565,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -385,6 +385,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -623,6 +628,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -867,6 +877,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -966,6 +981,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -837,7 +837,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1162,7 +1169,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1487,7 +1501,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1545,7 +1566,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -395,6 +395,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -633,6 +638,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -877,6 +887,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -976,6 +991,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -838,7 +838,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1163,7 +1170,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1488,7 +1502,14 @@
"procMount": "procMountValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -1546,7 +1567,14 @@
"fsGroupChangePolicy": "fsGroupChangePolicyValue",
"seccompProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
"localhostProfile": "localhostProfileValue",
"oci": {
"ref": "refValue",
"baseProfile": {
"type": "typeValue",
"localhostProfile": "localhostProfileValue"
}
}
},
"appArmorProfile": {
"type": "typeValue",
@@ -385,6 +385,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -623,6 +628,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -867,6 +877,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
windowsOptions:
gmsaCredentialSpec: gmsaCredentialSpecValue
@@ -966,6 +981,11 @@ spec:
user: userValue
seccompProfile:
localhostProfile: localhostProfileValue
oci:
baseProfile:
localhostProfile: localhostProfileValue
type: typeValue
ref: refValue
type: typeValue
supplementalGroups:
- 4
@@ -34,12 +34,22 @@ type SeccompProfileApplyConfiguration struct {
// Localhost - a profile defined in a file on the node should be used.
// RuntimeDefault - the container runtime default profile should be used.
// Unconfined - no profile should be applied.
// OCI - a profile pulled from an OCI registry should be used, merged with a
// base profile (see oci.baseProfile). Privileged containers cannot use it,
// whether it is set on the container or inherited from the pod. This is an
// alpha value and requires enabling the SecurityProfileOCI feature gate.
Type *corev1.SeccompProfileType `json:"type,omitempty"`
// localhostProfile indicates a profile defined in a file on the node should be used.
// The profile must be preconfigured on the node to work.
// Must be a descending path, relative to the kubelet's configured seccomp profile location.
// Must be set if type is "Localhost". Must NOT be set for any other type.
LocalhostProfile *string `json:"localhostProfile,omitempty"`
// oci specifies a seccomp profile stored as an artifact in an OCI registry.
// The container runtime merges the profile with a base profile, so the
// effective profile permits an operation only if both permit it.
// Must be set if type is "OCI". Must NOT be set for any other type.
// This is an alpha field and requires enabling the SecurityProfileOCI feature gate.
OCI *SecurityProfileOCIApplyConfiguration `json:"oci,omitempty"`
}
// SeccompProfileApplyConfiguration constructs a declarative configuration of the SeccompProfile type for use with
@@ -63,3 +73,11 @@ func (b *SeccompProfileApplyConfiguration) WithLocalhostProfile(value string) *S
b.LocalhostProfile = &value
return b
}
// WithOCI sets the OCI field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the OCI field is set to the value of the last call.
func (b *SeccompProfileApplyConfiguration) WithOCI(value *SecurityProfileOCIApplyConfiguration) *SeccompProfileApplyConfiguration {
b.OCI = value
return b
}
@@ -0,0 +1,63 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v1
// SecurityProfileOCIApplyConfiguration represents a declarative configuration of the SecurityProfileOCI type for use
// with apply.
//
// SecurityProfileOCI references a security profile stored as an artifact in an
// OCI registry, with an optional base profile.
type SecurityProfileOCIApplyConfiguration struct {
// ref is the OCI reference of the profile.
// It must be a digest-pinned reference in canonical form,
// registry/repository@<algorithm>:<digest>, with the registry spelled out
// (for example docker.io/library/profile, not profile or docker.io/profile).
// Tags are rejected. The digest algorithm must be sha256, sha384, or sha512.
// The maximum length is 1024 characters.
// Pull secrets are assembled in the same way as for the container image by
// looking up node credentials, service account image pull secrets, and pod spec image pull secrets.
Ref *string `json:"ref,omitempty"`
// baseProfile optionally specifies the base profile that the container
// runtime merges with the OCI profile. The effective profile permits an
// operation only if both permit it. When omitted, the container runtime
// default profile is the base; a Localhost base profile takes its place.
BaseProfile *SecurityProfileOCIBaseApplyConfiguration `json:"baseProfile,omitempty"`
}
// SecurityProfileOCIApplyConfiguration constructs a declarative configuration of the SecurityProfileOCI type for use with
// apply.
func SecurityProfileOCI() *SecurityProfileOCIApplyConfiguration {
return &SecurityProfileOCIApplyConfiguration{}
}
// WithRef sets the Ref field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Ref field is set to the value of the last call.
func (b *SecurityProfileOCIApplyConfiguration) WithRef(value string) *SecurityProfileOCIApplyConfiguration {
b.Ref = &value
return b
}
// WithBaseProfile sets the BaseProfile field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the BaseProfile field is set to the value of the last call.
func (b *SecurityProfileOCIApplyConfiguration) WithBaseProfile(value *SecurityProfileOCIBaseApplyConfiguration) *SecurityProfileOCIApplyConfiguration {
b.BaseProfile = value
return b
}
@@ -0,0 +1,64 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by applyconfiguration-gen. DO NOT EDIT.
package v1
import (
corev1 "k8s.io/api/core/v1"
)
// SecurityProfileOCIBaseApplyConfiguration represents a declarative configuration of the SecurityProfileOCIBase type for use
// with apply.
//
// SecurityProfileOCIBase specifies the base profile of an OCI security profile.
type SecurityProfileOCIBaseApplyConfiguration struct {
// type indicates which kind of base profile will be applied.
// Valid options are:
//
// Localhost - a profile defined in a file on the node should be used.
// RuntimeDefault - the container runtime default profile should be used.
Type *corev1.SecurityProfileOCIBaseType `json:"type,omitempty"`
// localhostProfile indicates a base profile defined in a file on the node
// should be used. The profile must be preconfigured on the node to work.
// Must be a non-empty descending path, relative to the kubelet's configured seccomp profile location,
// of at most 4096 characters.
// Must be set if type is "Localhost". Must NOT be set for any other type.
LocalhostProfile *string `json:"localhostProfile,omitempty"`
}
// SecurityProfileOCIBaseApplyConfiguration constructs a declarative configuration of the SecurityProfileOCIBase type for use with
// apply.
func SecurityProfileOCIBase() *SecurityProfileOCIBaseApplyConfiguration {
return &SecurityProfileOCIBaseApplyConfiguration{}
}
// WithType sets the Type field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Type field is set to the value of the last call.
func (b *SecurityProfileOCIBaseApplyConfiguration) WithType(value corev1.SecurityProfileOCIBaseType) *SecurityProfileOCIBaseApplyConfiguration {
b.Type = &value
return b
}
// WithLocalhostProfile sets the LocalhostProfile field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the LocalhostProfile field is set to the value of the last call.
func (b *SecurityProfileOCIBaseApplyConfiguration) WithLocalhostProfile(value string) *SecurityProfileOCIBaseApplyConfiguration {
b.LocalhostProfile = &value
return b
}
@@ -8040,6 +8040,9 @@ var schemaYAML = typed.YAMLObject(`types:
- name: localhostProfile
type:
scalar: string
- name: oci
type:
namedType: io.k8s.api.core.v1.SecurityProfileOCI
- name: type
type:
scalar: string
@@ -8049,6 +8052,8 @@ var schemaYAML = typed.YAMLObject(`types:
fields:
- fieldName: localhostProfile
discriminatorValue: LocalhostProfile
- fieldName: oci
discriminatorValue: OCI
- name: io.k8s.api.core.v1.Secret
map:
fields:
@@ -8189,6 +8194,31 @@ var schemaYAML = typed.YAMLObject(`types:
- name: windowsOptions
type:
namedType: io.k8s.api.core.v1.WindowsSecurityContextOptions
- name: io.k8s.api.core.v1.SecurityProfileOCI
map:
fields:
- name: baseProfile
type:
namedType: io.k8s.api.core.v1.SecurityProfileOCIBase
- name: ref
type:
scalar: string
default: ""
- name: io.k8s.api.core.v1.SecurityProfileOCIBase
map:
fields:
- name: localhostProfile
type:
scalar: string
- name: type
type:
scalar: string
default: ""
unions:
- discriminator: type
fields:
- fieldName: localhostProfile
discriminatorValue: LocalhostProfile
- name: io.k8s.api.core.v1.Service
map:
fields:
@@ -980,6 +980,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &applyconfigurationscorev1.SecretVolumeSourceApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("SecurityContext"):
return &applyconfigurationscorev1.SecurityContextApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("SecurityProfileOCI"):
return &applyconfigurationscorev1.SecurityProfileOCIApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("SecurityProfileOCIBase"):
return &applyconfigurationscorev1.SecurityProfileOCIBaseApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("SELinuxOptions"):
return &applyconfigurationscorev1.SELinuxOptionsApplyConfiguration{}
case corev1.SchemeGroupVersion.WithKind("Service"):
@@ -23,6 +23,7 @@ import (
"k8s.io/component-helpers/nodedeclaredfeatures/features/inplacepodresize"
"k8s.io/component-helpers/nodedeclaredfeatures/features/podcertificatesmldsa"
"k8s.io/component-helpers/nodedeclaredfeatures/features/restartallcontainers"
"k8s.io/component-helpers/nodedeclaredfeatures/features/securityprofileoci"
"k8s.io/component-helpers/nodedeclaredfeatures/features/usernamespaceshostnetwork"
"k8s.io/component-helpers/nodedeclaredfeatures/features/volumebindmountoptions"
"k8s.io/component-helpers/nodedeclaredfeatures/types"
@@ -42,4 +43,5 @@ var AllFeatures = []types.Feature{
volumebindmountoptions.Feature,
draoptionalnodeoperations.Feature,
podcertificatesmldsa.Feature,
securityprofileoci.Feature,
}
@@ -0,0 +1,113 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package securityprofileoci
import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/version"
"k8s.io/component-helpers/nodedeclaredfeatures/types"
)
// Ensure the feature struct implements the unified Feature interface.
var _ types.Feature = &securityProfileOCIFeature{}
const (
// SecurityProfileOCIFeatureGate is the feature gate name.
SecurityProfileOCIFeatureGate = "SecurityProfileOCI"
// SecurityProfileOCI is the declared feature name.
SecurityProfileOCI = "SecurityProfileOCI"
)
// Feature is the implementation of the `SecurityProfileOCI` feature.
var Feature = &securityProfileOCIFeature{}
type securityProfileOCIFeature struct{}
func (f *securityProfileOCIFeature) Name() string {
return SecurityProfileOCI
}
func (f *securityProfileOCIFeature) Requirements() *types.FeatureRequirements {
return &types.FeatureRequirements{
EnabledFeatureGates: []string{SecurityProfileOCIFeatureGate},
RequiredRuntimeFeatures: &types.RuntimeFeatures{
SeccompProfileOCI: true,
},
}
}
func (f *securityProfileOCIFeature) Discover(cfg *types.NodeConfiguration) bool {
// The feature gate must be enabled and the container runtime must
// support OCI seccomp profiles.
if !cfg.FeatureGates.Enabled(SecurityProfileOCIFeatureGate) {
return false
}
return cfg.RuntimeFeatures.SeccompProfileOCI
}
func (f *securityProfileOCIFeature) InferForScheduling(podInfo *types.PodInfo) bool {
return podSpecUsesSeccompProfileOCI(podInfo.Spec)
}
func (f *securityProfileOCIFeature) InferForUpdate(oldPodInfo, newPodInfo *types.PodInfo) bool {
// Seccomp profiles of existing containers are immutable, so only an update
// that adds the first OCI profile introduces the requirement: adding an
// ephemeral container with an OCI profile to a pod without one. The API
// server does not validate the ephemeralcontainers subresource against
// declared features; the kubelet reports a missing feature with a
// FailedNodeDeclaredFeaturesCheck event, and the container runtime
// rejects the profile.
return !podSpecUsesSeccompProfileOCI(oldPodInfo.Spec) && podSpecUsesSeccompProfileOCI(newPodInfo.Spec)
}
func (f *securityProfileOCIFeature) MaxVersion() *version.Version {
return nil
}
func podSpecUsesSeccompProfileOCI(spec *v1.PodSpec) bool {
if spec == nil {
return false
}
if spec.SecurityContext != nil && isOCI(spec.SecurityContext.SeccompProfile) {
return true
}
for i := range spec.InitContainers {
if containerUsesOCI(spec.InitContainers[i].SecurityContext) {
return true
}
}
for i := range spec.Containers {
if containerUsesOCI(spec.Containers[i].SecurityContext) {
return true
}
}
for i := range spec.EphemeralContainers {
if containerUsesOCI(spec.EphemeralContainers[i].SecurityContext) {
return true
}
}
return false
}
func containerUsesOCI(sc *v1.SecurityContext) bool {
return sc != nil && isOCI(sc.SeccompProfile)
}
func isOCI(profile *v1.SeccompProfile) bool {
return profile != nil && profile.Type == v1.SeccompProfileTypeOCI
}
@@ -0,0 +1,129 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package securityprofileoci
import (
"testing"
v1 "k8s.io/api/core/v1"
"k8s.io/component-helpers/nodedeclaredfeatures/types"
)
type fakeFeatureGate map[string]bool
func (f fakeFeatureGate) Enabled(key string) bool {
return f[key]
}
func TestDiscover(t *testing.T) {
for _, tc := range []struct {
name string
featureGate bool
runtimeSupport bool
expected bool
}{
{name: "feature gate disabled", featureGate: false, runtimeSupport: true, expected: false},
{name: "feature gate enabled but no runtime support", featureGate: true, runtimeSupport: false, expected: false},
{name: "feature gate enabled and runtime supports it", featureGate: true, runtimeSupport: true, expected: true},
} {
t.Run(tc.name, func(t *testing.T) {
cfg := &types.NodeConfiguration{
FeatureGates: fakeFeatureGate{SecurityProfileOCIFeatureGate: tc.featureGate},
RuntimeFeatures: types.RuntimeFeatures{SeccompProfileOCI: tc.runtimeSupport},
}
if got := Feature.Discover(cfg); got != tc.expected {
t.Errorf("Discover() = %v, expected %v", got, tc.expected)
}
})
}
}
func TestRequirements(t *testing.T) {
reqs := Feature.Requirements()
if reqs == nil || len(reqs.EnabledFeatureGates) != 1 || reqs.EnabledFeatureGates[0] != SecurityProfileOCIFeatureGate {
t.Fatalf("unexpected requirements: %+v", reqs)
}
if reqs.RequiredRuntimeFeatures == nil || !reqs.RequiredRuntimeFeatures.SeccompProfileOCI {
t.Errorf("expected the SeccompProfileOCI runtime feature to be required, got %+v", reqs.RequiredRuntimeFeatures)
}
}
func TestName(t *testing.T) {
if Feature.Name() != SecurityProfileOCI {
t.Fatalf("expected Name to be %s, got %s", SecurityProfileOCI, Feature.Name())
}
}
func TestInferForScheduling(t *testing.T) {
oci := &v1.SeccompProfile{Type: v1.SeccompProfileTypeOCI, OCI: &v1.SecurityProfileOCI{Ref: "registry.example.com/profile@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}}
runtimeDefault := &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}
withProfile := func(profile *v1.SeccompProfile) *v1.SecurityContext {
return &v1.SecurityContext{SeccompProfile: profile}
}
tests := []struct {
name string
spec *v1.PodSpec
expected bool
}{{
name: "no security context",
spec: &v1.PodSpec{Containers: []v1.Container{{Name: "c"}}},
}, {
name: "RuntimeDefault profiles",
spec: &v1.PodSpec{
SecurityContext: &v1.PodSecurityContext{SeccompProfile: runtimeDefault},
Containers: []v1.Container{{Name: "c", SecurityContext: withProfile(runtimeDefault)}},
},
}, {
name: "pod-level OCI profile",
spec: &v1.PodSpec{SecurityContext: &v1.PodSecurityContext{SeccompProfile: oci}, Containers: []v1.Container{{Name: "c"}}},
expected: true,
}, {
name: "container OCI profile",
spec: &v1.PodSpec{Containers: []v1.Container{{Name: "a"}, {Name: "b", SecurityContext: withProfile(oci)}}},
expected: true,
}, {
name: "init container OCI profile",
spec: &v1.PodSpec{InitContainers: []v1.Container{{Name: "init", SecurityContext: withProfile(oci)}}, Containers: []v1.Container{{Name: "c"}}},
expected: true,
}, {
name: "ephemeral container OCI profile",
spec: &v1.PodSpec{
Containers: []v1.Container{{Name: "c"}},
EphemeralContainers: []v1.EphemeralContainer{{
EphemeralContainerCommon: v1.EphemeralContainerCommon{Name: "debug", SecurityContext: withProfile(oci)},
}},
},
expected: true,
}}
noOCI := &types.PodInfo{Spec: &v1.PodSpec{Containers: []v1.Container{{Name: "c"}}}}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
podInfo := &types.PodInfo{Spec: tc.spec}
if got := Feature.InferForScheduling(podInfo); got != tc.expected {
t.Errorf("InferForScheduling() = %v, want %v", got, tc.expected)
}
if got := Feature.InferForUpdate(noOCI, podInfo); got != tc.expected {
t.Errorf("InferForUpdate() from a pod without OCI profiles = %v, want %v", got, tc.expected)
}
if Feature.InferForUpdate(podInfo, podInfo) {
t.Error("InferForUpdate() without a change = true, want false")
}
})
}
}
@@ -80,6 +80,8 @@ type RuntimeFeatures struct {
UserNamespacesHostNetwork bool
// MountOptions indicates if the runtime supports additional bind mount options on container mounts.
MountOptions bool
// SeccompProfileOCI indicates if the runtime supports seccomp profiles pulled from OCI registries.
SeccompProfileOCI bool
}
// StaticConfiguration provides a view of a node's static configuration required for feature discovery.
@@ -195,6 +195,7 @@
| SchedulerAsyncPreemption | :ballot_box_with_check:&nbsp;1.33+ | | 1.32 | 1.33– | | | | [code](https://cs.k8s.io/?q=%5CbSchedulerAsyncPreemption%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSchedulerAsyncPreemption%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| SchedulerPopFromBackoffQ | :ballot_box_with_check:&nbsp;1.33+ | | | 1.33– | | | | [code](https://cs.k8s.io/?q=%5CbSchedulerPopFromBackoffQ%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSchedulerPopFromBackoffQ%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| SchedulerPreQueueingHints | :ballot_box_with_check:&nbsp;1.38+ | | 1.37 | 1.38– | | | | [code](https://cs.k8s.io/?q=%5CbSchedulerPreQueueingHints%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSchedulerPreQueueingHints%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| SecurityProfileOCI | | | 1.38– | | | | | [code](https://cs.k8s.io/?q=%5CbSecurityProfileOCI%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSecurityProfileOCI%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| SeparateCacheWatchRPC | :ballot_box_with_check:&nbsp;1.28+ | :closed_lock_with_key:&nbsp;1.36+ | | 1.28–1.32 | | 1.33– | | [code](https://cs.k8s.io/?q=%5CbSeparateCacheWatchRPC%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbSeparateCacheWatchRPC%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| ServiceAccountNodeAudienceRestriction | :ballot_box_with_check:&nbsp;1.33+ | | | 1.32– | | | | [code](https://cs.k8s.io/?q=%5CbServiceAccountNodeAudienceRestriction%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbServiceAccountNodeAudienceRestriction%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| ServiceCIDRStatusFieldWiping | :ballot_box_with_check:&nbsp;1.36+ | | | | 1.0–1.35 | 1.36– | | [code](https://cs.k8s.io/?q=%5CbServiceCIDRStatusFieldWiping%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbServiceCIDRStatusFieldWiping%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
@@ -1744,6 +1744,12 @@
lockToDefault: false
preRelease: Beta
version: "1.38"
- name: SecurityProfileOCI
versionedSpecs:
- default: false
lockToDefault: false
preRelease: Alpha
version: "1.38"
- name: SELinuxChangePolicy
versionedSpecs:
- default: false
@@ -73,6 +73,42 @@ func init() {
"spec.template.spec.containers": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.evictionResponders": {
{ErrorType: "FieldValueTooMany", Origin: "maxItems"},
},
@@ -88,12 +124,48 @@ func init() {
{ErrorType: "FieldValueInvalid", Origin: "minimum"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.restartPolicy": {
{ErrorType: "FieldValueNotSupported"},
},
"spec.template.spec.schedulingGroup": {
{ErrorType: "FieldValueForbidden", Origin: "dependentForbidden"},
},
"spec.template.spec.securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.tolerations[*].key": {
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
},
@@ -73,6 +73,42 @@ func init() {
"spec.template.spec.containers": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.evictionResponders": {
{ErrorType: "FieldValueTooMany", Origin: "maxItems"},
},
@@ -88,12 +124,48 @@ func init() {
{ErrorType: "FieldValueInvalid", Origin: "minimum"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.restartPolicy": {
{ErrorType: "FieldValueNotSupported"},
},
"spec.template.spec.schedulingGroup": {
{ErrorType: "FieldValueForbidden", Origin: "dependentForbidden"},
},
"spec.template.spec.securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.tolerations[*].key": {
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
},
@@ -73,6 +73,42 @@ func init() {
"spec.template.spec.containers": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.evictionResponders": {
{ErrorType: "FieldValueTooMany", Origin: "maxItems"},
},
@@ -88,9 +124,45 @@ func init() {
{ErrorType: "FieldValueInvalid", Origin: "minimum"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.schedulingGroup": {
{ErrorType: "FieldValueForbidden", Origin: "dependentForbidden"},
},
"spec.template.spec.securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.tolerations[*].key": {
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
},
@@ -73,6 +73,42 @@ func init() {
"spec.template.spec.containers": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.evictionResponders": {
{ErrorType: "FieldValueTooMany", Origin: "maxItems"},
},
@@ -88,9 +124,45 @@ func init() {
{ErrorType: "FieldValueInvalid", Origin: "minimum"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.schedulingGroup": {
{ErrorType: "FieldValueForbidden", Origin: "dependentForbidden"},
},
"spec.template.spec.securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.tolerations[*].key": {
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
},
@@ -73,6 +73,42 @@ func init() {
"spec.template.spec.containers": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.evictionResponders": {
{ErrorType: "FieldValueTooMany", Origin: "maxItems"},
},
@@ -88,9 +124,45 @@ func init() {
{ErrorType: "FieldValueInvalid", Origin: "minimum"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.schedulingGroup": {
{ErrorType: "FieldValueForbidden", Origin: "dependentForbidden"},
},
"spec.template.spec.securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.tolerations[*].key": {
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
},
@@ -73,6 +73,42 @@ func init() {
"spec.template.spec.containers": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.evictionResponders": {
{ErrorType: "FieldValueTooMany", Origin: "maxItems"},
},
@@ -88,9 +124,45 @@ func init() {
{ErrorType: "FieldValueInvalid", Origin: "minimum"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.schedulingGroup": {
{ErrorType: "FieldValueForbidden", Origin: "dependentForbidden"},
},
"spec.template.spec.securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.tolerations[*].key": {
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
},
@@ -73,6 +73,42 @@ func init() {
"spec.template.spec.containers": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.containers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.ephemeralContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.evictionResponders": {
{ErrorType: "FieldValueTooMany", Origin: "maxItems"},
},
@@ -88,9 +124,45 @@ func init() {
{ErrorType: "FieldValueInvalid", Origin: "minimum"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.initContainers[*].securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.schedulingGroup": {
{ErrorType: "FieldValueForbidden", Origin: "dependentForbidden"},
},
"spec.template.spec.securityContext.seccompProfile.oci": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.localhostProfile": {
{ErrorType: "FieldValueInvalid", Origin: "union"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.oci.baseProfile.type": {
{ErrorType: "FieldValueNotSupported"},
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.securityContext.seccompProfile.oci.ref": {
{ErrorType: "FieldValueRequired"},
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
},
"spec.template.spec.securityContext.seccompProfile.type": {
{ErrorType: "FieldValueRequired"},
},
"spec.template.spec.tolerations[*].key": {
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
},
Loaded 100 of 112 files, more files were not shown because too many files have changed in this diff. Show more