PodSecurity: admission/api: configuration API

Admission configuration:
- user, namespace, runtimeclass exemptions
- default policy levels and versions
- defaulting
- load and serialization helpers

Co-authored-by: Tim Allclair <timallclair@gmail.com>
This commit is contained in:
Jordan Liggitt 2021-06-22 14:01:52 -04:00
parent 9ce17c8773
commit a3ba921b16
20 changed files with 1277 additions and 0 deletions

View File

@ -0,0 +1,20 @@
/*
Copyright 2021 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.
*/
// +k8s:deepcopy-gen=package
// Package api contains PodSecurity admission configuration file types
package api

View File

@ -0,0 +1,87 @@
/*
Copyright 2021 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 api
import (
"fmt"
"k8s.io/apimachinery/pkg/util/errors"
policyapi "k8s.io/pod-security-admission/api"
)
var requiredErr = fmt.Errorf("required")
// TODO: deduplicate against PolicyToEvaluate
func ToPolicy(defaults PodSecurityDefaults) (policyapi.Policy, error) {
var (
err error
errs []error
p policyapi.Policy
)
if len(defaults.Enforce) == 0 {
errs = appendErr(errs, requiredErr, "Enforce.Level")
} else {
p.Enforce.Level, err = policyapi.ParseLevel(defaults.Enforce)
errs = appendErr(errs, err, "Enforce.Level")
}
if len(defaults.EnforceVersion) == 0 {
errs = appendErr(errs, requiredErr, "Enforce.Version")
} else {
p.Enforce.Version, err = policyapi.ParseVersion(defaults.EnforceVersion)
errs = appendErr(errs, err, "Enforce.Version")
}
if len(defaults.Audit) == 0 {
errs = appendErr(errs, requiredErr, "Audit.Level")
} else {
p.Audit.Level, err = policyapi.ParseLevel(defaults.Audit)
errs = appendErr(errs, err, "Audit.Level")
}
if len(defaults.AuditVersion) == 0 {
errs = appendErr(errs, requiredErr, "Audit.Version")
} else {
p.Audit.Version, err = policyapi.ParseVersion(defaults.AuditVersion)
errs = appendErr(errs, err, "Audit.Version")
}
if len(defaults.Warn) == 0 {
errs = appendErr(errs, requiredErr, "Warn.Level")
} else {
p.Warn.Level, err = policyapi.ParseLevel(defaults.Warn)
errs = appendErr(errs, err, "Warn.Level")
}
if len(defaults.WarnVersion) == 0 {
errs = appendErr(errs, requiredErr, "Warn.Version")
} else {
p.Warn.Version, err = policyapi.ParseVersion(defaults.WarnVersion)
errs = appendErr(errs, err, "Warn.Version")
}
return p, errors.NewAggregate(errs)
}
// appendErr is a helper function to collect field-specific errors.
func appendErr(errs []error, err error, field string) []error {
if err != nil {
return append(errs, fmt.Errorf("%s: %s", field, err.Error()))
}
return errs
}

View File

@ -0,0 +1,78 @@
/*
Copyright 2021 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 load
import (
"fmt"
"io"
"os"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/pod-security-admission/admission/api"
"k8s.io/pod-security-admission/admission/api/scheme"
apiv1alpha1 "k8s.io/pod-security-admission/admission/api/v1alpha1"
)
func LoadFromFile(file string) (*api.PodSecurityConfiguration, error) {
if len(file) == 0 {
// no file specified, use default config
return LoadFromData(nil)
}
// read from file
data, err := os.ReadFile(file)
if err != nil {
return nil, err
}
return LoadFromData(data)
}
func LoadFromReader(reader io.Reader) (*api.PodSecurityConfiguration, error) {
if reader == nil {
// no reader specified, use default config
return LoadFromData(nil)
}
data, err := io.ReadAll(reader)
if err != nil {
return nil, err
}
return LoadFromData(data)
}
func LoadFromData(data []byte) (*api.PodSecurityConfiguration, error) {
if len(data) == 0 {
// no config provided, return default
externalConfig := &apiv1alpha1.PodSecurityConfiguration{}
scheme.Scheme.Default(externalConfig)
internalConfig := &api.PodSecurityConfiguration{}
if err := scheme.Scheme.Convert(externalConfig, internalConfig, nil); err != nil {
return nil, err
}
return internalConfig, nil
}
decodedObj, err := runtime.Decode(scheme.Codecs.UniversalDecoder(), data)
if err != nil {
return nil, err
}
configuration, ok := decodedObj.(*api.PodSecurityConfiguration)
if !ok {
return nil, fmt.Errorf("expected PodSecurityConfiguration, got %T", decodedObj)
}
return configuration, nil
}

View File

@ -0,0 +1,305 @@
/*
Copyright 2021 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 load
import (
"bytes"
"io/ioutil"
"os"
"reflect"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"k8s.io/pod-security-admission/admission/api"
)
var defaultConfig = &api.PodSecurityConfiguration{
Defaults: api.PodSecurityDefaults{
Enforce: "privileged", EnforceVersion: "latest",
Warn: "privileged", WarnVersion: "latest",
Audit: "privileged", AuditVersion: "latest",
},
}
func writeTempFile(t *testing.T, content string) string {
t.Helper()
file, err := ioutil.TempFile("", "podsecurityconfig")
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
os.Remove(file.Name())
})
if err := ioutil.WriteFile(file.Name(), []byte(content), 0600); err != nil {
t.Fatal(err)
}
return file.Name()
}
func TestLoadFromFile(t *testing.T) {
// no file
{
config, err := LoadFromFile("")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(config, defaultConfig) {
t.Fatalf("unexpected config:\n%s", cmp.Diff(defaultConfig, config))
}
}
// empty file
{
config, err := LoadFromFile(writeTempFile(t, ``))
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(config, defaultConfig) {
t.Fatalf("unexpected config:\n%s", cmp.Diff(defaultConfig, config))
}
}
// valid file
{
input := `{
"apiVersion":"pod-security.admission.config.k8s.io/v1alpha1",
"kind":"PodSecurityConfiguration",
"defaults":{"enforce":"baseline"}}`
expect := &api.PodSecurityConfiguration{
Defaults: api.PodSecurityDefaults{
Enforce: "baseline", EnforceVersion: "latest",
Warn: "privileged", WarnVersion: "latest",
Audit: "privileged", AuditVersion: "latest",
},
}
config, err := LoadFromFile(writeTempFile(t, input))
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(config, expect) {
t.Fatalf("unexpected config:\n%s", cmp.Diff(expect, config))
}
}
// missing file
{
_, err := LoadFromFile(`bogus-missing-pod-security-policy-config-file`)
if err == nil {
t.Fatalf("expected err, got none")
}
if !strings.Contains(err.Error(), "bogus-missing-pod-security-policy-config-file") {
t.Fatalf("expected missing file error, got %v", err)
}
}
// invalid content file
{
input := `{
"apiVersion":"pod-security.admission.config.k8s.io/v99",
"kind":"PodSecurityConfiguration",
"defaults":{"enforce":"baseline"}}`
_, err := LoadFromFile(writeTempFile(t, input))
if err == nil {
t.Fatalf("expected err, got none")
}
if !strings.Contains(err.Error(), "pod-security.admission.config.k8s.io/v99") {
t.Fatalf("expected apiVersion error, got %v", err)
}
}
}
func TestLoadFromReader(t *testing.T) {
// no reader
{
config, err := LoadFromReader(nil)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(config, defaultConfig) {
t.Fatalf("unexpected config:\n%s", cmp.Diff(defaultConfig, config))
}
}
// empty reader
{
config, err := LoadFromReader(&bytes.Buffer{})
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(config, defaultConfig) {
t.Fatalf("unexpected config:\n%s", cmp.Diff(defaultConfig, config))
}
}
// valid reader
{
input := `{
"apiVersion":"pod-security.admission.config.k8s.io/v1alpha1",
"kind":"PodSecurityConfiguration",
"defaults":{"enforce":"baseline"}}`
expect := &api.PodSecurityConfiguration{
Defaults: api.PodSecurityDefaults{
Enforce: "baseline", EnforceVersion: "latest",
Warn: "privileged", WarnVersion: "latest",
Audit: "privileged", AuditVersion: "latest",
},
}
config, err := LoadFromReader(bytes.NewBufferString(input))
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(config, expect) {
t.Fatalf("unexpected config:\n%s", cmp.Diff(expect, config))
}
}
// invalid reader
{
input := `{
"apiVersion":"pod-security.admission.config.k8s.io/v99",
"kind":"PodSecurityConfiguration",
"defaults":{"enforce":"baseline"}}`
_, err := LoadFromReader(bytes.NewBufferString(input))
if err == nil {
t.Fatalf("expected err, got none")
}
if !strings.Contains(err.Error(), "pod-security.admission.config.k8s.io/v99") {
t.Fatalf("expected apiVersion error, got %v", err)
}
}
}
func TestLoadFromData(t *testing.T) {
testcases := []struct {
name string
data []byte
expectErr string
expectConfig *api.PodSecurityConfiguration
}{
{
name: "nil",
data: nil,
expectConfig: defaultConfig,
},
{
name: "nil",
data: []byte{},
expectConfig: defaultConfig,
},
{
name: "v1alpha1 - json",
data: []byte(`{
"apiVersion":"pod-security.admission.config.k8s.io/v1alpha1",
"kind":"PodSecurityConfiguration",
"defaults":{"enforce":"baseline"}}`),
expectConfig: &api.PodSecurityConfiguration{
Defaults: api.PodSecurityDefaults{
Enforce: "baseline", EnforceVersion: "latest",
Warn: "privileged", WarnVersion: "latest",
Audit: "privileged", AuditVersion: "latest",
},
},
},
{
name: "v1alpha1 - yaml",
data: []byte(`
apiVersion: pod-security.admission.config.k8s.io/v1alpha1
kind: PodSecurityConfiguration
defaults:
enforce: baseline
enforce-version: v1.7
exemptions:
usernames: ["alice","bob"]
namespaces: ["kube-system"]
runtimeClasses: ["special"]
`),
expectConfig: &api.PodSecurityConfiguration{
Defaults: api.PodSecurityDefaults{
Enforce: "baseline", EnforceVersion: "v1.7",
Warn: "privileged", WarnVersion: "latest",
Audit: "privileged", AuditVersion: "latest",
},
Exemptions: api.PodSecurityExemptions{
Usernames: []string{"alice", "bob"},
Namespaces: []string{"kube-system"},
RuntimeClasses: []string{"special"},
},
},
},
{
name: "missing apiVersion",
data: []byte(`{"kind":"PodSecurityConfiguration"}`),
expectErr: `'apiVersion' is missing`,
},
{
name: "missing kind",
data: []byte(`{"apiVersion":"pod-security.admission.config.k8s.io/v1alpha1"}`),
expectErr: `'Kind' is missing`,
},
{
name: "unknown group",
data: []byte(`{"apiVersion":"apps/v1alpha1","kind":"PodSecurityConfiguration"}`),
expectErr: `apps/v1alpha1`,
},
{
name: "unknown version",
data: []byte(`{"apiVersion":"pod-security.admission.config.k8s.io/v99","kind":"PodSecurityConfiguration"}`),
expectErr: `pod-security.admission.config.k8s.io/v99`,
},
{
name: "unknown kind",
data: []byte(`{"apiVersion":"pod-security.admission.config.k8s.io/v1alpha1","kind":"SomeConfiguration"}`),
expectErr: `SomeConfiguration`,
},
{
name: "unknown field",
data: []byte(`{
"apiVersion":"pod-security.admission.config.k8s.io/v1alpha1",
"kind":"PodSecurityConfiguration",
"deflaults":{"enforce":"baseline"}}`),
expectErr: `unknown field: deflaults`,
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
config, err := LoadFromData(tc.data)
if err != nil {
if len(tc.expectErr) == 0 {
t.Fatalf("unexpected error: %v", err)
}
if !strings.Contains(err.Error(), tc.expectErr) {
t.Fatalf("unexpected error: %v", err)
}
return
}
if len(tc.expectErr) > 0 {
t.Fatalf("expected err, got none")
}
if !reflect.DeepEqual(config, tc.expectConfig) {
t.Fatalf("unexpected config:\n%s", cmp.Diff(tc.expectConfig, config))
}
})
}
}

View File

@ -0,0 +1,50 @@
/*
Copyright 2021 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 api
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "pod-security.admission.config.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
var (
// SchemeBuilder is a pointer used to call AddToScheme
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
// AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes)
}
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&PodSecurityConfiguration{},
)
return nil
}

View File

@ -0,0 +1,17 @@
/*
Copyright 2021 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 api

View File

@ -0,0 +1,44 @@
/*
Copyright 2021 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 scheme
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
podsecurityapi "k8s.io/pod-security-admission/admission/api"
podsecurityv1alpha1 "k8s.io/pod-security-admission/admission/api/v1alpha1"
)
var (
// Scheme is the runtime.Scheme to which all podsecurity api types are registered.
Scheme = runtime.NewScheme()
// Codecs provides access to encoding and decoding for the scheme.
Codecs = serializer.NewCodecFactory(Scheme, serializer.EnableStrict)
)
func init() {
AddToScheme(Scheme)
}
// AddToScheme builds the podsecurity scheme using all known versions of the podsecurity api.
func AddToScheme(scheme *runtime.Scheme) {
utilruntime.Must(podsecurityapi.AddToScheme(scheme))
utilruntime.Must(podsecurityv1alpha1.AddToScheme(scheme))
utilruntime.Must(scheme.SetVersionPriority(podsecurityv1alpha1.SchemeGroupVersion))
}

View File

@ -0,0 +1,17 @@
/*
Copyright 2021 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 scheme

View File

@ -0,0 +1,44 @@
/*
Copyright 2021 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 api
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PodSecurityConfiguration struct {
metav1.TypeMeta
Defaults PodSecurityDefaults
Exemptions PodSecurityExemptions
}
type PodSecurityDefaults struct {
Enforce string
EnforceVersion string
Audit string
AuditVersion string
Warn string
WarnVersion string
}
type PodSecurityExemptions struct {
Usernames []string
Namespaces []string
RuntimeClasses []string
}

View File

@ -0,0 +1,48 @@
/*
Copyright 2021 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 v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/pod-security-admission/api"
)
func addDefaultingFuncs(scheme *runtime.Scheme) error {
return RegisterDefaults(scheme)
}
func SetDefaults_PodSecurityDefaults(obj *PodSecurityDefaults) {
if len(obj.Enforce) == 0 {
obj.Enforce = string(api.LevelPrivileged)
}
if len(obj.Warn) == 0 {
obj.Warn = string(api.LevelPrivileged)
}
if len(obj.Audit) == 0 {
obj.Audit = string(api.LevelPrivileged)
}
if len(obj.EnforceVersion) == 0 {
obj.EnforceVersion = string(api.VersionLatest)
}
if len(obj.WarnVersion) == 0 {
obj.WarnVersion = string(api.VersionLatest)
}
if len(obj.AuditVersion) == 0 {
obj.AuditVersion = string(api.VersionLatest)
}
}

View File

@ -0,0 +1,17 @@
/*
Copyright 2021 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 v1alpha1

View File

@ -0,0 +1,23 @@
/*
Copyright 2021 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.
*/
// +k8s:deepcopy-gen=package
// +k8s:conversion-gen=k8s.io/pod-security-admission/admission/api
// +k8s:defaulter-gen=TypeMeta
// +groupName=pod-security.admission.config.k8s.io
// Package v1alpha1 contains PodSecurity admission configuration file types
package v1alpha1

