...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/util/endpoint_test.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/util

     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 util
    18  
    19  import (
    20  	"testing"
    21  
    22  	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
    23  )
    24  
    25  func TestGetControlPlaneEndpoint(t *testing.T) {
    26  	var tests = []struct {
    27  		name             string
    28  		cfg              *kubeadmapi.InitConfiguration
    29  		expectedEndpoint string
    30  		expectedError    bool
    31  	}{
    32  		{
    33  			name: "use ControlPlaneEndpoint (dns) if fully defined",
    34  			cfg: &kubeadmapi.InitConfiguration{
    35  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
    36  					BindPort:         4567,
    37  					AdvertiseAddress: "4.5.6.7",
    38  				},
    39  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
    40  					ControlPlaneEndpoint: "cp.k8s.io:1234",
    41  				},
    42  			},
    43  			expectedEndpoint: "https://cp.k8s.io:1234",
    44  		},
    45  		{
    46  			name: "use ControlPlaneEndpoint (ipv4) if fully defined",
    47  			cfg: &kubeadmapi.InitConfiguration{
    48  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
    49  					BindPort:         4567,
    50  					AdvertiseAddress: "4.5.6.7",
    51  				},
    52  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
    53  					ControlPlaneEndpoint: "1.2.3.4:1234",
    54  				},
    55  			},
    56  			expectedEndpoint: "https://1.2.3.4:1234",
    57  		},
    58  		{
    59  			name: "use ControlPlaneEndpoint (ipv6) if fully defined",
    60  			cfg: &kubeadmapi.InitConfiguration{
    61  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
    62  					BindPort:         4567,
    63  					AdvertiseAddress: "4.5.6.7",
    64  				},
    65  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
    66  					ControlPlaneEndpoint: "[2001:db8::1]:1234",
    67  				},
    68  			},
    69  			expectedEndpoint: "https://[2001:db8::1]:1234",
    70  		},
    71  		{
    72  			name: "use ControlPlaneEndpoint (dns) + BindPort if ControlPlaneEndpoint defined without port",
    73  			cfg: &kubeadmapi.InitConfiguration{
    74  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
    75  					BindPort:         4567,
    76  					AdvertiseAddress: "4.5.6.7",
    77  				},
    78  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
    79  
    80  					ControlPlaneEndpoint: "cp.k8s.io",
    81  				},
    82  			},
    83  			expectedEndpoint: "https://cp.k8s.io:4567",
    84  		},
    85  		{
    86  			name: "use ControlPlaneEndpoint (ipv4) + BindPort if ControlPlaneEndpoint defined without port",
    87  			cfg: &kubeadmapi.InitConfiguration{
    88  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
    89  					BindPort:         4567,
    90  					AdvertiseAddress: "4.5.6.7",
    91  				},
    92  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
    93  					ControlPlaneEndpoint: "1.2.3.4",
    94  				},
    95  			},
    96  			expectedEndpoint: "https://1.2.3.4:4567",
    97  		},
    98  		{
    99  			name: "use ControlPlaneEndpoint (ipv6) + BindPort if ControlPlaneEndpoint defined without port",
   100  			cfg: &kubeadmapi.InitConfiguration{
   101  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
   102  					BindPort:         4567,
   103  					AdvertiseAddress: "4.5.6.7",
   104  				},
   105  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
   106  
   107  					ControlPlaneEndpoint: "2001:db8::1",
   108  				},
   109  			},
   110  			expectedEndpoint: "https://[2001:db8::1]:4567",
   111  		},
   112  		{
   113  			name: "use AdvertiseAddress (ipv4) + BindPort if ControlPlaneEndpoint is not defined",
   114  			cfg: &kubeadmapi.InitConfiguration{
   115  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
   116  					BindPort:         4567,
   117  					AdvertiseAddress: "4.5.6.7",
   118  				},
   119  			},
   120  			expectedEndpoint: "https://4.5.6.7:4567",
   121  		},
   122  		{
   123  			name: "use AdvertiseAddress (ipv6) + BindPort if ControlPlaneEndpoint is not defined",
   124  			cfg: &kubeadmapi.InitConfiguration{
   125  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
   126  					BindPort:         4567,
   127  					AdvertiseAddress: "2001:db8::1",
   128  				},
   129  			},
   130  			expectedEndpoint: "https://[2001:db8::1]:4567",
   131  		},
   132  		{
   133  			name: "fail if invalid BindPort",
   134  			cfg: &kubeadmapi.InitConfiguration{
   135  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
   136  					BindPort: 0,
   137  				},
   138  			},
   139  			expectedError: true,
   140  		},
   141  		{
   142  			name: "fail if invalid ControlPlaneEndpoint (dns)",
   143  			cfg: &kubeadmapi.InitConfiguration{
   144  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
   145  					ControlPlaneEndpoint: "bad!!.cp.k8s.io",
   146  				},
   147  			},
   148  			expectedError: true,
   149  		},
   150  		{
   151  			name: "fail if invalid ControlPlaneEndpoint (ip4)",
   152  			cfg: &kubeadmapi.InitConfiguration{
   153  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
   154  					ControlPlaneEndpoint: "1..0",
   155  				},
   156  			},
   157  			expectedError: true,
   158  		},
   159  		{
   160  			name: "fail if invalid ControlPlaneEndpoint (ip6)",
   161  			cfg: &kubeadmapi.InitConfiguration{
   162  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
   163  					ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313",
   164  				},
   165  			},
   166  			expectedError: true,
   167  		},
   168  		{
   169  			name: "fail if invalid ControlPlaneEndpoint (port)",
   170  			cfg: &kubeadmapi.InitConfiguration{
   171  				ClusterConfiguration: kubeadmapi.ClusterConfiguration{
   172  					ControlPlaneEndpoint: "cp.k8s.io:0",
   173  				},
   174  			},
   175  			expectedError: true,
   176  		},
   177  		{
   178  			name: "fail if invalid AdvertiseAddress (ip4)",
   179  			cfg: &kubeadmapi.InitConfiguration{
   180  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
   181  					AdvertiseAddress: "1..0",
   182  					BindPort:         4567,
   183  				},
   184  			},
   185  			expectedError: true,
   186  		},
   187  		{
   188  			name: "fail if invalid AdvertiseAddress (ip6)",
   189  			cfg: &kubeadmapi.InitConfiguration{
   190  				LocalAPIEndpoint: kubeadmapi.APIEndpoint{
   191  					AdvertiseAddress: "1200::AB00:1234::2552:7777:1313",
   192  					BindPort:         4567,
   193  				},
   194  			},
   195  			expectedError: true,
   196  		},
   197  	}
   198  
   199  	for _, rt := range tests {
   200  		t.Run(rt.name, func(t *testing.T) {
   201  			actualEndpoint, actualError := GetControlPlaneEndpoint(rt.cfg.ControlPlaneEndpoint, &rt.cfg.LocalAPIEndpoint)
   202  
   203  			if (actualError != nil) && !rt.expectedError {
   204  				t.Errorf("%s unexpected failure: %v", rt.name, actualError)
   205  				return
   206  			} else if (actualError == nil) && rt.expectedError {
   207  				t.Errorf("%s passed when expected to fail", rt.name)
   208  				return
   209  			}
   210  
   211  			if actualEndpoint != rt.expectedEndpoint {
   212  				t.Errorf("%s returned invalid endpoint %s, expected %s", rt.name, actualEndpoint, rt.expectedEndpoint)
   213  			}
   214  		})
   215  	}
   216  }
   217  
   218  func TestParseHostPort(t *testing.T) {
   219  
   220  	var tests = []struct {
   221  		name          string
   222  		hostport      string
   223  		expectedHost  string
   224  		expectedPort  string
   225  		expectedError bool
   226  	}{
   227  		{
   228  			name:         "valid dns",
   229  			hostport:     "cp.k8s.io",
   230  			expectedHost: "cp.k8s.io",
   231  			expectedPort: "",
   232  		},
   233  		{
   234  			name:         "valid dns:port",
   235  			hostport:     "cp.k8s.io:1234",
   236  			expectedHost: "cp.k8s.io",
   237  			expectedPort: "1234",
   238  		},
   239  		{
   240  			name:         "valid ip4",
   241  			hostport:     "1.2.3.4",
   242  			expectedHost: "1.2.3.4",
   243  			expectedPort: "",
   244  		},
   245  		{
   246  			name:         "valid ipv4:port",
   247  			hostport:     "1.2.3.4:1234",
   248  			expectedHost: "1.2.3.4",
   249  			expectedPort: "1234",
   250  		},
   251  		{
   252  			name:         "valid ipv6",
   253  			hostport:     "2001:db8::1",
   254  			expectedHost: "2001:db8::1",
   255  			expectedPort: "",
   256  		},
   257  		{
   258  			name:         "valid ipv6:port",
   259  			hostport:     "[2001:db8::1]:1234",
   260  			expectedHost: "2001:db8::1",
   261  			expectedPort: "1234",
   262  		},
   263  		{
   264  			name:          "invalid port(not a number)",
   265  			hostport:      "cp.k8s.io:aaa",
   266  			expectedError: true,
   267  		},
   268  		{
   269  			name:          "invalid port(out of range, positive port number)",
   270  			hostport:      "cp.k8s.io:987654321",
   271  			expectedError: true,
   272  		},
   273  		{
   274  			name:          "invalid port(out of range, negative port number)",
   275  			hostport:      "cp.k8s.io:-987654321",
   276  			expectedError: true,
   277  		},
   278  		{
   279  			name:          "invalid port(out of range, negative port number)",
   280  			hostport:      "cp.k8s.io:123:123",
   281  			expectedError: true,
   282  		},
   283  		{
   284  			name:          "invalid dns",
   285  			hostport:      "bad!!cp.k8s.io",
   286  			expectedError: true,
   287  		},
   288  		{
   289  			name:          "invalid valid dns:port",
   290  			hostport:      "bad!!cp.k8s.io:1234",
   291  			expectedError: true,
   292  		},
   293  		{
   294  			name:         "invalid ip4, but valid DNS",
   295  			hostport:     "259.2.3.4",
   296  			expectedHost: "259.2.3.4",
   297  		},
   298  		{
   299  			name:          "invalid ip4",
   300  			hostport:      "1..3.4",
   301  			expectedError: true,
   302  		},
   303  		{
   304  			name:          "invalid ip4(2):port",
   305  			hostport:      "1..3.4:1234",
   306  			expectedError: true,
   307  		},
   308  		{
   309  			name:          "invalid ipv6",
   310  			hostport:      "1200::AB00:1234::2552:7777:1313",
   311  			expectedError: true,
   312  		},
   313  		{
   314  			name:          "invalid ipv6:port",
   315  			hostport:      "[1200::AB00:1234::2552:7777:1313]:1234",
   316  			expectedError: true,
   317  		},
   318  	}
   319  
   320  	for _, rt := range tests {
   321  		t.Run(rt.name, func(t *testing.T) {
   322  			actualHost, actualPort, actualError := ParseHostPort(rt.hostport)
   323  
   324  			if (actualError != nil) && !rt.expectedError {
   325  				t.Errorf("%s unexpected failure: %v", rt.name, actualError)
   326  				return
   327  			} else if (actualError == nil) && rt.expectedError {
   328  				t.Errorf("%s passed when expected to fail", rt.name)
   329  				return
   330  			}
   331  
   332  			if actualHost != rt.expectedHost {
   333  				t.Errorf("%s returned invalid host %s, expected %s", rt.name, actualHost, rt.expectedHost)
   334  				return
   335  			}
   336  
   337  			if actualPort != rt.expectedPort {
   338  				t.Errorf("%s returned invalid port %s, expected %s", rt.name, actualPort, rt.expectedPort)
   339  			}
   340  		})
   341  	}
   342  }
   343  
   344  func TestParsePort(t *testing.T) {
   345  
   346  	var tests = []struct {
   347  		name          string
   348  		port          string
   349  		expectedPort  int
   350  		expectedError bool
   351  	}{
   352  		{
   353  			name:         "valid port",
   354  			port:         "1234",
   355  			expectedPort: 1234,
   356  		},
   357  		{
   358  			name:          "invalid port (not a number)",
   359  			port:          "a",
   360  			expectedError: true,
   361  		},
   362  		{
   363  			name:          "invalid port (<1)",
   364  			port:          "-10",
   365  			expectedError: true,
   366  		},
   367  		{
   368  			name:          "invalid port (>65535)",
   369  			port:          "66535",
   370  			expectedError: true,
   371  		},
   372  	}
   373  
   374  	for _, rt := range tests {
   375  		t.Run(rt.name, func(t *testing.T) {
   376  			actualPort, actualError := ParsePort(rt.port)
   377  
   378  			if (actualError != nil) && !rt.expectedError {
   379  				t.Errorf("%s unexpected failure: %v", rt.name, actualError)
   380  				return
   381  			} else if (actualError == nil) && rt.expectedError {
   382  				t.Errorf("%s passed when expected to fail", rt.name)
   383  				return
   384  			}
   385  
   386  			if actualPort != rt.expectedPort {
   387  				t.Errorf("%s returned invalid port %d, expected %d", rt.name, actualPort, rt.expectedPort)
   388  			}
   389  		})
   390  	}
   391  }
   392  

View as plain text