mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			392 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			392 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2017 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 util
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 
 | |
| 	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
 | |
| )
 | |
| 
 | |
| func TestGetControlPlaneEndpoint(t *testing.T) {
 | |
| 	var tests = []struct {
 | |
| 		name             string
 | |
| 		cfg              *kubeadmapi.InitConfiguration
 | |
| 		expectedEndpoint string
 | |
| 		expectedError    bool
 | |
| 	}{
 | |
| 		{
 | |
| 			name: "use ControlPlaneEndpoint (dns) if fully defined",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort:         4567,
 | |
| 					AdvertiseAddress: "4.5.6.7",
 | |
| 				},
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 					ControlPlaneEndpoint: "cp.k8s.io:1234",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedEndpoint: "https://cp.k8s.io:1234",
 | |
| 		},
 | |
| 		{
 | |
| 			name: "use ControlPlaneEndpoint (ipv4) if fully defined",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort:         4567,
 | |
| 					AdvertiseAddress: "4.5.6.7",
 | |
| 				},
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 					ControlPlaneEndpoint: "1.2.3.4:1234",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedEndpoint: "https://1.2.3.4:1234",
 | |
| 		},
 | |
| 		{
 | |
| 			name: "use ControlPlaneEndpoint (ipv6) if fully defined",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort:         4567,
 | |
| 					AdvertiseAddress: "4.5.6.7",
 | |
| 				},
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 					ControlPlaneEndpoint: "[2001:db8::1]:1234",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedEndpoint: "https://[2001:db8::1]:1234",
 | |
| 		},
 | |
| 		{
 | |
| 			name: "use ControlPlaneEndpoint (dns) + BindPort if ControlPlaneEndpoint defined without port",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort:         4567,
 | |
| 					AdvertiseAddress: "4.5.6.7",
 | |
| 				},
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 
 | |
| 					ControlPlaneEndpoint: "cp.k8s.io",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedEndpoint: "https://cp.k8s.io:4567",
 | |
| 		},
 | |
| 		{
 | |
| 			name: "use ControlPlaneEndpoint (ipv4) + BindPort if ControlPlaneEndpoint defined without port",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort:         4567,
 | |
| 					AdvertiseAddress: "4.5.6.7",
 | |
| 				},
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 					ControlPlaneEndpoint: "1.2.3.4",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedEndpoint: "https://1.2.3.4:4567",
 | |
| 		},
 | |
| 		{
 | |
| 			name: "use ControlPlaneEndpoint (ipv6) + BindPort if ControlPlaneEndpoint defined without port",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort:         4567,
 | |
| 					AdvertiseAddress: "4.5.6.7",
 | |
| 				},
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 
 | |
| 					ControlPlaneEndpoint: "2001:db8::1",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedEndpoint: "https://[2001:db8::1]:4567",
 | |
| 		},
 | |
| 		{
 | |
| 			name: "use AdvertiseAddress (ipv4) + BindPort if ControlPlaneEndpoint is not defined",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort:         4567,
 | |
| 					AdvertiseAddress: "4.5.6.7",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedEndpoint: "https://4.5.6.7:4567",
 | |
| 		},
 | |
| 		{
 | |
| 			name: "use AdvertiseAddress (ipv6) + BindPort if ControlPlaneEndpoint is not defined",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort:         4567,
 | |
| 					AdvertiseAddress: "2001:db8::1",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedEndpoint: "https://[2001:db8::1]:4567",
 | |
| 		},
 | |
| 		{
 | |
| 			name: "fail if invalid BindPort",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					BindPort: 0,
 | |
| 				},
 | |
| 			},
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name: "fail if invalid ControlPlaneEndpoint (dns)",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 					ControlPlaneEndpoint: "bad!!.cp.k8s.io",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name: "fail if invalid ControlPlaneEndpoint (ip4)",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 					ControlPlaneEndpoint: "1..0",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name: "fail if invalid ControlPlaneEndpoint (ip6)",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 					ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name: "fail if invalid ControlPlaneEndpoint (port)",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
 | |
| 					ControlPlaneEndpoint: "cp.k8s.io:0",
 | |
| 				},
 | |
| 			},
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name: "fail if invalid AdvertiseAddress (ip4)",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					AdvertiseAddress: "1..0",
 | |
| 					BindPort:         4567,
 | |
| 				},
 | |
| 			},
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name: "fail if invalid AdvertiseAddress (ip6)",
 | |
| 			cfg: &kubeadmapi.InitConfiguration{
 | |
| 				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
 | |
| 					AdvertiseAddress: "1200::AB00:1234::2552:7777:1313",
 | |
| 					BindPort:         4567,
 | |
| 				},
 | |