View File

@ -0,0 +1,50 @@
/*
Copyright 2021 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 v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "pod-security.admission.config.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
var (
// SchemeBuilder is a pointer used to call AddToScheme
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
// AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs)
}
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&PodSecurityConfiguration{},
)
return nil
}

View File

@ -0,0 +1,44 @@
/*
Copyright 2021 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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PodSecurityConfiguration struct {
metav1.TypeMeta
Defaults PodSecurityDefaults `json:"defaults"`
Exemptions PodSecurityExemptions `json:"exemptions"`
}
type PodSecurityDefaults struct {
Enforce string `json:"enforce,omitempty"`
EnforceVersion string `json:"enforce-version,omitempty"`
Audit string `json:"audit,omitempty"`
AuditVersion string `json:"audit-version,omitempty"`
Warn string `json:"warn,omitempty"`
WarnVersion string `json:"warn-version,omitempty"`
}
type PodSecurityExemptions struct {
Usernames []string `json:"usernames,omitempty"`
Namespaces []string `json:"namespaces,omitempty"`
RuntimeClasses []string `json:"runtimeClasses,omitempty"`
}

View File

@ -0,0 +1,153 @@
// +build !ignore_autogenerated
/*
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 conversion-gen. DO NOT EDIT.
package v1alpha1
import (
unsafe "unsafe"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
api "k8s.io/pod-security-admission/admission/api"
)
func init() {
localSchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
if err := s.AddGeneratedConversionFunc((*PodSecurityConfiguration)(nil), (*api.PodSecurityConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_PodSecurityConfiguration_To_api_PodSecurityConfiguration(a.(*PodSecurityConfiguration), b.(*api.PodSecurityConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*api.PodSecurityConfiguration)(nil), (*PodSecurityConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_api_PodSecurityConfiguration_To_v1alpha1_PodSecurityConfiguration(a.(*api.PodSecurityConfiguration), b.(*PodSecurityConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*PodSecurityDefaults)(nil), (*api.PodSecurityDefaults)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_PodSecurityDefaults_To_api_PodSecurityDefaults(a.(*PodSecurityDefaults), b.(*api.PodSecurityDefaults), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*api.PodSecurityDefaults)(nil), (*PodSecurityDefaults)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_api_PodSecurityDefaults_To_v1alpha1_PodSecurityDefaults(a.(*api.PodSecurityDefaults), b.(*PodSecurityDefaults), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*PodSecurityExemptions)(nil), (*api.PodSecurityExemptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_PodSecurityExemptions_To_api_PodSecurityExemptions(a.(*PodSecurityExemptions), b.(*api.PodSecurityExemptions), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*api.PodSecurityExemptions)(nil), (*PodSecurityExemptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_api_PodSecurityExemptions_To_v1alpha1_PodSecurityExemptions(a.(*api.PodSecurityExemptions), b.(*PodSecurityExemptions), scope)
}); err != nil {
return err
}
return nil
}
func autoConvert_v1alpha1_PodSecurityConfiguration_To_api_PodSecurityConfiguration(in *PodSecurityConfiguration, out *api.PodSecurityConfiguration, s conversion.Scope) error {
if err := Convert_v1alpha1_PodSecurityDefaults_To_api_PodSecurityDefaults(&in.Defaults, &out.Defaults, s); err != nil {
return err
}
if err := Convert_v1alpha1_PodSecurityExemptions_To_api_PodSecurityExemptions(&in.Exemptions, &out.Exemptions, s); err != nil {
return err
}
return nil
}
// Convert_v1alpha1_PodSecurityConfiguration_To_api_PodSecurityConfiguration is an autogenerated conversion function.
func Convert_v1alpha1_PodSecurityConfiguration_To_api_PodSecurityConfiguration(in *PodSecurityConfiguration, out *api.PodSecurityConfiguration, s conversion.Scope) error {
return autoConvert_v1alpha1_PodSecurityConfiguration_To_api_PodSecurityConfiguration(in, out, s)
}
func autoConvert_api_PodSecurityConfiguration_To_v1alpha1_PodSecurityConfiguration(in *api.PodSecurityConfiguration, out *PodSecurityConfiguration, s conversion.Scope) error {
if err := Convert_api_PodSecurityDefaults_To_v1alpha1_PodSecurityDefaults(&in.Defaults, &out.Defaults, s); err != nil {
return err
}
if err := Convert_api_PodSecurityExemptions_To_v1alpha1_PodSecurityExemptions(&in.Exemptions, &out.Exemptions, s); err != nil {
return err
}
return nil
}
// Convert_api_PodSecurityConfiguration_To_v1alpha1_PodSecurityConfiguration is an autogenerated conversion function.
func Convert_api_PodSecurityConfiguration_To_v1alpha1_PodSecurityConfiguration(in *api.PodSecurityConfiguration, out *PodSecurityConfiguration, s conversion.Scope) error {
return autoConvert_api_PodSecurityConfiguration_To_v1alpha1_PodSecurityConfiguration(in, out, s)
}
func autoConvert_v1alpha1_PodSecurityDefaults_To_api_PodSecurityDefaults(in *PodSecurityDefaults, out *api.PodSecurityDefaults, s conversion.Scope) error {
out.Enforce = in.Enforce
out.EnforceVersion = in.EnforceVersion
out.Audit = in.Audit
out.AuditVersion = in.AuditVersion
out.Warn = in.Warn
out.WarnVersion = in.WarnVersion
return nil
}
// Convert_v1alpha1_PodSecurityDefaults_To_api_PodSecurityDefaults is an autogenerated conversion function.
func Convert_v1alpha1_PodSecurityDefaults_To_api_PodSecurityDefaults(in *PodSecurityDefaults, out *api.PodSecurityDefaults, s conversion.Scope) error {
return autoConvert_v1alpha1_PodSecurityDefaults_To_api_PodSecurityDefaults(in, out, s)
}
func autoConvert_api_PodSecurityDefaults_To_v1alpha1_PodSecurityDefaults(in *api.PodSecurityDefaults, out *PodSecurityDefaults, s conversion.Scope) error {
out.Enforce = in.Enforce
out.EnforceVersion = in.EnforceVersion
out.Audit = in.Audit
out.AuditVersion = in.AuditVersion
out.Warn = in.Warn
out.WarnVersion = in.WarnVersion
return nil
}
// Convert_api_PodSecurityDefaults_To_v1alpha1_PodSecurityDefaults is an autogenerated conversion function.
func Convert_api_PodSecurityDefaults_To_v1alpha1_PodSecurityDefaults(in *api.PodSecurityDefaults, out *PodSecurityDefaults, s conversion.Scope) error {
return autoConvert_api_PodSecurityDefaults_To_v1alpha1_PodSecurityDefaults(in, out, s)
}
func autoConvert_v1alpha1_PodSecurityExemptions_To_api_PodSecurityExemptions(in *PodSecurityExemptions, out *api.PodSecurityExemptions, s conversion.Scope) error {
out.Usernames = *(*[]string)(unsafe.Pointer(&in.Usernames))
out.Namespaces = *(*[]string)(unsafe.Pointer(&in.Namespaces))
out.RuntimeClasses = *(*[]string)(unsafe.Pointer(&in.RuntimeClasses))
return nil
}
// Convert_v1alpha1_PodSecurityExemptions_To_api_PodSecurityExemptions is an autogenerated conversion function.
func Convert_v1alpha1_PodSecurityExemptions_To_api_PodSecurityExemptions(in *PodSecurityExemptions, out *api.PodSecurityExemptions, s conversion.Scope) error {
return autoConvert_v1alpha1_PodSecurityExemptions_To_api_PodSecurityExemptions(in, out, s)
}
func autoConvert_api_PodSecurityExemptions_To_v1alpha1_PodSecurityExemptions(in *api.PodSecurityExemptions, out *PodSecurityExemptions, s conversion.Scope) error {
out.Usernames = *(*[]string)(unsafe.Pointer(&in.Usernames))
out.Namespaces = *(*[]string)(unsafe.Pointer(&in.Namespaces))
out.RuntimeClasses = *(*[]string)(unsafe.Pointer(&in.RuntimeClasses))
return nil
}
// Convert_api_PodSecurityExemptions_To_v1alpha1_PodSecurityExemptions is an autogenerated conversion function.
func Convert_api_PodSecurityExemptions_To_v1alpha1_PodSecurityExemptions(in *api.PodSecurityExemptions, out *PodSecurityExemptions, s conversion.Scope) error {
return autoConvert_api_PodSecurityExemptions_To_v1alpha1_PodSecurityExemptions(in, out, s)
}

View File

@ -0,0 +1,99 @@
// +build !ignore_autogenerated
/*
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 deepcopy-gen. DO NOT EDIT.
package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodSecurityConfiguration) DeepCopyInto(out *PodSecurityConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
out.Defaults = in.Defaults
in.Exemptions.DeepCopyInto(&out.Exemptions)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityConfiguration.
func (in *PodSecurityConfiguration) DeepCopy() *PodSecurityConfiguration {
if in == nil {
return nil
}
out := new(PodSecurityConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodSecurityConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodSecurityDefaults) DeepCopyInto(out *PodSecurityDefaults) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityDefaults.
func (in *PodSecurityDefaults) DeepCopy() *PodSecurityDefaults {
if in == nil {
return nil
}
out := new(PodSecurityDefaults)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodSecurityExemptions) DeepCopyInto(out *PodSecurityExemptions) {
*out = *in
if in.Usernames != nil {
in, out := &in.Usernames, &out.Usernames
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Namespaces != nil {
in, out := &in.Namespaces, &out.Namespaces
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.RuntimeClasses != nil {
in, out := &in.RuntimeClasses, &out.RuntimeClasses
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityExemptions.
func (in *PodSecurityExemptions) DeepCopy() *PodSecurityExemptions {
if in == nil {
return nil
}
out := new(PodSecurityExemptions)
in.DeepCopyInto(out)
return out
}

View File

@ -0,0 +1,37 @@
// +build !ignore_autogenerated
/*
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 defaulter-gen. DO NOT EDIT.
package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// RegisterDefaults adds defaulters functions to the given scheme.
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
scheme.AddTypeDefaultingFunc(&PodSecurityConfiguration{}, func(obj interface{}) { SetObjectDefaults_PodSecurityConfiguration(obj.(*PodSecurityConfiguration)) })
return nil
}
func SetObjectDefaults_PodSecurityConfiguration(in *PodSecurityConfiguration) {
SetDefaults_PodSecurityDefaults(&in.Defaults)
}

View File

@ -0,0 +1,28 @@
/*
Copyright 2021 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 validation
import (
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/pod-security-admission/admission/api"
)
func ValidatePodSecurityConfiguration(configuration *api.PodSecurityConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
// TODO: validate default levels and versions
return allErrs
}

View File

@ -0,0 +1,17 @@
/*
Copyright 2021 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 validation

View File

@ -0,0 +1,99 @@
// +build !ignore_autogenerated
/*
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 deepcopy-gen. DO NOT EDIT.
package api
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodSecurityConfiguration) DeepCopyInto(out *PodSecurityConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
out.Defaults = in.Defaults
in.Exemptions.DeepCopyInto(&out.Exemptions)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityConfiguration.
func (in *PodSecurityConfiguration) DeepCopy() *PodSecurityConfiguration {
if in == nil {
return nil
}
out := new(PodSecurityConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodSecurityConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodSecurityDefaults) DeepCopyInto(out *PodSecurityDefaults) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityDefaults.
func (in *PodSecurityDefaults) DeepCopy() *PodSecurityDefaults {
if in == nil {
return nil
}
out := new(PodSecurityDefaults)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodSecurityExemptions) DeepCopyInto(out *PodSecurityExemptions) {
*out = *in
if in.Usernames != nil {
in, out := &in.Usernames, &out.Usernames
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Namespaces != nil {
in, out := &in.Namespaces, &out.Namespaces
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.RuntimeClasses != nil {
in, out := &in.RuntimeClasses, &out.RuntimeClasses
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityExemptions.
func (in *PodSecurityExemptions) DeepCopy() *PodSecurityExemptions {
if in == nil {
return nil
}
out := new(PodSecurityExemptions)
in.DeepCopyInto(out)
return out
}