EgressSelectorConfiguration now uses strict validation

This commit is contained in:
Sean Sullivan 2024-10-11 16:17:09 -07:00
parent 762a85e25d
commit 32b2eea50d
3 changed files with 41 additions and 15 deletions

View File

@ -22,13 +22,12 @@ import (
"strings"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/apis/apiserver"
"k8s.io/apiserver/pkg/apis/apiserver/install"
"k8s.io/apiserver/pkg/apis/apiserver/v1beta1"
"k8s.io/utils/path"
"sigs.k8s.io/yaml"
)
var cfgScheme = runtime.NewScheme()
@ -55,19 +54,13 @@ func ReadEgressSelectorConfiguration(configFilePath string) (*apiserver.EgressSe
if err != nil {
return nil, fmt.Errorf("unable to read egress selector configuration from %q [%v]", configFilePath, err)
}
var decodedConfig v1beta1.EgressSelectorConfiguration
err = yaml.Unmarshal(data, &decodedConfig)
config, gvk, err := serializer.NewCodecFactory(cfgScheme, serializer.EnableStrict).UniversalDecoder().Decode(data, nil, nil)
if err != nil {
// we got an error where the decode wasn't related to a missing type
return nil, err
}
if decodedConfig.Kind != "EgressSelectorConfiguration" {
return nil, fmt.Errorf("invalid service configuration object %q", decodedConfig.Kind)
}
internalConfig := &apiserver.EgressSelectorConfiguration{}
if err := cfgScheme.Convert(&decodedConfig, internalConfig, nil); err != nil {
// we got an error where the decode wasn't related to a missing type
return nil, err
internalConfig, ok := config.(*apiserver.EgressSelectorConfiguration)
if !ok {
return nil, fmt.Errorf("unexpected config type: %v", gvk)
}
return internalConfig, nil
}

View File

@ -20,6 +20,7 @@ import (
"fmt"
"os"
"reflect"
"strings"
"testing"
utiltesting "k8s.io/client-go/util/testing"
@ -52,7 +53,39 @@ func TestReadEgressSelectorConfiguration(t *testing.T) {
createFile: false,
contents: ``,
expectedResult: nil,
expectedError: strptr("unable to read egress selector configuration from \"test-egress-selector-config-absent\" [open test-egress-selector-config-absent: no such file or directory]"),
expectedError: strptr("errors.errorString{s:\"unable to read egress selector configuration"),
},
{
name: "unknown field causes error",
createFile: false,
contents: `
apiVersion: apiserver.k8s.io/v1beta1
kind: EgressSelectorConfiguration
egressSelections:
- name: "etcd"
connection:
proxyProtocol: "Direct"
foo:
bar: "baz"
`,
expectedResult: nil,
expectedError: strptr("runtime.strictDecodingError"),
},
{
name: "duplicate field causes error",
createFile: false,
contents: `
apiVersion: apiserver.k8s.io/v1beta1
kind: EgressSelectorConfiguration
egressSelections:
- name: "etcd"
connection:
proxyProtocol: "Direct"
connection:
proxyProtocol: "Indirect"
`,
expectedResult: nil,
expectedError: strptr("runtime.strictDecodingError"),
},
{
name: "v1beta1",
@ -295,7 +328,7 @@ spec:
if err != nil && tc.expectedError == nil {
t.Errorf("unexpected error calling ReadEgressSelectorConfiguration got: %#v", err)
}
if err != nil && tc.expectedError != nil && err.Error() != *tc.expectedError {
if err != nil && tc.expectedError != nil && strings.Contains(err.Error(), *tc.expectedError) {
t.Errorf("calling ReadEgressSelectorConfiguration expected error: %s, got %#v", *tc.expectedError, err)
}
if !reflect.DeepEqual(config, tc.expectedResult) {

View File

@ -208,7 +208,7 @@ func TestAPIServerTracingWithEgressSelector(t *testing.T) {
defer os.Remove(egressSelectorConfigFile.Name())
if err := os.WriteFile(egressSelectorConfigFile.Name(), []byte(`
apiVersion: apiserver.config.k8s.io/v1beta1
apiVersion: apiserver.k8s.io/v1beta1
kind: EgressSelectorConfiguration
egressSelections:
- name: cluster