k8s.io/apiserver@v0.29.3/pkg/storage/etcd3/preflight/checks.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package preflight 18 19 import ( 20 "fmt" 21 "math/rand" 22 "net" 23 "net/url" 24 "time" 25 ) 26 27 const connectionTimeout = 1 * time.Second 28 29 // EtcdConnection holds the Etcd server list 30 type EtcdConnection struct { 31 ServerList []string 32 } 33 34 func (EtcdConnection) serverReachable(connURL *url.URL) bool { 35 scheme := connURL.Scheme 36 if scheme == "http" || scheme == "https" || scheme == "tcp" { 37 scheme = "tcp" 38 } 39 if conn, err := net.DialTimeout(scheme, connURL.Host, connectionTimeout); err == nil { 40 defer conn.Close() 41 return true 42 } 43 return false 44 } 45 46 func parseServerURI(serverURI string) (*url.URL, error) { 47 connURL, err := url.Parse(serverURI) 48 if err != nil { 49 return &url.URL{}, fmt.Errorf("unable to parse etcd url: %v", err) 50 } 51 return connURL, nil 52 } 53 54 // CheckEtcdServers will attempt to reach all etcd servers once. If any 55 // can be reached, return true. 56 func (con EtcdConnection) CheckEtcdServers() (done bool, err error) { 57 // Attempt to reach every Etcd server randomly. 58 serverNumber := len(con.ServerList) 59 serverPerms := rand.Perm(serverNumber) 60 for _, index := range serverPerms { 61 host, err := parseServerURI(con.ServerList[index]) 62 if err != nil { 63 return false, err 64 } 65 if con.serverReachable(host) { 66 return true, nil 67 } 68 } 69 return false, nil 70 }