Created
August 31, 2020 07:45
-
-
Save sttts/3d858df53a5787d6b5304461d552e8dd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/openshift-kube-apiserver/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go b/openshift-kube-apiserver/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go | |
index 2495d4eb67b..07e98bf41d5 100644 | |
--- a/openshift-kube-apiserver/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go | |
+++ b/openshift-kube-apiserver/admission/customresourcevalidation/customresourcevalidationregistration/cr_validation_registration.go | |
@@ -2,6 +2,7 @@ package customresourcevalidationregistration | |
import ( | |
"k8s.io/apiserver/pkg/admission" | |
+ "k8s.io/kubernetes/openshift-kube-apiserver/admission/customresourcevalidation/proxy" | |
"k8s.io/kubernetes/openshift-kube-apiserver/admission/customresourcevalidation/apiserver" | |
"k8s.io/kubernetes/openshift-kube-apiserver/admission/customresourcevalidation/authentication" | |
@@ -27,6 +28,7 @@ var AllCustomResourceValidators = []string{ | |
image.PluginName, | |
oauth.PluginName, | |
project.PluginName, | |
+ proxy.PluginName, | |
config.PluginName, | |
scheduler.PluginName, | |
clusterresourcequota.PluginName, | |
@@ -46,6 +48,7 @@ func RegisterCustomResourceValidation(plugins *admission.Plugins) { | |
image.Register(plugins) | |
oauth.Register(plugins) | |
project.Register(plugins) | |
+ proxy.Register(plugins) | |
config.Register(plugins) | |
scheduler.Register(plugins) | |
diff --git a/openshift-kube-apiserver/admission/customresourcevalidation/proxy/validate_proxy.go b/openshift-kube-apiserver/admission/customresourcevalidation/proxy/validate_proxy.go | |
new file mode 100644 | |
index 00000000000..cad302d88de | |
--- /dev/null | |
+++ b/openshift-kube-apiserver/admission/customresourcevalidation/proxy/validate_proxy.go | |
@@ -0,0 +1,185 @@ | |
+package proxy | |
+ | |
+import ( | |
+ "fmt" | |
+ "io" | |
+ "net" | |
+ "net/url" | |
+ "strings" | |
+ | |
+ "k8s.io/apimachinery/pkg/api/validation" | |
+ "k8s.io/apimachinery/pkg/runtime" | |
+ "k8s.io/apimachinery/pkg/runtime/schema" | |
+ "k8s.io/apimachinery/pkg/util/validation/field" | |
+ "k8s.io/apiserver/pkg/admission" | |
+ | |
+ configv1 "github.com/openshift/api/config/v1" | |
+ "k8s.io/kubernetes/openshift-kube-apiserver/admission/customresourcevalidation" | |
+) | |
+ | |
+const PluginName = "config.openshift.io/ValidateProxy" | |
+ | |
+// Register registers a plugin | |
+func Register(plugins *admission.Plugins) { | |
+ plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) { | |
+ return customresourcevalidation.NewValidator( | |
+ map[schema.GroupResource]bool{ | |
+ configv1.Resource("proxies"): true, | |
+ }, | |
+ map[schema.GroupVersionKind]customresourcevalidation.ObjectValidator{ | |
+ configv1.GroupVersion.WithKind("Proxy"): proxyAdmission{}, | |
+ }) | |
+ }) | |
+} | |
+ | |
+type proxyAdmission struct { | |
+} | |
+ | |
+func toProxyV1(uncastObj runtime.Object) (*configv1.Proxy, field.ErrorList) { | |
+ if uncastObj == nil { | |
+ return nil, nil | |
+ } | |
+ | |
+ allErrs := field.ErrorList{} | |
+ | |
+ obj, ok := uncastObj.(*configv1.Proxy) | |
+ if !ok { | |
+ return nil, append(allErrs, | |
+ field.NotSupported(field.NewPath("kind"), fmt.Sprintf("%T", uncastObj), []string{"Proxy"}), | |
+ field.NotSupported(field.NewPath("apiVersion"), fmt.Sprintf("%T", uncastObj), []string{"config.openshift.io/v1"})) | |
+ } | |
+ | |
+ return obj, nil | |
+} | |
+ | |
+func (proxyAdmission) ValidateCreate(uncastObj runtime.Object) field.ErrorList { | |
+ obj, errs := toProxyV1(uncastObj) | |
+ if len(errs) > 0 { | |
+ return errs | |
+ } | |
+ | |
+ errs = append(errs, validation.ValidateObjectMeta(&obj.ObjectMeta, false, customresourcevalidation.RequireNameCluster, field.NewPath("metadata"))...) | |
+ errs =append(errs, ValidateSpec(&obj.Spec, nil, field.NewPath("spec"))...) | |
+ | |
+ return errs | |
+} | |
+ | |
+func (proxyAdmission) ValidateUpdate(uncastObj runtime.Object, uncastOldObj runtime.Object) field.ErrorList { | |
+ obj, errs := toProxyV1(uncastObj) | |
+ if len(errs) > 0 { | |
+ return errs | |
+ } | |
+ oldObj, errs := toProxyV1(uncastOldObj) | |
+ if len(errs) > 0 { | |
+ return errs | |
+ } | |
+ | |
+ errs = append(errs, validation.ValidateObjectMetaUpdate(&obj.ObjectMeta, &oldObj.ObjectMeta, field.NewPath("metadata"))...) | |
+ | |
+ return errs | |
+} | |
+ | |
+func (proxyAdmission) ValidateStatusUpdate(uncastObj runtime.Object, uncastOldObj runtime.Object) field.ErrorList { | |
+ obj, errs := toProxyV1(uncastObj) | |
+ if len(errs) > 0 { | |
+ return errs | |
+ } | |
+ oldObj, errs := toProxyV1(uncastOldObj) | |
+ if len(errs) > 0 { | |
+ return errs | |
+ } | |
+ | |
+ errs = append(errs, validation.ValidateObjectMetaUpdate(&obj.ObjectMeta, &oldObj.ObjectMeta, field.NewPath("metadata"))...) | |
+ | |
+ return errs | |
+} | |
+ | |
+func ValidateSpec(obj, old *configv1.ProxySpec, fldPath *field.Path) field.ErrorList { | |
+ var errs field.ErrorList | |
+ | |
+ if len(obj.HTTPProxy) > 0 && (old == nil || obj.HTTPProxy != old.HTTPProxy) { | |
+ err := validateURL(obj.HTTPProxy, "http://", fldPath.Child("httpProxy")) | |
+ if err != nil { | |
+ errs = append(errs, err) | |
+ } | |
+ } | |
+ | |
+ if len(obj.HTTPSProxy) > 0 && (old == nil || obj.HTTPSProxy != old.HTTPSProxy) { | |
+ err := validateURL(obj.HTTPSProxy, "https://", fldPath.Child("httpsProxy")) | |
+ if err != nil { | |
+ errs = append(errs, err) | |
+ } | |
+ } | |
+ | |
+ if len(obj.NoProxy) > 0 && (old ==nil || obj.NoProxy != old.NoProxy) { | |
+ for i, np := range(strings.Split(obj.NoProxy, ",")) { | |
+ _, _, err := net.ParseCIDR(np) | |
+ if err ==nil { | |
+ continue | |
+ } | |
+ | |
+ u, err := url.Parse(np) | |
+ if err != nil || u.Hostname() != np { | |
+ errs = append(errs, field.Invalid(fldPath.Child("noProxy").Index(i), np, "must be a CIDR or a hostname")) | |
+ } | |
+ } | |
+ } | |
+ | |
+ if len(obj.ReadinessEndpoints) > 0 && (old ==nil || obj.ReadinessEndpoints != old.ReadinessEndpoints) { | |
+ for i, np := range(strings.Split(obj.NoProxy, ",")) { | |
+ _, _, err := net.ParseCIDR(np) | |
+ if err ==nil { | |
+ continue | |
+ } | |
+ | |
+ u, err := url.Parse(np) | |
+ if err != nil || u.Hostname() != np { | |
+ errs = append(errs, field.Invalid(fldPath.Child("noProxy").Index(i), np, "must be a CIDR or a hostname")) | |
+ } | |
+ } | |
+ } | |
+ | |
+ // readinessEndpoints is a list of endpoints used to verify readiness of the proxy. | |
+ // +optional | |
+ ReadinessEndpoints []string `json:"readinessEndpoints,omitempty"` | |
+ | |
+ // trustedCA is a reference to a ConfigMap containing a CA certificate bundle. | |
+ // The trustedCA field should only be consumed by a proxy validator. The | |
+ // validator is responsible for reading the certificate bundle from the required | |
+ // key "ca-bundle.crt", merging it with the system default trust bundle, | |
+ // and writing the merged trust bundle to a ConfigMap named "trusted-ca-bundle" | |
+ // in the "openshift-config-managed" namespace. Clients that expect to make | |
+ // proxy connections must use the trusted-ca-bundle for all HTTPS requests to | |
+ // the proxy, and may use the trusted-ca-bundle for non-proxy HTTPS requests as | |
+ // well. | |
+ // | |
+ // The namespace for the ConfigMap referenced by trustedCA is | |
+ // "openshift-config". Here is an example ConfigMap (in yaml): | |
+ // | |
+ // apiVersion: v1 | |
+ // kind: ConfigMap | |
+ // metadata: | |
+ // name: user-ca-bundle | |
+ // namespace: openshift-config | |
+ // data: | |
+ // ca-bundle.crt: | | |
+ // -----BEGIN CERTIFICATE----- | |
+ // Custom CA certificate bundle. | |
+ // -----END CERTIFICATE----- | |
+ // | |
+ // +optional | |
+ TrustedCA ConfigMapNameReference `json:"trustedCA,omitempty"` | |
+} | |
+ | |
+func validateURL(u string, schema string, fldPath *field.Path) *field.Error { | |
+ _, err := url.Parse(u) | |
+ if err != nil { | |
+ return field.Invalid(fldPath, u, err.Error()) | |
+ } | |
+ | |
+ if !strings.HasPrefix(u, schema) { | |
+ return field.Invalid(fldPath, u, fmt.Sprintf("must start with %s", schema)) | |
+ } | |
+ | |
+ return nil | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment