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  }