Validate etcd and k8s version for Cilium

Signed-off-by: Maciej Kwiek <maciej@covalent.io>
This commit is contained in:
Maciej Kwiek 2018-01-30 13:23:51 +01:00
parent 52e0a42e46
commit ed67c013f5
4 changed files with 48 additions and 10 deletions

View File

@ -123,6 +123,6 @@ type AmazonVPCNetworkingSpec struct {
// CiliumNetworkingSpec declares that we want Cilium networking
type CiliumNetworkingSpec struct {
Debug bool `json:"Debug,omitempty"`
Debug bool `json:"debug,omitempty"`
Tunnel string `json:"tunnel,omitempty"`
}

View File

@ -16,6 +16,7 @@ go_library(
deps = [
"//pkg/apis/kops:go_default_library",
"//pkg/apis/kops/util:go_default_library",
"//pkg/model/components:go_default_library",
"//upup/pkg/fi:go_default_library",
"//upup/pkg/fi/cloudup/awsup:go_default_library",
"//vendor/github.com/blang/semver:go_default_library",

View File

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/kops/util"
"k8s.io/kops/pkg/model/components"
"k8s.io/kops/upup/pkg/fi"
"github.com/blang/semver"
@ -499,6 +500,11 @@ func ValidateCluster(c *kops.Cluster, strict bool) *field.Error {
}
}
// Cilium specific validation rules
if err := validateCilium(c); err != nil {
return err
}
if errs := newValidateCluster(c); len(errs) != 0 {
return errs[0]
}
@ -533,7 +539,7 @@ func validateEtcdClusterSpec(spec *kops.EtcdClusterSpec, fieldPath *field.Path)
// Not technically a requirement, but doesn't really make sense to allow
return field.Invalid(fieldPath.Child("Members"), len(spec.Members), "Should be an odd number of master-zones for quorum. Use --zones and --master-zones to declare node zones and master zones separately")
}
if err := validateEtcdVersion(spec, fieldPath); err != nil {
if err := validateEtcdVersion(spec, fieldPath, nil); err != nil {
return err
}
for _, m := range spec.Members {
@ -575,23 +581,33 @@ func validateEtcdStorage(specs []*kops.EtcdClusterSpec, fieldPath *field.Path) *
// validateEtcdVersion is responsible for validating the storage version of etcd
// @TODO semvar package doesn't appear to ignore a 'v' in v1.1.1 should could be a problem later down the line
func validateEtcdVersion(spec *kops.EtcdClusterSpec, fieldPath *field.Path) *field.Error {
func validateEtcdVersion(spec *kops.EtcdClusterSpec, fieldPath *field.Path, minimalVersion *semver.Version) *field.Error {
// @check if the storage is specified, thats is valid
if spec.Version == "" {
return nil // as it will be filled in by default for us
if minimalVersion == nil {
v := semver.MustParse("0.0.0")
minimalVersion = &v
}
sem, err := semver.Parse(strings.TrimPrefix(spec.Version, "v"))
version := spec.Version
if spec.Version == "" {
version = components.DefaultEtcdVersion
}
sem, err := semver.Parse(strings.TrimPrefix(version, "v"))
if err != nil {
return field.Invalid(fieldPath.Child("Version"), spec.Version, "the storage version is invalid")
return field.Invalid(fieldPath.Child("Version"), version, "the storage version is invalid")
}
// we only support v3 and v2 for now
if sem.Major == 3 || sem.Major == 2 {
if sem.LT(*minimalVersion) {
return field.Invalid(fieldPath.Child("Version"), version, fmt.Sprintf("minimal version required is %s", minimalVersion.String()))
}
return nil
}
return field.Invalid(fieldPath.Child("Version"), spec.Version, "unsupported storage version, we only support major versions 2 and 3")
return field.Invalid(fieldPath.Child("Version"), version, "unsupported storage version, we only support major versions 2 and 3")
}
// validateEtcdMemberSpec is responsible for validate the cluster member
@ -607,6 +623,25 @@ func validateEtcdMemberSpec(spec *kops.EtcdMemberSpec, fieldPath *field.Path) *f
return nil
}
func validateCilium(c *kops.Cluster) *field.Error {
if c.Spec.Networking.Cilium != nil {
specPath := field.NewPath("Spec")
minimalKubeVersion := semver.MustParse("1.7.0")
kubeVersion := semver.MustParse(c.Spec.KubernetesVersion)
if kubeVersion.LT(minimalKubeVersion) {
return field.Invalid(specPath.Child("KubernetesVersion"), c.Spec.KubernetesVersion, "Cilium needs at least Kubernetes 1.7")
}
minimalVersion := semver.MustParse("3.1.0")
path := specPath.Child("EtcdClusters").Index(0)
if err := validateEtcdVersion(c.Spec.EtcdClusters[0], path, &minimalVersion); err != nil {
return err
}
}
return nil
}
func DeepValidate(c *kops.Cluster, groups []*kops.InstanceGroup, strict bool) error {
if err := ValidateCluster(c, strict); err != nil {
return err

View File

@ -32,6 +32,8 @@ type EtcdOptionsBuilder struct {
var _ loader.OptionsBuilder = &EtcdOptionsBuilder{}
const DefaultEtcdVersion = "2.2.1"
// BuildOptions is responsible for filling in the defaults for the etcd cluster model
func (b *EtcdOptionsBuilder) BuildOptions(o interface{}) error {
spec := o.(*kops.ClusterSpec)
@ -41,7 +43,7 @@ func (b *EtcdOptionsBuilder) BuildOptions(o interface{}) error {
// @TODO if nothing is set, set the defaults. At a late date once we have a way of detecting a 'new' cluster
// we can default all clusters to v3
if x.Version == "" {
x.Version = "2.2.1"
x.Version = DefaultEtcdVersion
}
}