| 			},
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, rt := range tests {
 | |
| 		t.Run(rt.name, func(t *testing.T) {
 | |
| 			actualEndpoint, actualError := GetControlPlaneEndpoint(rt.cfg.ControlPlaneEndpoint, &rt.cfg.LocalAPIEndpoint)
 | |
| 
 | |
| 			if (actualError != nil) && !rt.expectedError {
 | |
| 				t.Errorf("%s unexpected failure: %v", rt.name, actualError)
 | |
| 				return
 | |
| 			} else if (actualError == nil) && rt.expectedError {
 | |
| 				t.Errorf("%s passed when expected to fail", rt.name)
 | |
| 				return
 | |
| 			}
 | |
| 
 | |
| 			if actualEndpoint != rt.expectedEndpoint {
 | |
| 				t.Errorf("%s returned invalid endpoint %s, expected %s", rt.name, actualEndpoint, rt.expectedEndpoint)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestParseHostPort(t *testing.T) {
 | |
| 
 | |
| 	var tests = []struct {
 | |
| 		name          string
 | |
| 		hostport      string
 | |
| 		expectedHost  string
 | |
| 		expectedPort  string
 | |
| 		expectedError bool
 | |
| 	}{
 | |
| 		{
 | |
| 			name:         "valid dns",
 | |
| 			hostport:     "cp.k8s.io",
 | |
| 			expectedHost: "cp.k8s.io",
 | |
| 			expectedPort: "",
 | |
| 		},
 | |
| 		{
 | |
| 			name:         "valid dns:port",
 | |
| 			hostport:     "cp.k8s.io:1234",
 | |
| 			expectedHost: "cp.k8s.io",
 | |
| 			expectedPort: "1234",
 | |
| 		},
 | |
| 		{
 | |
| 			name:         "valid ip4",
 | |
| 			hostport:     "1.2.3.4",
 | |
| 			expectedHost: "1.2.3.4",
 | |
| 			expectedPort: "",
 | |
| 		},
 | |
| 		{
 | |
| 			name:         "valid ipv4:port",
 | |
| 			hostport:     "1.2.3.4:1234",
 | |
| 			expectedHost: "1.2.3.4",
 | |
| 			expectedPort: "1234",
 | |
| 		},
 | |
| 		{
 | |
| 			name:         "valid ipv6",
 | |
| 			hostport:     "2001:db8::1",
 | |
| 			expectedHost: "2001:db8::1",
 | |
| 			expectedPort: "",
 | |
| 		},
 | |
| 		{
 | |
| 			name:         "valid ipv6:port",
 | |
| 			hostport:     "[2001:db8::1]:1234",
 | |
| 			expectedHost: "2001:db8::1",
 | |
| 			expectedPort: "1234",
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid port(not a number)",
 | |
| 			hostport:      "cp.k8s.io:aaa",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid port(out of range, positive port number)",
 | |
| 			hostport:      "cp.k8s.io:987654321",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid port(out of range, negative port number)",
 | |
| 			hostport:      "cp.k8s.io:-987654321",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid port(out of range, negative port number)",
 | |
| 			hostport:      "cp.k8s.io:123:123",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid dns",
 | |
| 			hostport:      "bad!!cp.k8s.io",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid valid dns:port",
 | |
| 			hostport:      "bad!!cp.k8s.io:1234",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:         "invalid ip4, but valid DNS",
 | |
| 			hostport:     "259.2.3.4",
 | |
| 			expectedHost: "259.2.3.4",
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid ip4",
 | |
| 			hostport:      "1..3.4",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid ip4(2):port",
 | |
| 			hostport:      "1..3.4:1234",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid ipv6",
 | |
| 			hostport:      "1200::AB00:1234::2552:7777:1313",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid ipv6:port",
 | |
| 			hostport:      "[1200::AB00:1234::2552:7777:1313]:1234",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, rt := range tests {
 | |
| 		t.Run(rt.name, func(t *testing.T) {
 | |
| 			actualHost, actualPort, actualError := ParseHostPort(rt.hostport)
 | |
| 
 | |
| 			if (actualError != nil) && !rt.expectedError {
 | |
| 				t.Errorf("%s unexpected failure: %v", rt.name, actualError)
 | |
| 				return
 | |
| 			} else if (actualError == nil) && rt.expectedError {
 | |
| 				t.Errorf("%s passed when expected to fail", rt.name)
 | |
| 				return
 | |
| 			}
 | |
| 
 | |
| 			if actualHost != rt.expectedHost {
 | |
| 				t.Errorf("%s returned invalid host %s, expected %s", rt.name, actualHost, rt.expectedHost)
 | |
| 				return
 | |
| 			}
 | |
| 
 | |
| 			if actualPort != rt.expectedPort {
 | |
| 				t.Errorf("%s returned invalid port %s, expected %s", rt.name, actualPort, rt.expectedPort)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestParsePort(t *testing.T) {
 | |
| 
 | |
| 	var tests = []struct {
 | |
| 		name          string
 | |
| 		port          string
 | |
| 		expectedPort  int
 | |
| 		expectedError bool
 | |
| 	}{
 | |
| 		{
 | |
| 			name:         "valid port",
 | |
| 			port:         "1234",
 | |
| 			expectedPort: 1234,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid port (not a number)",
 | |
| 			port:          "a",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid port (<1)",
 | |
| 			port:          "-10",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 		{
 | |
| 			name:          "invalid port (>65535)",
 | |
| 			port:          "66535",
 | |
| 			expectedError: true,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, rt := range tests {
 | |
| 		t.Run(rt.name, func(t *testing.T) {
 | |
| 			actualPort, actualError := ParsePort(rt.port)
 | |
| 
 | |
| 			if (actualError != nil) && !rt.expectedError {
 | |
| 				t.Errorf("%s unexpected failure: %v", rt.name, actualError)
 | |
| 				return
 | |
| 			} else if (actualError == nil) && rt.expectedError {
 | |
| 				t.Errorf("%s passed when expected to fail", rt.name)
 | |
| 				return
 | |
| 			}
 | |
| 
 | |
| 			if actualPort != rt.expectedPort {
 | |
| 				t.Errorf("%s returned invalid port %d, expected %d", rt.name, actualPort, rt.expectedPort)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 |