strict decode policy first

This commit is contained in:
kidddddddddddddddddddddd 2022-11-02 16:17:52 +08:00
parent e17a4f64d7
commit 5dcfaae7b9
2 changed files with 39 additions and 4 deletions

View File

@ -20,12 +20,13 @@ import (
"fmt"
"io/ioutil"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
auditinternal "k8s.io/apiserver/pkg/apis/audit"
auditv1 "k8s.io/apiserver/pkg/apis/audit/v1"
"k8s.io/apiserver/pkg/apis/audit/validation"
"k8s.io/apiserver/pkg/audit"
"k8s.io/klog/v2"
)
@ -61,11 +62,23 @@ func LoadPolicyFromFile(filePath string) (*auditinternal.Policy, error) {
func LoadPolicyFromBytes(policyDef []byte) (*auditinternal.Policy, error) {
policy := &auditinternal.Policy{}
decoder := audit.Codecs.UniversalDecoder(apiGroupVersions...)
strictDecoder := serializer.NewCodecFactory(audit.Scheme, serializer.EnableStrict).UniversalDecoder()
_, gvk, err := decoder.Decode(policyDef, nil, policy)
// Try strict decoding first.
_, gvk, err := strictDecoder.Decode(policyDef, nil, policy)
if err != nil {
return nil, fmt.Errorf("failed decoding: %v", err)
if !runtime.IsStrictDecodingError(err) {
return nil, fmt.Errorf("failed decoding: %w", err)
}
var (
lenientDecoder = audit.Codecs.UniversalDecoder(apiGroupVersions...)
lenientErr error
)
_, gvk, lenientErr = lenientDecoder.Decode(policyDef, nil, policy)
if lenientErr != nil {
return nil, fmt.Errorf("failed lenient decoding: %w", lenientErr)
}
klog.Warningf("Audit policy contains errors, falling back to lenient decoding: %v", err)
}
// Ensure the policy file contained an apiVersion and kind.

View File

@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apiserver/pkg/apis/audit"
// import to call webhook's init() function to register audit.Policy to schema
_ "k8s.io/apiserver/plugin/pkg/audit/webhook"
@ -70,6 +71,18 @@ rules:
- level: Metadata
`
const policyWithUnknownField = `
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: None
resources:
- group: coordination.k8s.io
resources:
- "leases"
verbs: ["watch", "get", "list"] # invalid indentation on verbs
`
var expectedPolicy = &audit.Policy{
Rules: []audit.PolicyRule{{
Level: audit.LevelNone,
@ -113,6 +126,15 @@ func TestParsePolicyWithNoVersionOrKind(t *testing.T) {
assert.Contains(t, err.Error(), "unknown group version field")
}
func TestParsePolicyWithUnknownField(t *testing.T) {
f, err := writePolicy(t, policyWithUnknownField)
require.NoError(t, err)
defer os.Remove(f)
_, err = LoadPolicyFromFile(f)
require.NoError(t, err)
}
func TestPolicyCntCheck(t *testing.T) {
var testCases = []struct {
caseName, policy string