mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-17 07:03:31 +00:00
add validate for advanced audit policy
This change checks group name and non-resrouce URLs format for audit policy.
This commit is contained in:
@@ -21,6 +21,7 @@ go_library(
|
|||||||
srcs = ["validation.go"],
|
srcs = ["validation.go"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/api/validation:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/apis/audit:go_default_library",
|
||||||
],
|
],
|
||||||
|
@@ -17,6 +17,9 @@ limitations under the License.
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/api/validation"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/apiserver/pkg/apis/audit"
|
"k8s.io/apiserver/pkg/apis/audit"
|
||||||
)
|
)
|
||||||
@@ -33,6 +36,8 @@ func ValidatePolicy(policy *audit.Policy) field.ErrorList {
|
|||||||
func validatePolicyRule(rule audit.PolicyRule, fldPath *field.Path) field.ErrorList {
|
func validatePolicyRule(rule audit.PolicyRule, fldPath *field.Path) field.ErrorList {
|
||||||
var allErrs field.ErrorList
|
var allErrs field.ErrorList
|
||||||
allErrs = append(allErrs, validateLevel(rule.Level, fldPath.Child("level"))...)
|
allErrs = append(allErrs, validateLevel(rule.Level, fldPath.Child("level"))...)
|
||||||
|
allErrs = append(allErrs, validateNonResourceURLs(rule.NonResourceURLs, fldPath.Child("nonResourceURLs"))...)
|
||||||
|
allErrs = append(allErrs, validateResources(rule.Resources, fldPath.Child("resources"))...)
|
||||||
|
|
||||||
if len(rule.NonResourceURLs) > 0 {
|
if len(rule.NonResourceURLs) > 0 {
|
||||||
if len(rule.Resources) > 0 || len(rule.Namespaces) > 0 {
|
if len(rule.Resources) > 0 || len(rule.Namespaces) > 0 {
|
||||||
@@ -60,3 +65,40 @@ func validateLevel(level audit.Level, fldPath *field.Path) field.ErrorList {
|
|||||||
return field.ErrorList{field.NotSupported(fldPath, level, validLevels)}
|
return field.ErrorList{field.NotSupported(fldPath, level, validLevels)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateNonResourceURLs(urls []string, fldPath *field.Path) field.ErrorList {
|
||||||
|
var allErrs field.ErrorList
|
||||||
|
for i, url := range urls {
|
||||||
|
if url == "*" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasPrefix(url, "/") {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Index(i), url, "non-resource URL rules must begin with a '/' character"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if url != "" && strings.ContainsRune(url[:len(url)-1], '*') {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Index(i), url, "non-resource URL wildcards '*' must be the final character of the rule"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateResources(groupResources []audit.GroupResources, fldPath *field.Path) field.ErrorList {
|
||||||
|
var allErrs field.ErrorList
|
||||||
|
for _, groupResource := range groupResources {
|
||||||
|
// The empty string represents the core API group.
|
||||||
|
if len(groupResource.Group) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group names must be lower case and be valid DNS subdomains.
|
||||||
|
// reference: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md
|
||||||
|
// an error is returned for group name like rbac.authorization.k8s.io/v1beta1
|
||||||
|
// rbac.authorization.k8s.io is the valid one
|
||||||
|
if msgs := validation.NameIsDNSSubdomain(groupResource.Group, false); len(msgs) != 0 {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("group"), groupResource.Group, strings.Join(msgs, ",")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
@@ -32,7 +32,7 @@ func TestValidatePolicy(t *testing.T) {
|
|||||||
}, { // Specific request
|
}, { // Specific request
|
||||||
Level: audit.LevelRequestResponse,
|
Level: audit.LevelRequestResponse,
|
||||||
Verbs: []string{"get"},
|
Verbs: []string{"get"},
|
||||||
Resources: []audit.GroupResources{{Resources: []string{"secrets"}}},
|
Resources: []audit.GroupResources{{Group: "rbac.authorization.k8s.io", Resources: []string{"roles", "rolebindings"}}},
|
||||||
Namespaces: []string{"kube-system"},
|
Namespaces: []string{"kube-system"},
|
||||||
}, { // Some non-resource URLs
|
}, { // Some non-resource URLs
|
||||||
Level: audit.LevelMetadata,
|
Level: audit.LevelMetadata,
|
||||||
@@ -41,6 +41,7 @@ func TestValidatePolicy(t *testing.T) {
|
|||||||
"/logs*",
|
"/logs*",
|
||||||
"/healthz*",
|
"/healthz*",
|
||||||
"/metrics",
|
"/metrics",
|
||||||
|
"*",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -73,6 +74,33 @@ func TestValidatePolicy(t *testing.T) {
|
|||||||
Level: audit.LevelMetadata,
|
Level: audit.LevelMetadata,
|
||||||
Resources: []audit.GroupResources{{Resources: []string{"secrets"}}},
|
Resources: []audit.GroupResources{{Resources: []string{"secrets"}}},
|
||||||
NonResourceURLs: []string{"/logs*"},
|
NonResourceURLs: []string{"/logs*"},
|
||||||
|
}, { // invalid group name
|
||||||
|
Level: audit.LevelMetadata,
|
||||||
|
Resources: []audit.GroupResources{{Group: "rbac.authorization.k8s.io/v1beta1", Resources: []string{"roles"}}},
|
||||||
|
}, { // invalid non-resource URLs
|
||||||
|
Level: audit.LevelMetadata,
|
||||||
|
NonResourceURLs: []string{
|
||||||
|
"logs",
|
||||||
|
"/healthz*",
|
||||||
|
},
|
||||||
|
}, { // empty non-resource URLs
|
||||||
|
Level: audit.LevelMetadata,
|
||||||
|
NonResourceURLs: []string{
|
||||||
|
"",
|
||||||
|
"/healthz*",
|
||||||
|
},
|
||||||
|
}, { // invalid non-resource URLs with multi "*"
|
||||||
|
Level: audit.LevelMetadata,
|
||||||
|
NonResourceURLs: []string{
|
||||||
|
"/logs/*/*",
|
||||||
|
"/metrics",
|
||||||
|
},
|
||||||
|
}, { // invalid non-resrouce URLs with "*" not in the end
|
||||||
|
Level: audit.LevelMetadata,
|
||||||
|
NonResourceURLs: []string{
|
||||||
|
"/logs/*.log",
|
||||||
|
"/metrics",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
errorCases := []audit.Policy{}
|
errorCases := []audit.Policy{}
|
||||||
|
Reference in New Issue
Block a user