From a94f2460934d33b42b46cfe3bd4df75c3dcd495e Mon Sep 17 00:00:00 2001 From: hzxuzhonghu Date: Wed, 8 Nov 2017 16:03:26 +0800 Subject: [PATCH] audit support wildcard matching subresources Kubernetes-commit: 6e83d88be906c174ab3860eec70f2a4aec0ecb48 --- pkg/apis/audit/types.go | 17 +++++++++++++---- pkg/apis/audit/v1alpha1/types.go | 17 +++++++++++++---- pkg/apis/audit/v1beta1/types.go | 17 +++++++++++++---- pkg/audit/policy/checker.go | 21 +++++++++++++++------ 4 files changed, 54 insertions(+), 18 deletions(-) diff --git a/pkg/apis/audit/types.go b/pkg/apis/audit/types.go index 155381b2c..d72505d10 100644 --- a/pkg/apis/audit/types.go +++ b/pkg/apis/audit/types.go @@ -234,10 +234,19 @@ type GroupResources struct { // The empty string represents the core API group. // +optional Group string - // Resources is a list of resources within the API group. Subresources are - // matched using a "/" to indicate the subresource. For example, "pods/log" - // would match request to the log subresource of pods. The top level resource - // does not match subresources, "pods" doesn't match "pods/log". + // Resources is a list of resources this rule applies to. + // + // For example: + // 'pods' matches pods. + // 'pods/log' matches the log subresource of pods. + // '*' matches all resources and their subresources. + // 'pods/*' matches all subresources of pods. + // '*/scale' matches all scale subresources. + // + // If wildcard is present, the validation rule will ensure resources do not + // overlap with each other. + // + // An empty list implies all resources and subresources in this API groups apply. // +optional Resources []string // ResourceNames is a list of resource instance names that the policy matches. diff --git a/pkg/apis/audit/v1alpha1/types.go b/pkg/apis/audit/v1alpha1/types.go index 8bf4a6ecb..7e8af12b8 100644 --- a/pkg/apis/audit/v1alpha1/types.go +++ b/pkg/apis/audit/v1alpha1/types.go @@ -241,10 +241,19 @@ type GroupResources struct { // The empty string represents the core API group. // +optional Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - // Resources is a list of resources within the API group. Subresources are - // matched using a "/" to indicate the subresource. For example, "pods/logs" - // would match request to the logs subresource of pods. The top level resource - // does not match subresources, "pods" doesn't match "pods/logs". + // Resources is a list of resources this rule applies to. + // + // For example: + // 'pods' matches pods. + // 'pods/log' matches the log subresource of pods. + // '*' matches all resources and their subresources. + // 'pods/*' matches all subresources of pods. + // '*/scale' matches all scale subresources. + // + // If wildcard is present, the validation rule will ensure resources do not + // overlap with each other. + // + // An empty list implies all resources and subresources in this API groups apply. // +optional Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"` // ResourceNames is a list of resource instance names that the policy matches. diff --git a/pkg/apis/audit/v1beta1/types.go b/pkg/apis/audit/v1beta1/types.go index 9f855968a..0c3299b4a 100644 --- a/pkg/apis/audit/v1beta1/types.go +++ b/pkg/apis/audit/v1beta1/types.go @@ -237,10 +237,19 @@ type GroupResources struct { // The empty string represents the core API group. // +optional Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - // Resources is a list of resources within the API group. Subresources are - // matched using a "/" to indicate the subresource. For example, "pods/log" - // would match request to the log subresource of pods. The top level resource - // does not match subresources, "pods" doesn't match "pods/log". + // Resources is a list of resources this rule applies to. + // + // For example: + // 'pods' matches pods. + // 'pods/log' matches the log subresource of pods. + // '*' matches all resources and their subresources. + // 'pods/*' matches all subresources of pods. + // '*/scale' matches all scale subresources. + // + // If wildcard is present, the validation rule will ensure resources do not + // overlap with each other. + // + // An empty list implies all resources and subresources in this API groups apply. // +optional Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"` // ResourceNames is a list of resource instance names that the policy matches. diff --git a/pkg/audit/policy/checker.go b/pkg/audit/policy/checker.go index 3259013ad..f3c175299 100644 --- a/pkg/audit/policy/checker.go +++ b/pkg/audit/policy/checker.go @@ -160,11 +160,11 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool apiGroup := attrs.GetAPIGroup() resource := attrs.GetResource() + subresource := attrs.GetSubresource() + combinedResource := resource // 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 + if subresource != "" { + combinedResource = resource + "/" + subresource } name := attrs.GetName() @@ -175,8 +175,17 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool return true } for _, res := range gr.Resources { - if res == resource { - if len(gr.ResourceNames) == 0 || hasString(gr.ResourceNames, name) { + if len(gr.ResourceNames) == 0 || hasString(gr.ResourceNames, name) { + // match "*" + if res == combinedResource || res == "*" { + return true + } + // match "*/subresource" + if len(subresource) > 0 && strings.HasPrefix(res, "*/") && subresource == strings.TrimLeft(res, "*/") { + return true + } + // match "resource/*" + if strings.HasSuffix(res, "/*") && resource == strings.TrimRight(res, "/*") { return true } }