package util import ( "context" "fmt" "net" "net/http" "strconv" "time" "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" ) func GetAddresses(endpoint *v1.Endpoints) []string { serverAddresses := []string{} if endpoint == nil { return serverAddresses } for _, subset := range endpoint.Subsets { var port string if len(subset.Ports) > 0 { port = strconv.Itoa(int(subset.Ports[0].Port)) } if port == "" { port = "443" } for _, address := range subset.Addresses { serverAddresses = append(serverAddresses, net.JoinHostPort(address.IP, port)) } } return serverAddresses } // WaitForAPIServerReady waits for the API Server's /readyz endpoint to report "ok" with timeout. // This is cribbed from the Kubernetes controller-manager app, but checks the readyz endpoint instead of the deprecated healthz endpoint. func WaitForAPIServerReady(client clientset.Interface, timeout time.Duration) error { var lastErr error err := wait.PollImmediate(time.Second, timeout, func() (bool, error) { healthStatus := 0 result := client.Discovery().RESTClient().Get().AbsPath("/readyz").Do(context.TODO()).StatusCode(&healthStatus) if result.Error() != nil { lastErr = fmt.Errorf("failed to get apiserver /readyz status: %v", result.Error()) return false, nil } if healthStatus != http.StatusOK { content, _ := result.Raw() lastErr = fmt.Errorf("APIServer isn't ready: %v", string(content)) logrus.Warnf("APIServer isn't ready yet: %v. Waiting a little while.", string(content)) return false, nil } return true, nil }) if err != nil { return fmt.Errorf("%v: %v", err, lastErr) } return nil }