Replace godep with dep
This commit is contained in:
parent
1e7489927c
commit
bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions
51
vendor/k8s.io/kubernetes/cmd/kubeadm/app/preflight/BUILD
generated
vendored
Normal file
51
vendor/k8s.io/kubernetes/cmd/kubeadm/app/preflight/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["checks.go"],
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//cmd/kube-controller-manager/app/options:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
||||
"//pkg/util/initsystem:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//plugin/cmd/kube-scheduler/app/options:go_default_library",
|
||||
"//test/e2e_node/system:go_default_library",
|
||||
"//vendor/github.com/PuerkitoBio/purell:go_default_library",
|
||||
"//vendor/github.com/blang/semver:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["checks_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//vendor/github.com/renstrom/dedent:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
733
vendor/k8s.io/kubernetes/cmd/kubeadm/app/preflight/checks.go
generated
vendored
Normal file
733
vendor/k8s.io/kubernetes/cmd/kubeadm/app/preflight/checks.go
generated
vendored
Normal file
|
|
@ -0,0 +1,733 @@
|
|||
/*
|
||||
Copyright 2016 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.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
|
||||
"github.com/PuerkitoBio/purell"
|
||||
"github.com/blang/semver"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"net/url"
|
||||
|
||||
apiservoptions "k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
cmoptions "k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||
"k8s.io/kubernetes/pkg/util/initsystem"
|
||||
versionutil "k8s.io/kubernetes/pkg/util/version"
|
||||
kubeadmversion "k8s.io/kubernetes/pkg/version"
|
||||
schoptions "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options"
|
||||
"k8s.io/kubernetes/test/e2e_node/system"
|
||||
)
|
||||
|
||||
const (
|
||||
bridgenf = "/proc/sys/net/bridge/bridge-nf-call-iptables"
|
||||
externalEtcdRequestTimeout = time.Duration(10 * time.Second)
|
||||
externalEtcdRequestRetries = 3
|
||||
externalEtcdRequestInterval = time.Duration(5 * time.Second)
|
||||
)
|
||||
|
||||
var (
|
||||
minExternalEtcdVersion = semver.MustParse(kubeadmconstants.MinExternalEtcdVersion)
|
||||
)
|
||||
|
||||
type Error struct {
|
||||
Msg string
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return fmt.Sprintf("[preflight] Some fatal errors occurred:\n%s%s", e.Msg, "[preflight] If you know what you are doing, you can skip pre-flight checks with `--skip-preflight-checks`")
|
||||
}
|
||||
|
||||
// Checker validates the state of the system to ensure kubeadm will be
|
||||
// successful as often as possilble.
|
||||
type Checker interface {
|
||||
Check() (warnings, errors []error)
|
||||
}
|
||||
|
||||
// ServiceCheck verifies that the given service is enabled and active. If we do not
|
||||
// detect a supported init system however, all checks are skipped and a warning is
|
||||
// returned.
|
||||
type ServiceCheck struct {
|
||||
Service string
|
||||
CheckIfActive bool
|
||||
}
|
||||
|
||||
func (sc ServiceCheck) Check() (warnings, errors []error) {
|
||||
initSystem, err := initsystem.GetInitSystem()
|
||||
if err != nil {
|
||||
return []error{err}, nil
|
||||
}
|
||||
|
||||
warnings = []error{}
|
||||
|
||||
if !initSystem.ServiceExists(sc.Service) {
|
||||
warnings = append(warnings, fmt.Errorf("%s service does not exist", sc.Service))
|
||||
return warnings, nil
|
||||
}
|
||||
|
||||
if !initSystem.ServiceIsEnabled(sc.Service) {
|
||||
warnings = append(warnings,
|
||||
fmt.Errorf("%s service is not enabled, please run 'systemctl enable %s.service'",
|
||||
sc.Service, sc.Service))
|
||||
}
|
||||
|
||||
if sc.CheckIfActive && !initSystem.ServiceIsActive(sc.Service) {
|
||||
errors = append(errors,
|
||||
fmt.Errorf("%s service is not active, please run 'systemctl start %s.service'",
|
||||
sc.Service, sc.Service))
|
||||
}
|
||||
|
||||
return warnings, errors
|
||||
}
|
||||
|
||||
// FirewalldCheck checks if firewalld is enabled or active, and if so outputs a warning.
|
||||
type FirewalldCheck struct {
|
||||
ports []int
|
||||
}
|
||||
|
||||
func (fc FirewalldCheck) Check() (warnings, errors []error) {
|
||||
initSystem, err := initsystem.GetInitSystem()
|
||||
if err != nil {
|
||||
return []error{err}, nil
|
||||
}
|
||||
|
||||
warnings = []error{}
|
||||
|
||||
if !initSystem.ServiceExists("firewalld") {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if initSystem.ServiceIsActive("firewalld") {
|
||||
warnings = append(warnings,
|
||||
fmt.Errorf("firewalld is active, please ensure ports %v are open or your cluster may not function correctly",
|
||||
fc.ports))
|
||||
}
|
||||
|
||||
return warnings, errors
|
||||
}
|
||||
|
||||
// PortOpenCheck ensures the given port is available for use.
|
||||
type PortOpenCheck struct {
|
||||
port int
|
||||
}
|
||||
|
||||
func (poc PortOpenCheck) Check() (warnings, errors []error) {
|
||||
errors = []error{}
|
||||
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", poc.port))
|
||||
if err != nil {
|
||||
errors = append(errors, fmt.Errorf("Port %d is in use", poc.port))
|
||||
}
|
||||
if ln != nil {
|
||||
ln.Close()
|
||||
}
|
||||
|
||||
return nil, errors
|
||||
}
|
||||
|
||||
// IsRootCheck verifies user is root
|
||||
type IsRootCheck struct{}
|
||||
|
||||
func (irc IsRootCheck) Check() (warnings, errors []error) {
|
||||
errors = []error{}
|
||||
if os.Getuid() != 0 {
|
||||
errors = append(errors, fmt.Errorf("user is not running as root"))
|
||||
}
|
||||
|
||||
return nil, errors
|
||||
}
|
||||
|
||||
// DirAvailableCheck checks if the given directory either does not exist, or is empty.
|
||||
type DirAvailableCheck struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func (dac DirAvailableCheck) Check() (warnings, errors []error) {
|
||||
errors = []error{}
|
||||
// If it doesn't exist we are good:
|
||||
if _, err := os.Stat(dac.Path); os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
f, err := os.Open(dac.Path)
|
||||
if err != nil {
|
||||
errors = append(errors, fmt.Errorf("unable to check if %s is empty: %s", dac.Path, err))
|
||||
return nil, errors
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.Readdirnames(1)
|
||||
if err != io.EOF {
|
||||
errors = append(errors, fmt.Errorf("%s is not empty", dac.Path))
|
||||
}
|
||||
|
||||
return nil, errors
|
||||
}
|
||||
|
||||
// FileAvailableCheck checks that the given file does not already exist.
|
||||
type FileAvailableCheck struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func (fac FileAvailableCheck) Check() (warnings, errors []error) {
|
||||
errors = []error{}
|
||||
if _, err := os.Stat(fac.Path); err == nil {
|
||||
errors = append(errors, fmt.Errorf("%s already exists", fac.Path))
|
||||
}
|
||||
return nil, errors
|
||||
}
|
||||
|
||||
// FileExistingCheck checks that the given file does not already exist.
|
||||
type FileExistingCheck struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func (fac FileExistingCheck) Check() (warnings, errors []error) {
|
||||
errors = []error{}
|
||||
if _, err := os.Stat(fac.Path); err != nil {
|
||||
errors = append(errors, fmt.Errorf("%s doesn't exist", fac.Path))
|
||||
}
|
||||
return nil, errors
|
||||
}
|
||||
|
||||
// FileContentCheck checks that the given file contains the string Content.
|
||||
type FileContentCheck struct {
|
||||
Path string
|
||||
Content []byte
|
||||
}
|
||||
|
||||
func (fcc FileContentCheck) Check() (warnings, errors []error) {
|
||||
f, err := os.Open(fcc.Path)
|
||||
if err != nil {
|
||||
return nil, []error{fmt.Errorf("%s does not exist", fcc.Path)}
|
||||
}
|
||||
|
||||
lr := io.LimitReader(f, int64(len(fcc.Content)))
|
||||
defer f.Close()
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
_, err = io.Copy(buf, lr)
|
||||
if err != nil {
|
||||
return nil, []error{fmt.Errorf("%s could not be read", fcc.Path)}
|
||||
}
|
||||
|
||||
if !bytes.Equal(buf.Bytes(), fcc.Content) {
|
||||
return nil, []error{fmt.Errorf("%s contents are not set to %s", fcc.Path, fcc.Content)}
|
||||
}
|
||||
return nil, []error{}
|
||||
|
||||
}
|
||||
|
||||
// InPathCheck checks if the given executable is present in the path
|
||||
type InPathCheck struct {
|
||||
executable string
|
||||
mandatory bool
|
||||
}
|
||||
|
||||
func (ipc InPathCheck) Check() (warnings, errors []error) {
|
||||
_, err := exec.LookPath(ipc.executable)
|
||||
if err != nil {
|
||||
if ipc.mandatory {
|
||||
// Return as an error:
|
||||
return nil, []error{fmt.Errorf("%s not found in system path", ipc.executable)}
|
||||
}
|
||||
// Return as a warning:
|
||||
return []error{fmt.Errorf("%s not found in system path", ipc.executable)}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// HostnameCheck checks if hostname match dns sub domain regex.
|
||||
// If hostname doesn't match this regex, kubelet will not launch static pods like kube-apiserver/kube-controller-manager and so on.
|
||||
type HostnameCheck struct {
|
||||
nodeName string
|
||||
}
|
||||
|
||||
func (hc HostnameCheck) Check() (warnings, errors []error) {
|
||||
errors = []error{}
|
||||
warnings = []error{}
|
||||
for _, msg := range validation.ValidateNodeName(hc.nodeName, false) {
|
||||
errors = append(errors, fmt.Errorf("hostname \"%s\" %s", hc.nodeName, msg))
|
||||
}
|
||||
addr, err := net.LookupHost(hc.nodeName)
|
||||
if addr == nil {
|
||||
warnings = append(warnings, fmt.Errorf("hostname \"%s\" could not be reached", hc.nodeName))
|
||||
}
|
||||
if err != nil {
|
||||
warnings = append(warnings, fmt.Errorf("hostname \"%s\" %s", hc.nodeName, err))
|
||||
}
|
||||
return warnings, errors
|
||||
}
|
||||
|
||||
// HTTPProxyCheck checks if https connection to specific host is going
|
||||
// to be done directly or over proxy. If proxy detected, it will return warning.
|
||||
type HTTPProxyCheck struct {
|
||||
Proto string
|
||||
Host string
|
||||
Port int
|
||||
}
|
||||
|
||||
func (hst HTTPProxyCheck) Check() (warnings, errors []error) {
|
||||
|
||||
url := fmt.Sprintf("%s://%s:%d", hst.Proto, hst.Host, hst.Port)
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, []error{err}
|
||||
}
|
||||
|
||||
proxy, err := http.DefaultTransport.(*http.Transport).Proxy(req)
|
||||
if err != nil {
|
||||
return nil, []error{err}
|
||||
}
|
||||
if proxy != nil {
|
||||
return []error{fmt.Errorf("Connection to %q uses proxy %q. If that is not intended, adjust your proxy settings", url, proxy)}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ExtraArgsCheck checks if arguments are valid.
|
||||
type ExtraArgsCheck struct {
|
||||
APIServerExtraArgs map[string]string
|
||||
ControllerManagerExtraArgs map[string]string
|
||||
SchedulerExtraArgs map[string]string
|
||||
}
|
||||
|
||||
func (eac ExtraArgsCheck) Check() (warnings, errors []error) {
|
||||
argsCheck := func(name string, args map[string]string, f *pflag.FlagSet) []error {
|
||||
errs := []error{}
|
||||
for k, v := range args {
|
||||
if err := f.Set(k, v); err != nil {
|
||||
errs = append(errs, fmt.Errorf("%s: failed to parse extra argument --%s=%s", name, k, v))
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
warnings = []error{}
|
||||
if len(eac.APIServerExtraArgs) > 0 {
|
||||
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
|
||||
s := apiservoptions.NewServerRunOptions()
|
||||
s.AddFlags(flags)
|
||||
warnings = append(warnings, argsCheck("kube-apiserver", eac.APIServerExtraArgs, flags)...)
|
||||
}
|
||||
if len(eac.ControllerManagerExtraArgs) > 0 {
|
||||
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
|
||||
s := cmoptions.NewCMServer()
|
||||
s.AddFlags(flags, []string{}, []string{})
|
||||
warnings = append(warnings, argsCheck("kube-controller-manager", eac.ControllerManagerExtraArgs, flags)...)
|
||||
}
|
||||
if len(eac.SchedulerExtraArgs) > 0 {
|
||||
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
|
||||
s := schoptions.NewSchedulerServer()
|
||||
s.AddFlags(flags)
|
||||
warnings = append(warnings, argsCheck("kube-scheduler", eac.SchedulerExtraArgs, flags)...)
|
||||
}
|
||||
return warnings, nil
|
||||
}
|
||||
|
||||
type SystemVerificationCheck struct{}
|
||||
|
||||
func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
|
||||
// Create a buffered writer and choose a quite large value (1M) and suppose the output from the system verification test won't exceed the limit
|
||||
// Run the system verification check, but write to out buffered writer instead of stdout
|
||||
bufw := bufio.NewWriterSize(os.Stdout, 1*1024*1024)
|
||||
reporter := &system.StreamReporter{WriteStream: bufw}
|
||||
|
||||
var errs []error
|
||||
var warns []error
|
||||
// All the validators we'd like to run:
|
||||
var validators = []system.Validator{
|
||||
&system.OSValidator{Reporter: reporter},
|
||||
&system.KernelValidator{Reporter: reporter},
|
||||
&system.CgroupsValidator{Reporter: reporter},
|
||||
&system.DockerValidator{Reporter: reporter},
|
||||
}
|
||||
|
||||
// Run all validators
|
||||
for _, v := range validators {
|
||||
warn, err := v.Validate(system.DefaultSysSpec)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if warn != nil {
|
||||
warns = append(warns, warn)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) != 0 {
|
||||
// Only print the output from the system verification check if the check failed
|
||||
fmt.Println("[preflight] The system verification failed. Printing the output from the verification:")
|
||||
bufw.Flush()
|
||||
return warns, errs
|
||||
}
|
||||
return warns, nil
|
||||
}
|
||||
|
||||
type KubernetesVersionCheck struct {
|
||||
KubeadmVersion string
|
||||
KubernetesVersion string
|
||||
}
|
||||
|
||||
func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) {
|
||||
|
||||
// Skip this check for "super-custom builds", where apimachinery/the overall codebase version is not set.
|
||||
if strings.HasPrefix(kubever.KubeadmVersion, "v0.0.0") {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
kadmVersion, err := versionutil.ParseSemantic(kubever.KubeadmVersion)
|
||||
if err != nil {
|
||||
return nil, []error{fmt.Errorf("couldn't parse kubeadm version %q: %v", kubever.KubeadmVersion, err)}
|
||||
}
|
||||
|
||||
k8sVersion, err := versionutil.ParseSemantic(kubever.KubernetesVersion)
|
||||
if err != nil {
|
||||
return nil, []error{fmt.Errorf("couldn't parse kubernetes version %q: %v", kubever.KubernetesVersion, err)}
|
||||
}
|
||||
|
||||
// Checks if k8sVersion greater or equal than the first unsupported versions by current version of kubeadm,
|
||||
// that is major.minor+1 (all patch and pre-releases versions included)
|
||||
// NB. in semver patches number is a numeric, while prerelease is a string where numeric identifiers always have lower precedence than non-numeric identifiers.
|
||||
// thus setting the value to x.y.0-0 we are defining the very first patch - prereleases within x.y minor release.
|
||||
firstUnsupportedVersion := versionutil.MustParseSemantic(fmt.Sprintf("%d.%d.%s", kadmVersion.Major(), kadmVersion.Minor()+1, "0-0"))
|
||||
if k8sVersion.AtLeast(firstUnsupportedVersion) {
|
||||
return []error{fmt.Errorf("kubernetes version is greater than kubeadm version. Please consider to upgrade kubeadm. kubernetes version: %s. Kubeadm version: %d.%d.x", k8sVersion, kadmVersion.Components()[0], kadmVersion.Components()[1])}, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// SwapCheck warns if swap is enabled
|
||||
type SwapCheck struct{}
|
||||
|
||||
func (swc SwapCheck) Check() (warnings, errors []error) {
|
||||
f, err := os.Open("/proc/swaps")
|
||||
if err != nil {
|
||||
// /proc/swaps not available, thus no reasons to warn
|
||||
return nil, nil
|
||||
}
|
||||
defer f.Close()
|
||||
var buf []string
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
buf = append(buf, scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, []error{fmt.Errorf("error parsing /proc/swaps: %v", err)}
|
||||
}
|
||||
|
||||
if len(buf) > 1 {
|
||||
return []error{fmt.Errorf("Running with swap on is not supported. Please disable swap or set kubelet's --fail-swap-on flag to false.")}, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type etcdVersionResponse struct {
|
||||
Etcdserver string `json:"etcdserver"`
|
||||
Etcdcluster string `json:"etcdcluster"`
|
||||
}
|
||||
|
||||
// ExternalEtcdVersionCheck checks if version of external etcd meets the demand of kubeadm
|
||||
type ExternalEtcdVersionCheck struct {
|
||||
Etcd kubeadmapi.Etcd
|
||||
}
|
||||
|
||||
func (evc ExternalEtcdVersionCheck) Check() (warnings, errors []error) {
|
||||
var config *tls.Config
|
||||
var err error
|
||||
if config, err = evc.configRootCAs(config); err != nil {
|
||||
errors = append(errors, err)
|
||||
return nil, errors
|
||||
}
|
||||
if config, err = evc.configCertAndKey(config); err != nil {
|
||||
errors = append(errors, err)
|
||||
return nil, errors
|
||||
}
|
||||
|
||||
client := evc.getHTTPClient(config)
|
||||
for _, endpoint := range evc.Etcd.Endpoints {
|
||||
if _, err := url.Parse(endpoint); err != nil {
|
||||
errors = append(errors, fmt.Errorf("failed to parse external etcd endpoint %s : %v", endpoint, err))
|
||||
continue
|
||||
}
|
||||
resp := etcdVersionResponse{}
|
||||
var err error
|
||||
versionURL := fmt.Sprintf("%s/%s", endpoint, "version")
|
||||
if tmpVersionURL, err := purell.NormalizeURLString(versionURL, purell.FlagRemoveDuplicateSlashes); err != nil {
|
||||
errors = append(errors, fmt.Errorf("failed to normalize external etcd version url %s : %v", versionURL, err))
|
||||
continue
|
||||
} else {
|
||||
versionURL = tmpVersionURL
|
||||
}
|
||||
if err = getEtcdVersionResponse(client, versionURL, &resp); err != nil {
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
etcdVersion, err := semver.Parse(resp.Etcdserver)
|
||||
if err != nil {
|
||||
errors = append(errors, fmt.Errorf("couldn't parse external etcd version %q: %v", resp.Etcdserver, err))
|
||||
continue
|
||||
}
|
||||
if etcdVersion.LT(minExternalEtcdVersion) {
|
||||
errors = append(errors, fmt.Errorf("this version of kubeadm only supports external etcd version >= %s. Current version: %s", kubeadmconstants.MinExternalEtcdVersion, resp.Etcdserver))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors
|
||||
}
|
||||
|
||||
// configRootCAs configures and returns a reference to tls.Config instance if CAFile is provided
|
||||
func (evc ExternalEtcdVersionCheck) configRootCAs(config *tls.Config) (*tls.Config, error) {
|
||||
var CACertPool *x509.CertPool
|
||||
if evc.Etcd.CAFile != "" {
|
||||
CACert, err := ioutil.ReadFile(evc.Etcd.CAFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't load external etcd's server certificate %s: %v", evc.Etcd.CAFile, err)
|
||||
}
|
||||
CACertPool = x509.NewCertPool()
|
||||
CACertPool.AppendCertsFromPEM(CACert)
|
||||
}
|
||||
if CACertPool != nil {
|
||||
if config == nil {
|
||||
config = &tls.Config{}
|
||||
}
|
||||
config.RootCAs = CACertPool
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// configCertAndKey configures and returns a reference to tls.Config instance if CertFile and KeyFile pair is provided
|
||||
func (evc ExternalEtcdVersionCheck) configCertAndKey(config *tls.Config) (*tls.Config, error) {
|
||||
var cert tls.Certificate
|
||||
if evc.Etcd.CertFile != "" && evc.Etcd.KeyFile != "" {
|
||||
var err error
|
||||
cert, err = tls.LoadX509KeyPair(evc.Etcd.CertFile, evc.Etcd.KeyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't load external etcd's certificate and key pair %s, %s: %v", evc.Etcd.CertFile, evc.Etcd.KeyFile, err)
|
||||
}
|
||||
if config == nil {
|
||||
config = &tls.Config{}
|
||||
}
|
||||
config.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
func (evc ExternalEtcdVersionCheck) getHTTPClient(config *tls.Config) *http.Client {
|
||||
if config != nil {
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: config,
|
||||
}
|
||||
return &http.Client{
|
||||
Transport: transport,
|
||||
Timeout: externalEtcdRequestTimeout,
|
||||
}
|
||||
}
|
||||
return &http.Client{Timeout: externalEtcdRequestTimeout}
|
||||
}
|
||||
func getEtcdVersionResponse(client *http.Client, url string, target interface{}) error {
|
||||
loopCount := externalEtcdRequestRetries + 1
|
||||
var err error
|
||||
var stopRetry bool
|
||||
for loopCount > 0 {
|
||||
if loopCount <= externalEtcdRequestRetries {
|
||||
time.Sleep(externalEtcdRequestInterval)
|
||||
}
|
||||
stopRetry, err = func() (stopRetry bool, err error) {
|
||||
r, err := client.Get(url)
|
||||
if err != nil {
|
||||
loopCount--
|
||||
return false, nil
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
if r != nil && r.StatusCode >= 500 && r.StatusCode <= 599 {
|
||||
loopCount--
|
||||
return false, nil
|
||||
}
|
||||
return true, json.NewDecoder(r.Body).Decode(target)
|
||||
|
||||
}()
|
||||
if stopRetry {
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
|
||||
// First, check if we're root separately from the other preflight checks and fail fast
|
||||
if err := RunRootCheckOnly(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
checks := []Checker{
|
||||
KubernetesVersionCheck{KubernetesVersion: cfg.KubernetesVersion, KubeadmVersion: kubeadmversion.Get().GitVersion},
|
||||
SystemVerificationCheck{},
|
||||
IsRootCheck{},
|
||||
HostnameCheck{nodeName: cfg.NodeName},
|
||||
ServiceCheck{Service: "kubelet", CheckIfActive: false},
|
||||
ServiceCheck{Service: "docker", CheckIfActive: true},
|
||||
FirewalldCheck{ports: []int{int(cfg.API.BindPort), 10250}},
|
||||
PortOpenCheck{port: int(cfg.API.BindPort)},
|
||||
PortOpenCheck{port: 10250},
|
||||
PortOpenCheck{port: 10251},
|
||||
PortOpenCheck{port: 10252},
|
||||
HTTPProxyCheck{Proto: "https", Host: cfg.API.AdvertiseAddress, Port: int(cfg.API.BindPort)},
|
||||
DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)},
|
||||
DirAvailableCheck{Path: "/var/lib/kubelet"},
|
||||
FileContentCheck{Path: bridgenf, Content: []byte{'1'}},
|
||||
SwapCheck{},
|
||||
InPathCheck{executable: "ip", mandatory: true},
|
||||
InPathCheck{executable: "iptables", mandatory: true},
|
||||
InPathCheck{executable: "mount", mandatory: true},
|
||||
InPathCheck{executable: "nsenter", mandatory: true},
|
||||
InPathCheck{executable: "ebtables", mandatory: false},
|
||||
InPathCheck{executable: "ethtool", mandatory: false},
|
||||
InPathCheck{executable: "socat", mandatory: false},
|
||||
InPathCheck{executable: "tc", mandatory: false},
|
||||
InPathCheck{executable: "touch", mandatory: false},
|
||||
ExtraArgsCheck{
|
||||
APIServerExtraArgs: cfg.APIServerExtraArgs,
|
||||
ControllerManagerExtraArgs: cfg.ControllerManagerExtraArgs,
|
||||
SchedulerExtraArgs: cfg.SchedulerExtraArgs,
|
||||
},
|
||||
}
|
||||
|
||||
if len(cfg.Etcd.Endpoints) == 0 {
|
||||
// Only do etcd related checks when no external endpoints were specified
|
||||
checks = append(checks,
|
||||
PortOpenCheck{port: 2379},
|
||||
DirAvailableCheck{Path: cfg.Etcd.DataDir},
|
||||
)
|
||||
} else {
|
||||
// Only check etcd version when external endpoints are specified
|
||||
checks = append(checks,
|
||||
ExternalEtcdVersionCheck{Etcd: cfg.Etcd},
|
||||
)
|
||||
}
|
||||
|
||||
// Check the config for authorization mode
|
||||
for _, authzMode := range cfg.AuthorizationModes {
|
||||
switch authzMode {
|
||||
case authzmodes.ModeABAC:
|
||||
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationPolicyPath})
|
||||
case authzmodes.ModeWebhook:
|
||||
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationWebhookConfigPath})
|
||||
}
|
||||
}
|
||||
|
||||
return RunChecks(checks, os.Stderr)
|
||||
}
|
||||
|
||||
func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error {
|
||||
// First, check if we're root separately from the other preflight checks and fail fast
|
||||
if err := RunRootCheckOnly(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
checks := []Checker{
|
||||
SystemVerificationCheck{},
|
||||
IsRootCheck{},
|
||||
HostnameCheck{cfg.NodeName},
|
||||
ServiceCheck{Service: "kubelet", CheckIfActive: false},
|
||||
ServiceCheck{Service: "docker", CheckIfActive: true},
|
||||
PortOpenCheck{port: 10250},
|
||||
DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)},
|
||||
DirAvailableCheck{Path: "/var/lib/kubelet"},
|
||||
FileAvailableCheck{Path: cfg.CACertPath},
|
||||
FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)},
|
||||
FileContentCheck{Path: bridgenf, Content: []byte{'1'}},
|
||||
SwapCheck{},
|
||||
InPathCheck{executable: "ip", mandatory: true},
|
||||
InPathCheck{executable: "iptables", mandatory: true},
|
||||
InPathCheck{executable: "mount", mandatory: true},
|
||||
InPathCheck{executable: "nsenter", mandatory: true},
|
||||
InPathCheck{executable: "ebtables", mandatory: false},
|
||||
InPathCheck{executable: "ethtool", mandatory: false},
|
||||
InPathCheck{executable: "socat", mandatory: false},
|
||||
InPathCheck{executable: "tc", mandatory: false},
|
||||
InPathCheck{executable: "touch", mandatory: false},
|
||||
}
|
||||
|
||||
return RunChecks(checks, os.Stderr)
|
||||
}
|
||||
|
||||
func RunRootCheckOnly() error {
|
||||
checks := []Checker{
|
||||
IsRootCheck{},
|
||||
}
|
||||
|
||||
return RunChecks(checks, os.Stderr)
|
||||
}
|
||||
|
||||
// RunChecks runs each check, displays it's warnings/errors, and once all
|
||||
// are processed will exit if any errors occurred.
|
||||
func RunChecks(checks []Checker, ww io.Writer) error {
|
||||
found := []error{}
|
||||
for _, c := range checks {
|
||||
warnings, errs := c.Check()
|
||||
for _, w := range warnings {
|
||||
io.WriteString(ww, fmt.Sprintf("[preflight] WARNING: %v\n", w))
|
||||
}
|
||||
found = append(found, errs...)
|
||||
}
|
||||
if len(found) > 0 {
|
||||
var errs bytes.Buffer
|
||||
for _, i := range found {
|
||||
errs.WriteString("\t" + i.Error() + "\n")
|
||||
}
|
||||
return &Error{Msg: errs.String()}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TryStartKubelet() {
|
||||
// If we notice that the kubelet service is inactive, try to start it
|
||||
initSystem, err := initsystem.GetInitSystem()
|
||||
if err != nil {
|
||||
fmt.Println("[preflight] No supported init system detected, won't ensure kubelet is running.")
|
||||
} else if initSystem.ServiceExists("kubelet") && !initSystem.ServiceIsActive("kubelet") {
|
||||
|
||||
fmt.Println("[preflight] Starting the kubelet service")
|
||||
if err := initSystem.ServiceStart("kubelet"); err != nil {
|
||||
fmt.Printf("[preflight] WARNING: Unable to start the kubelet service: [%v]\n", err)
|
||||
fmt.Println("[preflight] WARNING: Please ensure kubelet is running manually.")
|
||||
}
|
||||
}
|
||||
}
|
||||
411
vendor/k8s.io/kubernetes/cmd/kubeadm/app/preflight/checks_test.go
generated
vendored
Normal file
411
vendor/k8s.io/kubernetes/cmd/kubeadm/app/preflight/checks_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
/*
|
||||
Copyright 2016 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.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
|
||||
"os"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
)
|
||||
|
||||
var (
|
||||
externalEtcdRootCAFileContent = dedent.Dedent(`
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
Z9JkQayesM6D7uwbQJXd5rgy
|
||||
-----END CERTIFICATE-----
|
||||
`)
|
||||
|
||||
externalEtcdCertFileContent = dedent.Dedent(`
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
XRMVQjawUTknbAgHuE7/rEX8c27WUA==
|
||||
-----END CERTIFICATE-----
|
||||
`)
|
||||
externalEtcdKeyFileContent = dedent.Dedent(`
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`)
|
||||
)
|
||||
|
||||
type preflightCheckTest struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
func (pfct preflightCheckTest) Check() (warning, errors []error) {
|
||||
if pfct.msg == "warning" {
|
||||
return []error{fmt.Errorf("warning")}, nil
|
||||
}
|
||||
if pfct.msg != "" {
|
||||
return nil, []error{fmt.Errorf("fake error")}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func TestRunInitMasterChecks(t *testing.T) {
|
||||
var tests = []struct {
|
||||
cfg *kubeadmapi.MasterConfiguration
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
cfg: &kubeadmapi.MasterConfiguration{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "foo"},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, rt := range tests {
|
||||
actual := RunInitMasterChecks(rt.cfg)
|
||||
if (actual == nil) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed RunInitMasterChecks:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(actual != nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunJoinNodeChecks(t *testing.T) {
|
||||
var tests = []struct {
|
||||
cfg *kubeadmapi.NodeConfiguration
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
cfg: &kubeadmapi.NodeConfiguration{},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, rt := range tests {
|
||||
actual := RunJoinNodeChecks(rt.cfg)
|
||||
if (actual == nil) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed RunJoinNodeChecks:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(actual != nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunChecks(t *testing.T) {
|
||||
var tokenTest = []struct {
|
||||
p []Checker
|
||||
expected bool
|
||||
output string
|
||||
}{
|
||||
{[]Checker{}, true, ""},
|
||||
{[]Checker{preflightCheckTest{"warning"}}, true, "[preflight] WARNING: warning\n"}, // should just print warning
|
||||
{[]Checker{preflightCheckTest{"error"}}, false, ""},
|
||||
{[]Checker{preflightCheckTest{"test"}}, false, ""},
|
||||
{[]Checker{DirAvailableCheck{Path: "/does/not/exist"}}, true, ""},
|
||||
{[]Checker{DirAvailableCheck{Path: "/"}}, false, ""},
|
||||
{[]Checker{FileAvailableCheck{Path: "/does/not/exist"}}, true, ""},
|
||||
{[]Checker{FileContentCheck{Path: "/does/not/exist"}}, false, ""},
|
||||
{[]Checker{FileContentCheck{Path: "/"}}, true, ""},
|
||||
{[]Checker{FileContentCheck{Path: "/", Content: []byte("does not exist")}}, false, ""},
|
||||
{[]Checker{InPathCheck{executable: "foobarbaz"}}, true, "[preflight] WARNING: foobarbaz not found in system path\n"},
|
||||
{[]Checker{InPathCheck{executable: "foobarbaz", mandatory: true}}, false, ""},
|
||||
{[]Checker{ExtraArgsCheck{
|
||||
APIServerExtraArgs: map[string]string{"secure-port": "1234"},
|
||||
ControllerManagerExtraArgs: map[string]string{"use-service-account-credentials": "true"},
|
||||
SchedulerExtraArgs: map[string]string{"leader-elect": "true"},
|
||||
}}, true, ""},
|
||||
{[]Checker{ExtraArgsCheck{
|
||||
APIServerExtraArgs: map[string]string{"secure-port": "foo"},
|
||||
}}, true, "[preflight] WARNING: kube-apiserver: failed to parse extra argument --secure-port=foo\n"},
|
||||
{[]Checker{ExtraArgsCheck{
|
||||
APIServerExtraArgs: map[string]string{"invalid-argument": "foo"},
|
||||
}}, true, "[preflight] WARNING: kube-apiserver: failed to parse extra argument --invalid-argument=foo\n"},
|
||||
}
|
||||
for _, rt := range tokenTest {
|
||||
buf := new(bytes.Buffer)
|
||||
actual := RunChecks(rt.p, buf)
|
||||
if (actual == nil) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed RunChecks:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
if buf.String() != rt.output {
|
||||
t.Errorf(
|
||||
"failed RunChecks:\n\texpected: %s\n\t actual: %s",
|
||||
rt.output,
|
||||
buf.String(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestConfigRootCAs(t *testing.T) {
|
||||
f, err := ioutil.TempFile(os.TempDir(), "kubeadm-external-etcd-test-cafile")
|
||||
if err != nil {
|
||||
t.Errorf("failed configRootCAs:\n\texpected: succeed creating temp CA file\n\tactual:%v", err)
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
if err := ioutil.WriteFile(f.Name(), []byte(externalEtcdRootCAFileContent), 0644); err != nil {
|
||||
t.Errorf("failed configRootCAs:\n\texpected: succeed writing contents to temp CA file %s\n\tactual:%v", f.Name(), err)
|
||||
}
|
||||
|
||||
c := ExternalEtcdVersionCheck{Etcd: kubeadmapi.Etcd{CAFile: f.Name()}}
|
||||
|
||||
config, err := c.configRootCAs(nil)
|
||||
if err != nil {
|
||||
t.Errorf(
|
||||
"failed configRootCAs:\n\texpected: has no error\n\tactual:%v",
|
||||
err,
|
||||
)
|
||||
}
|
||||
if config.RootCAs == nil {
|
||||
t.Errorf(
|
||||
"failed configRootCAs:\n\texpected: RootCAs not equal to nil\n\tactual:%v",
|
||||
config.RootCAs,
|
||||
)
|
||||
}
|
||||
}
|
||||
func TestConfigCertAndKey(t *testing.T) {
|
||||
certFile, err := ioutil.TempFile(os.TempDir(), "kubeadm-external-etcd-test-certfile")
|
||||
if err != nil {
|
||||
t.Errorf(
|
||||
"failed configCertAndKey:\n\texpected: succeed creating temp CertFile file\n\tactual:%v",
|
||||
err,
|
||||
)
|
||||
}
|
||||
defer os.Remove(certFile.Name())
|
||||
if err := ioutil.WriteFile(certFile.Name(), []byte(externalEtcdCertFileContent), 0644); err != nil {
|
||||
t.Errorf(
|
||||
"failed configCertAndKey:\n\texpected: succeed writing contents to temp CertFile file %s\n\tactual:%v",
|
||||
certFile.Name(),
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
keyFile, err := ioutil.TempFile(os.TempDir(), "kubeadm-external-etcd-test-keyfile")
|
||||
if err != nil {
|
||||
t.Errorf(
|
||||
"failed configCertAndKey:\n\texpected: succeed creating temp KeyFile file\n\tactual:%v",
|
||||
err,
|
||||
)
|
||||
}
|
||||
defer os.Remove(keyFile.Name())
|
||||
if err := ioutil.WriteFile(keyFile.Name(), []byte(externalEtcdKeyFileContent), 0644); err != nil {
|
||||
t.Errorf(
|
||||
"failed configCertAndKey:\n\texpected: succeed writing contents to temp KeyFile file %s\n\tactual:%v",
|
||||
keyFile.Name(),
|
||||
err,
|
||||
)
|
||||
}
|
||||
c := ExternalEtcdVersionCheck{Etcd: kubeadmapi.Etcd{
|
||||
CertFile: certFile.Name(),
|
||||
KeyFile: keyFile.Name(),
|
||||
}}
|
||||
|
||||
config, err := c.configCertAndKey(nil)
|
||||
if err != nil {
|
||||
t.Errorf(
|
||||
"failed configCertAndKey:\n\texpected: has no error\n\tactual:%v",
|
||||
err,
|
||||
)
|
||||
}
|
||||
if config.Certificates == nil {
|
||||
t.Errorf(
|
||||
"failed configCertAndKey:\n\texpected: Certificates not equal to nil\n\tactual:%v",
|
||||
config.Certificates,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubernetesVersionCheck(t *testing.T) {
|
||||
var tests = []struct {
|
||||
check KubernetesVersionCheck
|
||||
expectWarnings bool
|
||||
}{
|
||||
{
|
||||
check: KubernetesVersionCheck{
|
||||
KubeadmVersion: "v1.6.6", //Same version
|
||||
KubernetesVersion: "v1.6.6",
|
||||
},
|
||||
expectWarnings: false,
|
||||
},
|
||||
{
|
||||
check: KubernetesVersionCheck{
|
||||
KubeadmVersion: "v1.6.6", //KubernetesVersion version older than KubeadmVersion
|
||||
KubernetesVersion: "v1.5.5",
|
||||
},
|
||||
expectWarnings: false,
|
||||
},
|
||||
{
|
||||
check: KubernetesVersionCheck{
|
||||
KubeadmVersion: "v1.6.6", //KubernetesVersion newer than KubeadmVersion, within the same minor release (new patch)
|
||||
KubernetesVersion: "v1.6.7",
|
||||
},
|
||||
expectWarnings: false,
|
||||
},
|
||||
{
|
||||
check: KubernetesVersionCheck{
|
||||
KubeadmVersion: "v1.6.6", //KubernetesVersion newer than KubeadmVersion, in a different minor/in pre-release
|
||||
KubernetesVersion: "v1.7.0-alpha.0",
|
||||
},
|
||||
expectWarnings: true,
|
||||
},
|
||||
{
|
||||
check: KubernetesVersionCheck{
|
||||
KubeadmVersion: "v1.6.6", //KubernetesVersion newer than KubeadmVersion, in a different minor/stable
|
||||
KubernetesVersion: "v1.7.0",
|
||||
},
|
||||
expectWarnings: true,
|
||||
},
|
||||
{
|
||||
check: KubernetesVersionCheck{
|
||||
KubeadmVersion: "v0.0.0", //"super-custom" builds - Skip this check
|
||||
KubernetesVersion: "v1.7.0",
|
||||
},
|
||||
expectWarnings: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, rt := range tests {
|
||||
warning, _ := rt.check.Check()
|
||||
if (warning != nil) != rt.expectWarnings {
|
||||
t.Errorf(
|
||||
"failed KubernetesVersionCheck:\n\texpected: %t\n\t actual: %t (KubeadmVersion:%s, KubernetesVersion: %s)",
|
||||
rt.expectWarnings,
|
||||
(warning != nil),
|
||||
rt.check.KubeadmVersion,
|
||||
rt.check.KubernetesVersion,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue