mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-15 14:14:39 +00:00
kubeadm: reduce the usage of InitConfiguration
For historical reasons InitConfiguration is used almost everywhere in kubeadm as a carrier of various configuration components such as ClusterConfiguration, local API server endpoint, node registration settings, etc. Since v1alpha2, InitConfiguration is meant to be used solely as a way to supply the kubeadm init configuration from a config file. Its usage outside of this context is caused by technical dept, it's clunky and requires hacks to fetch a working InitConfiguration from the cluster (as it's not stored in the config map in its entirety). This change is a small step towards removing all unnecessary usages of InitConfiguration. It reduces its usage by replacing it in some places with some of the following: - ClusterConfiguration only. - APIEndpoint (as local API server endpoint). - NodeRegistrationOptions only. - Some combinations of the above types, or if single fields from them are used, only those field. Signed-off-by: Rostislav M. Georgiev <rostislavg@vmware.com>
This commit is contained in:
@@ -29,35 +29,35 @@ import (
|
||||
)
|
||||
|
||||
// GetMasterEndpoint returns a properly formatted endpoint for the control plane built according following rules:
|
||||
// - If the ControlPlaneEndpoint is defined, use it.
|
||||
// - if the ControlPlaneEndpoint is defined but without a port number, use the ControlPlaneEndpoint + api.BindPort is used.
|
||||
// - Otherwise, in case the ControlPlaneEndpoint is not defined, use the api.AdvertiseAddress + the api.BindPort.
|
||||
func GetMasterEndpoint(cfg *kubeadmapi.InitConfiguration) (string, error) {
|
||||
// - If the controlPlaneEndpoint is defined, use it.
|
||||
// - if the controlPlaneEndpoint is defined but without a port number, use the controlPlaneEndpoint + localEndpoint.BindPort is used.
|
||||
// - Otherwise, in case the controlPlaneEndpoint is not defined, use the localEndpoint.AdvertiseAddress + the localEndpoint.BindPort.
|
||||
func GetMasterEndpoint(controlPlaneEndpoint string, localEndpoint *kubeadmapi.APIEndpoint) (string, error) {
|
||||
// parse the bind port
|
||||
bindPortString := strconv.Itoa(int(cfg.LocalAPIEndpoint.BindPort))
|
||||
bindPortString := strconv.Itoa(int(localEndpoint.BindPort))
|
||||
if _, err := ParsePort(bindPortString); err != nil {
|
||||
return "", errors.Wrapf(err, "invalid value %q given for api.bindPort", cfg.LocalAPIEndpoint.BindPort)
|
||||
return "", errors.Wrapf(err, "invalid value %q given for api.bindPort", localEndpoint.BindPort)
|
||||
}
|
||||
|
||||
// parse the AdvertiseAddress
|
||||
var ip = net.ParseIP(cfg.LocalAPIEndpoint.AdvertiseAddress)
|
||||
var ip = net.ParseIP(localEndpoint.AdvertiseAddress)
|
||||
if ip == nil {
|
||||
return "", errors.Errorf("invalid value `%s` given for api.advertiseAddress", cfg.LocalAPIEndpoint.AdvertiseAddress)
|
||||
return "", errors.Errorf("invalid value `%s` given for api.advertiseAddress", localEndpoint.AdvertiseAddress)
|
||||
}
|
||||
|
||||
// set the master url using cfg.API.AdvertiseAddress + the cfg.API.BindPort
|
||||
// set the master url using localEndpoint.AdvertiseAddress + the localEndpoint.BindPort
|
||||
masterURL := &url.URL{
|
||||
Scheme: "https",
|
||||
Host: net.JoinHostPort(ip.String(), bindPortString),
|
||||
}
|
||||
|
||||
// if the controlplane endpoint is defined
|
||||
if len(cfg.ControlPlaneEndpoint) > 0 {
|
||||
if len(controlPlaneEndpoint) > 0 {
|
||||
// parse the controlplane endpoint
|
||||
var host, port string
|
||||
var err error
|
||||
if host, port, err = ParseHostPort(cfg.ControlPlaneEndpoint); err != nil {
|
||||
return "", errors.Wrapf(err, "invalid value %q given for controlPlaneEndpoint", cfg.ControlPlaneEndpoint)
|
||||
if host, port, err = ParseHostPort(controlPlaneEndpoint); err != nil {
|
||||
return "", errors.Wrapf(err, "invalid value %q given for controlPlaneEndpoint", controlPlaneEndpoint)
|
||||
}
|
||||
|
||||
// if a port is provided within the controlPlaneAddress warn the users we are using it, else use the bindport
|
||||
|
@@ -198,7 +198,7 @@ func TestGetMasterEndpoint(t *testing.T) {
|
||||
|
||||
for _, rt := range tests {
|
||||
t.Run(rt.name, func(t *testing.T) {
|
||||
actualEndpoint, actualError := GetMasterEndpoint(rt.cfg)
|
||||
actualEndpoint, actualError := GetMasterEndpoint(rt.cfg.ControlPlaneEndpoint, &rt.cfg.LocalAPIEndpoint)
|
||||
|
||||
if (actualError != nil) && !rt.expectedError {
|
||||
t.Errorf("%s unexpected failure: %v", rt.name, actualError)
|
||||
|
@@ -290,14 +290,14 @@ func CheckConfigurationIsHA(cfg *kubeadmapi.Etcd) bool {
|
||||
|
||||
// GetClientURL creates an HTTPS URL that uses the configured advertise
|
||||
// address and client port for the API controller
|
||||
func GetClientURL(cfg *kubeadmapi.InitConfiguration) string {
|
||||
return "https://" + net.JoinHostPort(cfg.LocalAPIEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenClientPort))
|
||||
func GetClientURL(localEndpoint *kubeadmapi.APIEndpoint) string {
|
||||
return "https://" + net.JoinHostPort(localEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenClientPort))
|
||||
}
|
||||
|
||||
// GetPeerURL creates an HTTPS URL that uses the configured advertise
|
||||
// address and peer port for the API controller
|
||||
func GetPeerURL(cfg *kubeadmapi.InitConfiguration) string {
|
||||
return "https://" + net.JoinHostPort(cfg.LocalAPIEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenPeerPort))
|
||||
func GetPeerURL(localEndpoint *kubeadmapi.APIEndpoint) string {
|
||||
return "https://" + net.JoinHostPort(localEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenPeerPort))
|
||||
}
|
||||
|
||||
// GetClientURLByIP creates an HTTPS URL based on an IP address
|
||||
|
@@ -72,7 +72,7 @@ func TestCheckConfigurationIsHA(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testGetURL(t *testing.T, getURLFunc func(*kubeadmapi.InitConfiguration) string, port int) {
|
||||
func testGetURL(t *testing.T, getURLFunc func(*kubeadmapi.APIEndpoint) string, port int) {
|
||||
portStr := strconv.Itoa(port)
|
||||
var tests = []struct {
|
||||
name string
|
||||
@@ -102,12 +102,7 @@ func testGetURL(t *testing.T, getURLFunc func(*kubeadmapi.InitConfiguration) str
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
cfg := &kubeadmapi.InitConfiguration{
|
||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
||||
AdvertiseAddress: test.advertiseAddress,
|
||||
},
|
||||
}
|
||||
url := getURLFunc(cfg)
|
||||
url := getURLFunc(&kubeadmapi.APIEndpoint{AdvertiseAddress: test.advertiseAddress})
|
||||
if url != test.expectedURL {
|
||||
t.Errorf("expected %s, got %s", test.expectedURL, url)
|
||||
}
|
||||
|
@@ -12,11 +12,9 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/test:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -32,7 +30,6 @@ go_library(
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@@ -31,7 +31,6 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
@@ -82,28 +81,11 @@ func ComponentResources(cpu string) v1.ResourceRequirements {
|
||||
}
|
||||
}
|
||||
|
||||
// ComponentProbe is a helper function building a ready v1.Probe object from some simple parameters
|
||||
func ComponentProbe(cfg *kubeadmapi.InitConfiguration, componentName string, port int, path string, scheme v1.URIScheme) *v1.Probe {
|
||||
return &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
HTTPGet: &v1.HTTPGetAction{
|
||||
Host: GetProbeAddress(cfg, componentName),
|
||||
Path: path,
|
||||
Port: intstr.FromInt(port),
|
||||
Scheme: scheme,
|
||||
},
|
||||
},
|
||||
InitialDelaySeconds: 15,
|
||||
TimeoutSeconds: 15,
|
||||
FailureThreshold: 8,
|
||||
}
|
||||
}
|
||||
|
||||
// EtcdProbe is a helper function for building a shell-based, etcdctl v1.Probe object to healthcheck etcd
|
||||
func EtcdProbe(cfg *kubeadmapi.InitConfiguration, componentName string, port int, certsDir string, CACertName string, CertName string, KeyName string) *v1.Probe {
|
||||
func EtcdProbe(cfg *kubeadmapi.Etcd, port int, certsDir string, CACertName string, CertName string, KeyName string) *v1.Probe {
|
||||
tlsFlags := fmt.Sprintf("--cacert=%[1]s/%[2]s --cert=%[1]s/%[3]s --key=%[1]s/%[4]s", certsDir, CACertName, CertName, KeyName)
|
||||
// etcd pod is alive if a linearizable get succeeds.
|
||||
cmd := fmt.Sprintf("ETCDCTL_API=3 etcdctl --endpoints=https://[%s]:%d %s get foo", GetProbeAddress(cfg, componentName), port, tlsFlags)
|
||||
cmd := fmt.Sprintf("ETCDCTL_API=3 etcdctl --endpoints=https://[%s]:%d %s get foo", GetEtcdProbeAddress(cfg), port, tlsFlags)
|
||||
|
||||
return &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
@@ -225,71 +207,80 @@ func ReadStaticPodFromDisk(manifestPath string) (*v1.Pod, error) {
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
// GetProbeAddress returns an IP address or 127.0.0.1 to use for liveness probes
|
||||
// in static pod manifests.
|
||||
func GetProbeAddress(cfg *kubeadmapi.InitConfiguration, componentName string) string {
|
||||
switch {
|
||||
case componentName == kubeadmconstants.KubeAPIServer:
|
||||
// In the case of a self-hosted deployment, the initial host on which kubeadm --init is run,
|
||||
// will generate a DaemonSet with a nodeSelector such that all nodes with the label
|
||||
// node-role.kubernetes.io/master='' will have the API server deployed to it. Since the init
|
||||
// is run only once on an initial host, the API advertise address will be invalid for any
|
||||
// future hosts that do not have the same address. Furthermore, since liveness and readiness
|
||||
// probes do not support the Downward API we cannot dynamically set the advertise address to
|
||||
// the node's IP. The only option then is to use localhost.
|
||||
if cfg.LocalAPIEndpoint.AdvertiseAddress != "" {
|
||||
return cfg.LocalAPIEndpoint.AdvertiseAddress
|
||||
}
|
||||
case componentName == kubeadmconstants.KubeControllerManager:
|
||||
if addr, exists := cfg.ControllerManager.ExtraArgs[kubeControllerManagerAddressArg]; exists {
|
||||
return addr
|
||||
}
|
||||
case componentName == kubeadmconstants.KubeScheduler:
|
||||
if addr, exists := cfg.Scheduler.ExtraArgs[kubeSchedulerAddressArg]; exists {
|
||||
return addr
|
||||
}
|
||||
case componentName == kubeadmconstants.Etcd:
|
||||
if cfg.Etcd.Local != nil && cfg.Etcd.Local.ExtraArgs != nil {
|
||||
if arg, exists := cfg.Etcd.Local.ExtraArgs[etcdListenClientURLsArg]; exists {
|
||||
// Use the first url in the listen-client-urls if multiple url's are specified.
|
||||
if strings.ContainsAny(arg, ",") {
|
||||
arg = strings.Split(arg, ",")[0]
|
||||
// GetAPIServerProbeAddress returns the probe address for the API server
|
||||
func GetAPIServerProbeAddress(endpoint *kubeadmapi.APIEndpoint) string {
|
||||
// In the case of a self-hosted deployment, the initial host on which kubeadm --init is run,
|
||||
// will generate a DaemonSet with a nodeSelector such that all nodes with the label
|
||||
// node-role.kubernetes.io/master='' will have the API server deployed to it. Since the init
|
||||
// is run only once on an initial host, the API advertise address will be invalid for any
|
||||
// future hosts that do not have the same address. Furthermore, since liveness and readiness
|
||||
// probes do not support the Downward API we cannot dynamically set the advertise address to
|
||||
// the node's IP. The only option then is to use localhost.
|
||||
if endpoint != nil && endpoint.AdvertiseAddress != "" {
|
||||
return endpoint.AdvertiseAddress
|
||||
}
|
||||
|
||||
return "127.0.0.1"
|
||||
}
|
||||
|
||||
// GetControllerManagerProbeAddress returns the kubernetes controller manager probe address
|
||||
func GetControllerManagerProbeAddress(cfg *kubeadmapi.ClusterConfiguration) string {
|
||||
if addr, exists := cfg.ControllerManager.ExtraArgs[kubeControllerManagerAddressArg]; exists {
|
||||
return addr
|
||||
}
|
||||
return "127.0.0.1"
|
||||
}
|
||||
|
||||
// GetSchedulerProbeAddress returns the kubernetes scheduler probe address
|
||||
func GetSchedulerProbeAddress(cfg *kubeadmapi.ClusterConfiguration) string {
|
||||
if addr, exists := cfg.Scheduler.ExtraArgs[kubeSchedulerAddressArg]; exists {
|
||||
return addr
|
||||
}
|
||||
return "127.0.0.1"
|
||||
}
|
||||
|
||||
// GetEtcdProbeAddress returns the etcd probe address
|
||||
func GetEtcdProbeAddress(cfg *kubeadmapi.Etcd) string {
|
||||
if cfg.Local != nil && cfg.Local.ExtraArgs != nil {
|
||||
if arg, exists := cfg.Local.ExtraArgs[etcdListenClientURLsArg]; exists {
|
||||
// Use the first url in the listen-client-urls if multiple url's are specified.
|
||||
if strings.ContainsAny(arg, ",") {
|
||||
arg = strings.Split(arg, ",")[0]
|
||||
}
|
||||
parsedURL, err := url.Parse(arg)
|
||||
if err != nil || parsedURL.Hostname() == "" {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
// Return the IP if the URL contains an address instead of a name.
|
||||
if ip := net.ParseIP(parsedURL.Hostname()); ip != nil {
|
||||
// etcdctl doesn't support auto-converting zero addresses into loopback addresses
|
||||
if ip.Equal(net.IPv4zero) {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
parsedURL, err := url.Parse(arg)
|
||||
if err != nil || parsedURL.Hostname() == "" {
|
||||
break
|
||||
}
|
||||
// Return the IP if the URL contains an address instead of a name.
|
||||
if ip := net.ParseIP(parsedURL.Hostname()); ip != nil {
|
||||
// etcdctl doesn't support auto-converting zero addresses into loopback addresses
|
||||
if ip.Equal(net.IPv4zero) {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
if ip.Equal(net.IPv6zero) {
|
||||
return net.IPv6loopback.String()
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
// Use the local resolver to try resolving the name within the URL.
|
||||
// If the name can not be resolved, return an IPv4 loopback address.
|
||||
// Otherwise, select the first valid IPv4 address.
|
||||
// If the name does not resolve to an IPv4 address, select the first valid IPv6 address.
|
||||
addrs, err := net.LookupIP(parsedURL.Hostname())
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
var ip net.IP
|
||||
for _, addr := range addrs {
|
||||
if addr.To4() != nil {
|
||||
ip = addr
|
||||
break
|
||||
}
|
||||
if addr.To16() != nil && ip == nil {
|
||||
ip = addr
|
||||
}
|
||||
if ip.Equal(net.IPv6zero) {
|
||||
return net.IPv6loopback.String()
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
// Use the local resolver to try resolving the name within the URL.
|
||||
// If the name can not be resolved, return an IPv4 loopback address.
|
||||
// Otherwise, select the first valid IPv4 address.
|
||||
// If the name does not resolve to an IPv4 address, select the first valid IPv6 address.
|
||||
addrs, err := net.LookupIP(parsedURL.Hostname())
|
||||
if err != nil {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
var ip net.IP
|
||||
for _, addr := range addrs {
|
||||
if addr.To4() != nil {
|
||||
ip = addr
|
||||
break
|
||||
}
|
||||
if addr.To16() != nil && ip == nil {
|
||||
ip = addr
|
||||
}
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
}
|
||||
return "127.0.0.1"
|
||||
|
@@ -27,9 +27,7 @@ import (
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||
)
|
||||
|
||||
@@ -42,151 +40,73 @@ func TestComponentResources(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestComponentProbe(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
cfg *kubeadmapi.InitConfiguration
|
||||
component string
|
||||
port int
|
||||
path string
|
||||
scheme v1.URIScheme
|
||||
expected string
|
||||
func TestGetAPIServerProbeAddress(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
endpoint *kubeadmapi.APIEndpoint
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "default apiserver advertise address with http",
|
||||
cfg: &kubeadmapi.InitConfiguration{
|
||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
||||
AdvertiseAddress: "",
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.KubeAPIServer,
|
||||
port: 1,
|
||||
path: "foo",
|
||||
scheme: v1.URISchemeHTTP,
|
||||
expected: "127.0.0.1",
|
||||
desc: "nil endpoint returns 127.0.0.1",
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
name: "default apiserver advertise address with https",
|
||||
cfg: &kubeadmapi.InitConfiguration{
|
||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
||||
AdvertiseAddress: "",
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.KubeAPIServer,
|
||||
port: 2,
|
||||
path: "bar",
|
||||
scheme: v1.URISchemeHTTPS,
|
||||
expected: "127.0.0.1",
|
||||
desc: "empty AdvertiseAddress endpoint returns 127.0.0.1",
|
||||
endpoint: &kubeadmapi.APIEndpoint{},
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
name: "valid ipv4 apiserver advertise address with http",
|
||||
cfg: &kubeadmapi.InitConfiguration{
|
||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
||||
AdvertiseAddress: "1.2.3.4",
|
||||
},
|
||||
desc: "filled in AdvertiseAddress endpoint returns it",
|
||||
endpoint: &kubeadmapi.APIEndpoint{
|
||||
AdvertiseAddress: "10.10.10.10",
|
||||
},
|
||||
component: kubeadmconstants.KubeAPIServer,
|
||||
port: 1,
|
||||
path: "foo",
|
||||
scheme: v1.URISchemeHTTP,
|
||||
expected: "1.2.3.4",
|
||||
},
|
||||
{
|
||||
name: "valid ipv6 apiserver advertise address with http",
|
||||
cfg: &kubeadmapi.InitConfiguration{
|
||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
||||
AdvertiseAddress: "2001:db8::1",
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.KubeAPIServer,
|
||||
port: 1,
|
||||
path: "foo",
|
||||
scheme: v1.URISchemeHTTP,
|
||||
expected: "2001:db8::1",
|
||||
},
|
||||
{
|
||||
name: "valid IPv4 controller-manager probe",
|
||||
cfg: &kubeadmapi.InitConfiguration{
|
||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
||||
ControllerManager: kubeadmapi.ControlPlaneComponent{
|
||||
ExtraArgs: map[string]string{"address": "1.2.3.4"},
|
||||
},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.KubeControllerManager,
|
||||
port: 1,
|
||||
path: "foo",
|
||||
scheme: v1.URISchemeHTTP,
|
||||
expected: "1.2.3.4",
|
||||
},
|
||||
{
|
||||
name: "valid IPv6 controller-manager probe",
|
||||
cfg: &kubeadmapi.InitConfiguration{
|
||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
||||
ControllerManager: kubeadmapi.ControlPlaneComponent{
|
||||
ExtraArgs: map[string]string{"address": "2001:db8::1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.KubeControllerManager,
|
||||
port: 1,
|
||||
path: "foo",
|
||||
scheme: v1.URISchemeHTTP,
|
||||
expected: "2001:db8::1",
|
||||
},
|
||||
{
|
||||
name: "valid IPv4 scheduler probe",
|
||||
cfg: &kubeadmapi.InitConfiguration{
|
||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
||||
Scheduler: kubeadmapi.ControlPlaneComponent{
|
||||
ExtraArgs: map[string]string{"address": "1.2.3.4"},
|
||||
},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.KubeScheduler,
|
||||
port: 1,
|
||||
path: "foo",
|
||||
scheme: v1.URISchemeHTTP,
|
||||
expected: "1.2.3.4",
|
||||
},
|
||||
{
|
||||
name: "valid IPv6 scheduler probe",
|
||||
cfg: &kubeadmapi.InitConfiguration{
|
||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
||||
Scheduler: kubeadmapi.ControlPlaneComponent{
|
||||
ExtraArgs: map[string]string{"address": "2001:db8::1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.KubeScheduler,
|
||||
port: 1,
|
||||
path: "foo",
|
||||
scheme: v1.URISchemeHTTP,
|
||||
expected: "2001:db8::1",
|
||||
expected: "10.10.10.10",
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
t.Run(rt.name, func(t *testing.T) {
|
||||
actual := ComponentProbe(rt.cfg, rt.component, rt.port, rt.path, rt.scheme)
|
||||
if actual.Handler.HTTPGet.Host != rt.expected {
|
||||
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
|
||||
rt.name, rt.expected,
|
||||
actual.Handler.HTTPGet.Host)
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
actual := GetAPIServerProbeAddress(test.endpoint)
|
||||
if actual != test.expected {
|
||||
t.Errorf("Unexpected result from GetAPIServerProbeAddress:\n\texpected: %s\n\tactual: %s", test.expected, actual)
|
||||
}
|
||||
if actual.Handler.HTTPGet.Port != intstr.FromInt(rt.port) {
|
||||
t.Errorf("%s test case failed:\n\texpected: %v\n\t actual: %v",
|
||||
rt.name, rt.port,
|
||||
actual.Handler.HTTPGet.Port)
|
||||
}
|
||||
if actual.Handler.HTTPGet.Path != rt.path {
|
||||
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
|
||||
rt.name, rt.path,
|
||||
actual.Handler.HTTPGet.Path)
|
||||
}
|
||||
if actual.Handler.HTTPGet.Scheme != rt.scheme {
|
||||
t.Errorf("%s test case failed:\n\texpected: %v\n\t actual: %v",
|
||||
rt.name, rt.scheme,
|
||||
actual.Handler.HTTPGet.Scheme)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetControllerManagerProbeAddress(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
cfg *kubeadmapi.ClusterConfiguration
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "no controller manager extra args leads to 127.0.0.1 being used",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
ControllerManager: kubeadmapi.ControlPlaneComponent{
|
||||
ExtraArgs: map[string]string{},
|
||||
},
|
||||
},
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
desc: "setting controller manager extra address arg to something acknowledges it",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
ControllerManager: kubeadmapi.ControlPlaneComponent{
|
||||
ExtraArgs: map[string]string{
|
||||
kubeControllerManagerAddressArg: "10.10.10.10",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "10.10.10.10",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
actual := GetControllerManagerProbeAddress(test.cfg)
|
||||
if actual != test.expected {
|
||||
t.Errorf("Unexpected result from GetControllerManagerProbeAddress:\n\texpected: %s\n\tactual: %s", test.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -194,150 +114,124 @@ func TestComponentProbe(t *testing.T) {
|
||||
|
||||
func TestEtcdProbe(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
cfg *kubeadmapi.ClusterConfiguration
|
||||
component string
|
||||
port int
|
||||
certsDir string
|
||||
cacert string
|
||||
cert string
|
||||
key string
|
||||
expected string
|
||||
name string
|
||||
cfg *kubeadmapi.Etcd
|
||||
port int
|
||||
certsDir string
|
||||
cacert string
|
||||
cert string
|
||||
key string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls IPv4 addresses",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
Etcd: kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
||||
},
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.Etcd,
|
||||
port: 1,
|
||||
certsDir: "secretsA",
|
||||
cacert: "ca1",
|
||||
cert: "cert1",
|
||||
key: "key1",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
||||
port: 1,
|
||||
certsDir: "secretsA",
|
||||
cacert: "ca1",
|
||||
cert: "cert1",
|
||||
key: "key1",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
Etcd: kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[0:0:0:0:0:0:0:0]:2379"},
|
||||
},
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[0:0:0:0:0:0:0:0]:2379"},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.Etcd,
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 2",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
Etcd: kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[::0:0]:2379"},
|
||||
},
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[::0:0]:2379"},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.Etcd,
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 3",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
Etcd: kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[::]:2379"},
|
||||
},
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[::]:2379"},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.Etcd,
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls unspecified IPv4 address",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
Etcd: kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
||||
},
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.Etcd,
|
||||
port: 1,
|
||||
certsDir: "secretsA",
|
||||
cacert: "ca1",
|
||||
cert: "cert1",
|
||||
key: "key1",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
||||
port: 1,
|
||||
certsDir: "secretsA",
|
||||
cacert: "ca1",
|
||||
cert: "cert1",
|
||||
key: "key1",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
||||
},
|
||||
{
|
||||
name: "valid etcd probe using listen-client-urls IPv6 addresses",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
Etcd: kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[2001:db8::1]:2379,http://[2001:db8::2]:2379"},
|
||||
},
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://[2001:db8::1]:2379,http://[2001:db8::2]:2379"},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.Etcd,
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[2001:db8::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
port: 1,
|
||||
certsDir: "secretsB",
|
||||
cacert: "ca2",
|
||||
cert: "cert2",
|
||||
key: "key2",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[2001:db8::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||
},
|
||||
{
|
||||
name: "valid IPv4 etcd probe using hostname for listen-client-urls",
|
||||
cfg: &kubeadmapi.ClusterConfiguration{
|
||||
Etcd: kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://localhost:2379"},
|
||||
},
|
||||
cfg: &kubeadmapi.Etcd{
|
||||
Local: &kubeadmapi.LocalEtcd{
|
||||
ExtraArgs: map[string]string{
|
||||
"listen-client-urls": "http://localhost:2379"},
|
||||
},
|
||||
},
|
||||
component: kubeadmconstants.Etcd,
|
||||
port: 1,
|
||||
certsDir: "secretsC",
|
||||
cacert: "ca3",
|
||||
cert: "cert3",
|
||||
key: "key3",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[127.0.0.1]:1 --cacert=secretsC/ca3 --cert=secretsC/cert3 --key=secretsC/key3 get foo",
|
||||
port: 1,
|
||||
certsDir: "secretsC",
|
||||
cacert: "ca3",
|
||||
cert: "cert3",
|
||||
key: "key3",
|
||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[127.0.0.1]:1 --cacert=secretsC/ca3 --cert=secretsC/cert3 --key=secretsC/key3 get foo",
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
t.Run(rt.name, func(t *testing.T) {
|
||||
// TODO: Make EtcdProbe accept a ClusterConfiguration object instead of InitConfiguration
|
||||
initcfg := &kubeadmapi.InitConfiguration{
|
||||
ClusterConfiguration: *rt.cfg,
|
||||
}
|
||||
actual := EtcdProbe(initcfg, rt.component, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key)
|
||||
actual := EtcdProbe(rt.cfg, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key)
|
||||
if actual.Handler.Exec.Command[2] != rt.expected {
|
||||
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
|
||||
rt.name, rt.expected,
|
||||
|
Reference in New Issue
Block a user