feat: update validation helpers

Signed-off-by: Jian Zeng <anonymousknight96@gmail.com>
This commit is contained in:
Jian Zeng
2024-09-13 22:18:13 +08:00
parent 389ab72725
commit b9228836e1
4 changed files with 149 additions and 21 deletions

View File

@@ -31,6 +31,8 @@ import (
"unicode/utf8"
"github.com/google/go-cmp/cmp"
netutils "k8s.io/utils/net"
v1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/resource"
@@ -47,6 +49,7 @@ import (
utilsysctl "k8s.io/component-helpers/node/util/sysctl"
schedulinghelper "k8s.io/component-helpers/scheduling/corev1"
kubeletapis "k8s.io/kubelet/pkg/apis"
apiservice "k8s.io/kubernetes/pkg/api/service"
"k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/core/helper"
@@ -57,7 +60,6 @@ import (
"k8s.io/kubernetes/pkg/cluster/ports"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/fieldpath"
netutils "k8s.io/utils/net"
)
const isNegativeErrorMsg string = apimachineryvalidation.IsNegativeErrorMsg
@@ -7522,7 +7524,13 @@ func validateOS(podSpec *core.PodSpec, fldPath *field.Path, opts PodValidationOp
return allErrs
}
func ValidatePodLogOptions(opts *core.PodLogOptions) field.ErrorList {
var validLogStreams = sets.New[string](
core.LogStreamStdout,
core.LogStreamStderr,
core.LogStreamAll,
)
func ValidatePodLogOptions(opts *core.PodLogOptions, allowStreamSelection bool) field.ErrorList {
allErrs := field.ErrorList{}
if opts.TailLines != nil && *opts.TailLines < 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("tailLines"), *opts.TailLines, isNegativeErrorMsg))
@@ -7538,6 +7546,20 @@ func ValidatePodLogOptions(opts *core.PodLogOptions) field.ErrorList {
allErrs = append(allErrs, field.Invalid(field.NewPath("sinceSeconds"), *opts.SinceSeconds, "must be greater than 0"))
}
}
if allowStreamSelection {
if opts.Stream == nil {
allErrs = append(allErrs, field.Required(field.NewPath("stream"), "must be specified"))
} else {
if !validLogStreams.Has(*opts.Stream) {
allErrs = append(allErrs, field.NotSupported(field.NewPath("stream"), *opts.Stream, validLogStreams.UnsortedList()))
}
if *opts.Stream != core.LogStreamAll && opts.TailLines != nil {
allErrs = append(allErrs, field.Forbidden(field.NewPath(""), "`tailLines` and specific `stream` are mutually exclusive for now"))
}
}
} else if opts.Stream != nil {
allErrs = append(allErrs, field.Forbidden(field.NewPath("stream"), "may not be specified"))
}
return allErrs
}

View File

@@ -21022,29 +21022,79 @@ func TestValidPodLogOptions(t *testing.T) {
negative := int64(-1)
zero := int64(0)
positive := int64(1)
stdoutStream := core.LogStreamStdout
stderrStream := core.LogStreamStderr
allStream := core.LogStreamAll
invalidStream := "invalid"
tests := []struct {
opt core.PodLogOptions
errs int
opt core.PodLogOptions
errs int
allowStreamSelection bool
}{
{core.PodLogOptions{}, 0},
{core.PodLogOptions{Previous: true}, 0},
{core.PodLogOptions{Follow: true}, 0},
{core.PodLogOptions{TailLines: &zero}, 0},
{core.PodLogOptions{TailLines: &negative}, 1},
{core.PodLogOptions{TailLines: &positive}, 0},
{core.PodLogOptions{LimitBytes: &zero}, 1},
{core.PodLogOptions{LimitBytes: &negative}, 1},
{core.PodLogOptions{LimitBytes: &positive}, 0},
{core.PodLogOptions{SinceSeconds: &negative}, 1},
{core.PodLogOptions{SinceSeconds: &positive}, 0},
{core.PodLogOptions{SinceSeconds: &zero}, 1},
{core.PodLogOptions{SinceTime: &now}, 0},
{core.PodLogOptions{}, 0, false},
{core.PodLogOptions{Previous: true}, 0, false},
{core.PodLogOptions{Follow: true}, 0, false},
{core.PodLogOptions{TailLines: &zero}, 0, false},
{core.PodLogOptions{TailLines: &negative}, 1, false},
{core.PodLogOptions{TailLines: &positive}, 0, false},
{core.PodLogOptions{LimitBytes: &zero}, 1, false},
{core.PodLogOptions{LimitBytes: &negative}, 1, false},
{core.PodLogOptions{LimitBytes: &positive}, 0, false},
{core.PodLogOptions{SinceSeconds: &negative}, 1, false},
{core.PodLogOptions{SinceSeconds: &positive}, 0, false},
{core.PodLogOptions{SinceSeconds: &zero}, 1, false},
{core.PodLogOptions{SinceTime: &now}, 0, false},
{
opt: core.PodLogOptions{
Stream: &stdoutStream,
},
allowStreamSelection: false,
errs: 1,
},
{
opt: core.PodLogOptions{
Stream: &stdoutStream,
},
allowStreamSelection: true,
},
{
opt: core.PodLogOptions{
Stream: &invalidStream,
},
allowStreamSelection: true,
errs: 1,
},
{
opt: core.PodLogOptions{
Stream: &stderrStream,
TailLines: &positive,
},
allowStreamSelection: true,
errs: 1,
},
{
opt: core.PodLogOptions{
Stream: &allStream,
TailLines: &positive,
},
allowStreamSelection: true,
},
{
opt: core.PodLogOptions{
Stream: &stdoutStream,
LimitBytes: &positive,
SinceTime: &now,
},
allowStreamSelection: true,
},
}
for i, test := range tests {
errs := ValidatePodLogOptions(&test.opt)
if test.errs != len(errs) {
t.Errorf("%d: Unexpected errors: %v", i, errs)
}
t.Run(fmt.Sprintf("case-%d", i), func(t *testing.T) {
errs := ValidatePodLogOptions(&test.opt, test.allowStreamSelection)
if test.errs != len(errs) {
t.Errorf("%d: Unexpected errors: %v", i, errs)
}
})
}
}