Replace godep with dep
This commit is contained in:
parent
1e7489927c
commit
bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions
56
vendor/k8s.io/apiserver/pkg/audit/policy/BUILD
generated
vendored
Normal file
56
vendor/k8s.io/apiserver/pkg/audit/policy/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"checker_test.go",
|
||||
"reader_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/audit/webhook:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"checker.go",
|
||||
"reader.go",
|
||||
],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/audit/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/audit/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/audit/validation:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/audit:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
189
vendor/k8s.io/apiserver/pkg/audit/policy/checker.go
generated
vendored
Normal file
189
vendor/k8s.io/apiserver/pkg/audit/policy/checker.go
generated
vendored
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
Copyright 2017 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 policy
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apiserver/pkg/apis/audit"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultAuditLevel is the default level to audit at, if no policy rules are matched.
|
||||
DefaultAuditLevel = audit.LevelNone
|
||||
)
|
||||
|
||||
// Checker exposes methods for checking the policy rules.
|
||||
type Checker interface {
|
||||
// Check the audit level for a request with the given authorizer attributes.
|
||||
LevelAndStages(authorizer.Attributes) (audit.Level, []audit.Stage)
|
||||
}
|
||||
|
||||
// NewChecker creates a new policy checker.
|
||||
func NewChecker(policy *audit.Policy) Checker {
|
||||
return &policyChecker{*policy}
|
||||
}
|
||||
|
||||
// FakeChecker creates a checker that returns a constant level for all requests (for testing).
|
||||
func FakeChecker(level audit.Level, stage []audit.Stage) Checker {
|
||||
return &fakeChecker{level, stage}
|
||||
}
|
||||
|
||||
type policyChecker struct {
|
||||
audit.Policy
|
||||
}
|
||||
|
||||
func (p *policyChecker) LevelAndStages(attrs authorizer.Attributes) (audit.Level, []audit.Stage) {
|
||||
for _, rule := range p.Rules {
|
||||
if ruleMatches(&rule, attrs) {
|
||||
return rule.Level, rule.OmitStages
|
||||
}
|
||||
}
|
||||
return DefaultAuditLevel, nil
|
||||
}
|
||||
|
||||
// Check whether the rule matches the request attrs.
|
||||
func ruleMatches(r *audit.PolicyRule, attrs authorizer.Attributes) bool {
|
||||
if len(r.Users) > 0 && attrs.GetUser() != nil {
|
||||
if !hasString(r.Users, attrs.GetUser().GetName()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(r.UserGroups) > 0 && attrs.GetUser() != nil {
|
||||
matched := false
|
||||
for _, group := range attrs.GetUser().GetGroups() {
|
||||
if hasString(r.UserGroups, group) {
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !matched {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(r.Verbs) > 0 {
|
||||
if !hasString(r.Verbs, attrs.GetVerb()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if len(r.Namespaces) > 0 || len(r.Resources) > 0 {
|
||||
return ruleMatchesResource(r, attrs)
|
||||
}
|
||||
|
||||
if len(r.NonResourceURLs) > 0 {
|
||||
return ruleMatchesNonResource(r, attrs)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Check whether the rule's non-resource URLs match the request attrs.
|
||||
func ruleMatchesNonResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool {
|
||||
if attrs.IsResourceRequest() {
|
||||
return false
|
||||
}
|
||||
|
||||
path := attrs.GetPath()
|
||||
for _, spec := range r.NonResourceURLs {
|
||||
if pathMatches(path, spec) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Check whether the path matches the path specification.
|
||||
func pathMatches(path, spec string) bool {
|
||||
// Allow wildcard match
|
||||
if spec == "*" {
|
||||
return true
|
||||
}
|
||||
// Allow exact match
|
||||
if spec == path {
|
||||
return true
|
||||
}
|
||||
// Allow a trailing * subpath match
|
||||
if strings.HasSuffix(spec, "*") && strings.HasPrefix(path, strings.TrimRight(spec, "*")) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Check whether the rule's resource fields match the request attrs.
|
||||
func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool {
|
||||
if !attrs.IsResourceRequest() {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(r.Namespaces) > 0 {
|
||||
if !hasString(r.Namespaces, attrs.GetNamespace()) { // Non-namespaced resources use the empty string.
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(r.Resources) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
apiGroup := attrs.GetAPIGroup()
|
||||
resource := attrs.GetResource()
|
||||
// If subresource, the resource in the policy must match "(resource)/(subresource)"
|
||||
//
|
||||
// TODO: consider adding options like "pods/*" to match all subresources.
|
||||
if sr := attrs.GetSubresource(); sr != "" {
|
||||
resource = resource + "/" + sr
|
||||
}
|
||||
|
||||
name := attrs.GetName()
|
||||
|
||||
for _, gr := range r.Resources {
|
||||
if gr.Group == apiGroup {
|
||||
if len(gr.Resources) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, res := range gr.Resources {
|
||||
if res == resource {
|
||||
if len(gr.ResourceNames) == 0 || hasString(gr.ResourceNames, name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Utility function to check whether a string slice contains a string.
|
||||
func hasString(slice []string, value string) bool {
|
||||
for _, s := range slice {
|
||||
if s == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type fakeChecker struct {
|
||||
level audit.Level
|
||||
stage []audit.Stage
|
||||
}
|
||||
|
||||
func (f *fakeChecker) LevelAndStages(_ authorizer.Attributes) (audit.Level, []audit.Stage) {
|
||||
return f.level, f.stage
|
||||
}
|
||||
215
vendor/k8s.io/apiserver/pkg/audit/policy/checker_test.go
generated
vendored
Normal file
215
vendor/k8s.io/apiserver/pkg/audit/policy/checker_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
Copyright 2017 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 policy
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"k8s.io/apiserver/pkg/apis/audit"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
)
|
||||
|
||||
func TestChecker(t *testing.T) {
|
||||
tim := &user.DefaultInfo{
|
||||
Name: "tim@k8s.io",
|
||||
Groups: []string{"humans", "developers"},
|
||||
}
|
||||
attrs := map[string]authorizer.Attributes{
|
||||
"namespaced": &authorizer.AttributesRecord{
|
||||
User: tim,
|
||||
Verb: "get",
|
||||
Namespace: "default",
|
||||
APIGroup: "", // Core
|
||||
APIVersion: "v1",
|
||||
Resource: "pods",
|
||||
Name: "busybox",
|
||||
ResourceRequest: true,
|
||||
Path: "/api/v1/namespaces/default/pods/busybox",
|
||||
},
|
||||
"cluster": &authorizer.AttributesRecord{
|
||||
User: tim,
|
||||
Verb: "get",
|
||||
APIGroup: "rbac.authorization.k8s.io", // Core
|
||||
APIVersion: "v1beta1",
|
||||
Resource: "clusterroles",
|
||||
Name: "edit",
|
||||
ResourceRequest: true,
|
||||
Path: "/apis/rbac.authorization.k8s.io/v1beta1/clusterroles/edit",
|
||||
},
|
||||
"nonResource": &authorizer.AttributesRecord{
|
||||
User: tim,
|
||||
Verb: "get",
|
||||
ResourceRequest: false,
|
||||
Path: "/logs/kubelet.log",
|
||||
},
|
||||
"subresource": &authorizer.AttributesRecord{
|
||||
User: tim,
|
||||
Verb: "get",
|
||||
Namespace: "default",
|
||||
APIGroup: "", // Core
|
||||
APIVersion: "v1",
|
||||
Resource: "pods",
|
||||
Subresource: "log",
|
||||
Name: "busybox",
|
||||
ResourceRequest: true,
|
||||
Path: "/api/v1/namespaces/default/pods/busybox",
|
||||
},
|
||||
}
|
||||
|
||||
rules := map[string]audit.PolicyRule{
|
||||
"default": {
|
||||
Level: audit.LevelMetadata,
|
||||
},
|
||||
"create": {
|
||||
Level: audit.LevelRequest,
|
||||
Verbs: []string{"create"},
|
||||
},
|
||||
"tims": {
|
||||
Level: audit.LevelMetadata,
|
||||
Users: []string{"tim@k8s.io"},
|
||||
},
|
||||
"humans": {
|
||||
Level: audit.LevelMetadata,
|
||||
UserGroups: []string{"humans"},
|
||||
},
|
||||
"serviceAccounts": {
|
||||
Level: audit.LevelRequest,
|
||||
UserGroups: []string{"system:serviceaccounts"},
|
||||
},
|
||||
"getPods": {
|
||||
Level: audit.LevelRequestResponse,
|
||||
Verbs: []string{"get"},
|
||||
Resources: []audit.GroupResources{{Resources: []string{"pods"}}},
|
||||
},
|
||||
"getPodLogs": {
|
||||
Level: audit.LevelRequest,
|
||||
Verbs: []string{"get"},
|
||||
Resources: []audit.GroupResources{{Resources: []string{"pods/log"}}},
|
||||
},
|
||||
"getClusterRoles": {
|
||||
Level: audit.LevelRequestResponse,
|
||||
Verbs: []string{"get"},
|
||||
Resources: []audit.GroupResources{{
|
||||
Group: "rbac.authorization.k8s.io",
|
||||
Resources: []string{"clusterroles"},
|
||||
}},
|
||||
Namespaces: []string{""},
|
||||
},
|
||||
"getLogs": {
|
||||
Level: audit.LevelRequestResponse,
|
||||
Verbs: []string{"get"},
|
||||
NonResourceURLs: []string{
|
||||
"/logs*",
|
||||
},
|
||||
},
|
||||
"getMetrics": {
|
||||
Level: audit.LevelRequest,
|
||||
Verbs: []string{"get"},
|
||||
NonResourceURLs: []string{
|
||||
"/metrics",
|
||||
},
|
||||
},
|
||||
"clusterRoleEdit": {
|
||||
Level: audit.LevelRequest,
|
||||
Resources: []audit.GroupResources{{
|
||||
Group: "rbac.authorization.k8s.io",
|
||||
Resources: []string{"clusterroles"},
|
||||
ResourceNames: []string{"edit"},
|
||||
}},
|
||||
},
|
||||
"omit RequestReceived": {
|
||||
Level: audit.LevelRequest,
|
||||
OmitStages: []audit.Stage{
|
||||
audit.StageRequestReceived,
|
||||
},
|
||||
},
|
||||
"only audit panic": {
|
||||
Level: audit.LevelRequest,
|
||||
OmitStages: []audit.Stage{
|
||||
audit.StageRequestReceived,
|
||||
audit.StageResponseStarted,
|
||||
audit.StageResponseComplete,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
test := func(req string, expLevel audit.Level, expOmitStages []audit.Stage, ruleNames ...string) {
|
||||
policy := audit.Policy{}
|
||||
for _, rule := range ruleNames {
|
||||
require.Contains(t, rules, rule)
|
||||
policy.Rules = append(policy.Rules, rules[rule])
|
||||
}
|
||||
require.Contains(t, attrs, req)
|
||||
actualLevel, actualOmitStages := NewChecker(&policy).LevelAndStages(attrs[req])
|
||||
assert.Equal(t, expLevel, actualLevel, "request:%s rules:%s", req, strings.Join(ruleNames, ","))
|
||||
assert.Equal(t, expOmitStages, actualOmitStages, "request:%s rules:%s", req, strings.Join(ruleNames, ","))
|
||||
}
|
||||
|
||||
test("namespaced", audit.LevelMetadata, nil, "default")
|
||||
test("namespaced", audit.LevelNone, nil, "create")
|
||||
test("namespaced", audit.LevelMetadata, nil, "tims")
|
||||
test("namespaced", audit.LevelMetadata, nil, "humans")
|
||||
test("namespaced", audit.LevelNone, nil, "serviceAccounts")
|
||||
test("namespaced", audit.LevelRequestResponse, nil, "getPods")
|
||||
test("namespaced", audit.LevelNone, nil, "getClusterRoles")
|
||||
test("namespaced", audit.LevelNone, nil, "getLogs")
|
||||
test("namespaced", audit.LevelNone, nil, "getMetrics")
|
||||
test("namespaced", audit.LevelMetadata, nil, "getMetrics", "serviceAccounts", "default")
|
||||
test("namespaced", audit.LevelRequestResponse, nil, "getMetrics", "getPods", "default")
|
||||
test("namespaced", audit.LevelRequestResponse, nil, "getPodLogs", "getPods")
|
||||
test("namespaced", audit.LevelRequest, []audit.Stage{audit.StageRequestReceived}, "omit RequestReceived", "getPods", "default")
|
||||
test("namespaced", audit.LevelRequest, []audit.Stage{audit.StageRequestReceived, audit.StageResponseStarted, audit.StageResponseComplete}, "only audit panic", "getPods", "default")
|
||||
|
||||
test("cluster", audit.LevelMetadata, nil, "default")
|
||||
test("cluster", audit.LevelNone, nil, "create")
|
||||
test("cluster", audit.LevelMetadata, nil, "tims")
|
||||
test("cluster", audit.LevelMetadata, nil, "humans")
|
||||
test("cluster", audit.LevelNone, nil, "serviceAccounts")
|
||||
test("cluster", audit.LevelNone, nil, "getPods")
|
||||
test("cluster", audit.LevelRequestResponse, nil, "getClusterRoles")
|
||||
test("cluster", audit.LevelRequest, nil, "clusterRoleEdit", "getClusterRoles")
|
||||
test("cluster", audit.LevelNone, nil, "getLogs")
|
||||
test("cluster", audit.LevelNone, nil, "getMetrics")
|
||||
test("cluster", audit.LevelMetadata, nil, "getMetrics", "serviceAccounts", "default")
|
||||
test("cluster", audit.LevelRequestResponse, nil, "getMetrics", "getClusterRoles", "default")
|
||||
test("cluster", audit.LevelNone, nil, "getPodLogs", "getPods")
|
||||
test("cluster", audit.LevelRequest, []audit.Stage{audit.StageRequestReceived}, "omit RequestReceived", "getPods", "default")
|
||||
test("cluster", audit.LevelRequest, []audit.Stage{audit.StageRequestReceived, audit.StageResponseStarted, audit.StageResponseComplete}, "only audit panic", "getPods", "default")
|
||||
|
||||
test("nonResource", audit.LevelMetadata, nil, "default")
|
||||
test("nonResource", audit.LevelNone, nil, "create")
|
||||
test("nonResource", audit.LevelMetadata, nil, "tims")
|
||||
test("nonResource", audit.LevelMetadata, nil, "humans")
|
||||
test("nonResource", audit.LevelNone, nil, "serviceAccounts")
|
||||
test("nonResource", audit.LevelNone, nil, "getPods")
|
||||
test("nonResource", audit.LevelNone, nil, "getClusterRoles")
|
||||
test("nonResource", audit.LevelRequestResponse, nil, "getLogs")
|
||||
test("nonResource", audit.LevelNone, nil, "getMetrics")
|
||||
test("nonResource", audit.LevelMetadata, nil, "getMetrics", "serviceAccounts", "default")
|
||||
test("nonResource", audit.LevelRequestResponse, nil, "getLogs", "getClusterRoles", "default")
|
||||
test("nonResource", audit.LevelNone, nil, "getPodLogs", "getPods")
|
||||
test("nonResource", audit.LevelRequest, []audit.Stage{audit.StageRequestReceived}, "omit RequestReceived", "getPods", "default")
|
||||
test("nonResource", audit.LevelRequest, []audit.Stage{audit.StageRequestReceived, audit.StageResponseStarted, audit.StageResponseComplete}, "only audit panic", "getPods", "default")
|
||||
|
||||
test("subresource", audit.LevelRequest, nil, "getPodLogs", "getPods")
|
||||
test("subresource", audit.LevelRequest, nil, "getPods", "getPodLogs")
|
||||
}
|
||||
58
vendor/k8s.io/apiserver/pkg/audit/policy/reader.go
generated
vendored
Normal file
58
vendor/k8s.io/apiserver/pkg/audit/policy/reader.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2017 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 policy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
auditinternal "k8s.io/apiserver/pkg/apis/audit"
|
||||
auditv1alpha1 "k8s.io/apiserver/pkg/apis/audit/v1alpha1"
|
||||
auditv1beta1 "k8s.io/apiserver/pkg/apis/audit/v1beta1"
|
||||
"k8s.io/apiserver/pkg/apis/audit/validation"
|
||||
"k8s.io/apiserver/pkg/audit"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
func LoadPolicyFromFile(filePath string) (*auditinternal.Policy, error) {
|
||||
if filePath == "" {
|
||||
return nil, fmt.Errorf("file path not specified")
|
||||
}
|
||||
policyDef, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read file path %q: %+v", filePath, err)
|
||||
}
|
||||
|
||||
policy := &auditinternal.Policy{}
|
||||
decoder := audit.Codecs.UniversalDecoder(auditv1beta1.SchemeGroupVersion, auditv1alpha1.SchemeGroupVersion)
|
||||
if err := runtime.DecodeInto(decoder, policyDef, policy); err != nil {
|
||||
return nil, fmt.Errorf("failed decoding file %q: %v", filePath, err)
|
||||
}
|
||||
|
||||
if err := validation.ValidatePolicy(policy); err != nil {
|
||||
return nil, err.ToAggregate()
|
||||
}
|
||||
|
||||
policyCnt := len(policy.Rules)
|
||||
if policyCnt == 0 {
|
||||
return nil, fmt.Errorf("loaded illegal policy with 0 rules from file %s", filePath)
|
||||
}
|
||||
glog.V(4).Infof("Loaded %d audit policy rules from file %s", policyCnt, filePath)
|
||||
return policy, nil
|
||||
}
|
||||
152
vendor/k8s.io/apiserver/pkg/audit/policy/reader_test.go
generated
vendored
Normal file
152
vendor/k8s.io/apiserver/pkg/audit/policy/reader_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
Copyright 2017 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 policy
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"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"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const policyDefV1alpha1 = `
|
||||
apiVersion: audit.k8s.io/v1alpha1
|
||||
kind: Policy
|
||||
rules:
|
||||
- level: None
|
||||
nonResourceURLs:
|
||||
- /healthz*
|
||||
- /version
|
||||
- level: RequestResponse
|
||||
users: ["tim"]
|
||||
userGroups: ["testers", "developers"]
|
||||
verbs: ["patch", "delete", "create"]
|
||||
resources:
|
||||
- group: ""
|
||||
- group: "rbac.authorization.k8s.io"
|
||||
resources: ["clusterroles", "clusterrolebindings"]
|
||||
namespaces: ["default", "kube-system"]
|
||||
- level: Metadata
|
||||
`
|
||||
|
||||
const policyDefV1beta1 = `
|
||||
apiVersion: audit.k8s.io/v1beta1
|
||||
kind: Policy
|
||||
rules:
|
||||
- level: None
|
||||
nonResourceURLs:
|
||||
- /healthz*
|
||||
- /version
|
||||
- level: RequestResponse
|
||||
users: ["tim"]
|
||||
userGroups: ["testers", "developers"]
|
||||
verbs: ["patch", "delete", "create"]
|
||||
resources:
|
||||
- group: ""
|
||||
- group: "rbac.authorization.k8s.io"
|
||||
resources: ["clusterroles", "clusterrolebindings"]
|
||||
namespaces: ["default", "kube-system"]
|
||||
- level: Metadata
|
||||
`
|
||||
|
||||
var expectedPolicy = &audit.Policy{
|
||||
Rules: []audit.PolicyRule{{
|
||||
Level: audit.LevelNone,
|
||||
NonResourceURLs: []string{"/healthz*", "/version"},
|
||||
}, {
|
||||
Level: audit.LevelRequestResponse,
|
||||
Users: []string{"tim"},
|
||||
UserGroups: []string{"testers", "developers"},
|
||||
Verbs: []string{"patch", "delete", "create"},
|
||||
Resources: []audit.GroupResources{{}, {
|
||||
Group: "rbac.authorization.k8s.io",
|
||||
Resources: []string{"clusterroles", "clusterrolebindings"},
|
||||
}},
|
||||
Namespaces: []string{"default", "kube-system"},
|
||||
}, {
|
||||
Level: audit.LevelMetadata,
|
||||
}},
|
||||
}
|
||||
|
||||
func TestParserV1alpha1(t *testing.T) {
|
||||
f, err := writePolicy(t, policyDefV1alpha1)
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(f)
|
||||
|
||||
policy, err := LoadPolicyFromFile(f)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, policy.Rules, 3) // Sanity check.
|
||||
if !reflect.DeepEqual(policy, expectedPolicy) {
|
||||
t.Errorf("Unexpected policy! Diff:\n%s", diff.ObjectDiff(policy, expectedPolicy))
|
||||
}
|
||||
}
|
||||
|
||||
func TestParserV1beta1(t *testing.T) {
|
||||
f, err := writePolicy(t, policyDefV1beta1)
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(f)
|
||||
|
||||
policy, err := LoadPolicyFromFile(f)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, policy.Rules, 3) // Sanity check.
|
||||
if !reflect.DeepEqual(policy, expectedPolicy) {
|
||||
t.Errorf("Unexpected policy! Diff:\n%s", diff.ObjectDiff(policy, expectedPolicy))
|
||||
}
|
||||
}
|
||||
|
||||
func TestPolicyCntCheck(t *testing.T) {
|
||||
var testCases = []struct {
|
||||
caseName, policy string
|
||||
}{
|
||||
{
|
||||
"policyWithNoRule",
|
||||
`apiVersion: audit.k8s.io/v1beta1
|
||||
kind: Policy`,
|
||||
},
|
||||
{"emptyPolicyFile", ""},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
f, err := writePolicy(t, tc.policy)
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(f)
|
||||
|
||||
_, err = LoadPolicyFromFile(f)
|
||||
assert.Errorf(t, err, "loaded illegal policy with 0 rules from testCase %s", tc.caseName)
|
||||
}
|
||||
}
|
||||
|
||||
func writePolicy(t *testing.T, policy string) (string, error) {
|
||||
f, err := ioutil.TempFile("", "policy.yaml")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = f.WriteString(policy)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.Close())
|
||||
|
||||
return f.Name(), nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue