github.com/oam-dev/cluster-gateway@v1.9.0/pkg/apis/cluster/v1alpha1/validation.go (about) 1 /* 2 Licensed under the Apache License, Version 2.0 (the "License"); 3 you may not use this file except in compliance with the License. 4 You may obtain a copy of the License at 5 6 http://www.apache.org/licenses/LICENSE-2.0 7 8 Unless required by applicable law or agreed to in writing, software 9 distributed under the License is distributed on an "AS IS" BASIS, 10 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 See the License for the specific language governing permissions and 12 limitations under the License. 13 */ 14 15 package v1alpha1 16 17 import ( 18 "encoding/base64" 19 "fmt" 20 "net/url" 21 22 "k8s.io/apimachinery/pkg/util/sets" 23 "k8s.io/apimachinery/pkg/util/validation/field" 24 ) 25 26 func ValidateClusterGateway(c *ClusterGateway) field.ErrorList { 27 var errs field.ErrorList 28 errs = append(errs, ValidateClusterGatewaySpec(&c.Spec, field.NewPath("spec"))...) 29 return errs 30 } 31 32 func ValidateClusterGatewaySpec(c *ClusterGatewaySpec, path *field.Path) field.ErrorList { 33 var errs field.ErrorList 34 if len(c.Provider) == 0 { 35 errs = append(errs, field.Required(path.Child("provider"), "should set provider")) 36 } 37 errs = append(errs, ValidateClusterGatewaySpecAccess(&c.Access, path.Child("access"))...) 38 return errs 39 } 40 41 func ValidateClusterGatewaySpecAccess(c *ClusterAccess, path *field.Path) field.ErrorList { 42 var errs field.ErrorList 43 switch c.Endpoint.Type { 44 case ClusterEndpointTypeConst: 45 if len(c.Endpoint.Const.Address) == 0 { 46 errs = append(errs, field.Required(path.Child("endpoint"), "should provide cluster endpoint")) 47 } 48 u, err := url.Parse(c.Endpoint.Const.Address) 49 if err != nil { 50 errs = append(errs, field.Invalid(path.Child("endpoint"), c.Endpoint, fmt.Sprintf("failed parsing as URL: %v", err))) 51 return errs 52 } 53 if u.Scheme != "https" { 54 errs = append(errs, field.Invalid(path.Child("endpoint"), c.Endpoint, "scheme must be https")) 55 } 56 if len(c.Endpoint.Const.CABundle) == 0 && 57 (c.Endpoint.Const.Insecure == nil || *c.Endpoint.Const.Insecure == false) { 58 errs = append(errs, field.Required(path.Child("caBundle"), "required for non-insecure endpoint")) 59 } 60 } 61 if c.Credential != nil { 62 errs = append(errs, ValidateClusterGatewaySpecAccessCredential(c.Credential, path.Child("credential"))...) 63 } 64 return errs 65 } 66 67 func ValidateClusterGatewaySpecAccessCredential(c *ClusterAccessCredential, path *field.Path) field.ErrorList { 68 var errs field.ErrorList 69 supportedCredTypes := sets.NewString(string(CredentialTypeServiceAccountToken), string(CredentialTypeX509Certificate)) 70 if !supportedCredTypes.Has(string(c.Type)) { 71 errs = append(errs, field.NotSupported(path.Child("type"), c.Type, supportedCredTypes.List())) 72 } 73 switch c.Type { 74 case CredentialTypeServiceAccountToken: 75 if _, err := base64.StdEncoding.DecodeString(c.ServiceAccountToken); err == nil { 76 errs = append(errs, field.Invalid(path.Child("serviceAccountToken"), c.ServiceAccountToken, "should not be base64 encoded")) 77 } 78 if len(c.ServiceAccountToken) == 0 { 79 errs = append(errs, field.Required(path.Child("serviceAccountToken"), "should provide service-account token")) 80 } 81 case CredentialTypeX509Certificate: 82 if c.X509 == nil { 83 errs = append(errs, field.Required(path.Child("x509"), "should provide x509 certificate and private-key")) 84 } else { 85 if len(c.X509.Certificate) == 0 { 86 errs = append(errs, field.Required(path.Child("x509").Child("certificate"), "should provide x509 certificate")) 87 } 88 if len(c.X509.PrivateKey) == 0 { 89 errs = append(errs, field.Required(path.Child("x509").Child("privateKey"), "should provide x509 private key")) 90 } 91 // TODO: test if certificate and private-key matches modulus 92 } 93 } 94 return errs 95 }