1package k8s_test 2 3import ( 4 "log" 5 "os" 6 "path/filepath" 7 "reflect" 8 "testing" 9 10 discover "github.com/hashicorp/go-discover" 11 "github.com/hashicorp/go-discover/provider/k8s" 12 corev1 "k8s.io/api/core/v1" 13 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14) 15 16var _ discover.Provider = (*k8s.Provider)(nil) 17 18// Acceptance test against a real cluster 19func TestAcc(t *testing.T) { 20 path := "../../test/tf/k8s/kubeconfig.yaml" 21 path, err := filepath.Abs(path) 22 if err != nil { 23 t.Fatalf("err: %s", err) 24 } 25 26 if _, err := os.Stat(path); err != nil { 27 t.Skipf("Skipping, can't find %q: %s", path, err) 28 return 29 } 30 31 args := discover.Config{ 32 "provider": "k8s", 33 "kubeconfig": path, 34 "label_selector": "app = valid", 35 } 36 37 l := log.New(os.Stderr, "", log.LstdFlags) 38 p := &k8s.Provider{} 39 addrs, err := p.Addrs(args, l) 40 if err != nil { 41 t.Fatal(err) 42 } 43 t.Logf("Addrs: %v", addrs) 44 if len(addrs) != 3 { 45 t.Fatalf("bad: %v", addrs) 46 } 47} 48 49func TestPodAddrs(t *testing.T) { 50 cases := []struct { 51 Name string 52 Args map[string]string 53 Pods []corev1.Pod 54 Expected []string 55 }{ 56 { 57 "Simple pods (no ready, no annotations, etc.)", 58 nil, 59 []corev1.Pod{ 60 corev1.Pod{ 61 Status: corev1.PodStatus{ 62 Phase: corev1.PodRunning, 63 PodIP: "1.2.3.4", 64 HostIP: "2.3.4.5", 65 }, 66 }, 67 }, 68 []string{"1.2.3.4"}, 69 }, 70 71 { 72 "Simple pods host network", 73 map[string]string{"host_network": "true"}, 74 []corev1.Pod{ 75 corev1.Pod{ 76 Status: corev1.PodStatus{ 77 Phase: corev1.PodRunning, 78 PodIP: "1.2.3.4", 79 HostIP: "2.3.4.5", 80 }, 81 }, 82 }, 83 []string{"2.3.4.5"}, 84 }, 85 86 { 87 "Only running pods", 88 nil, 89 []corev1.Pod{ 90 corev1.Pod{ 91 Status: corev1.PodStatus{ 92 Phase: corev1.PodPending, 93 PodIP: "2.3.4.5", 94 }, 95 }, 96 97 corev1.Pod{ 98 Status: corev1.PodStatus{ 99 Phase: corev1.PodRunning, 100 PodIP: "1.2.3.4", 101 }, 102 }, 103 }, 104 []string{"1.2.3.4"}, 105 }, 106 107 { 108 "Only pods that are ready", 109 nil, 110 []corev1.Pod{ 111 corev1.Pod{ 112 Status: corev1.PodStatus{ 113 Phase: corev1.PodPending, 114 PodIP: "2.3.4.5", 115 }, 116 }, 117 118 corev1.Pod{ 119 Status: corev1.PodStatus{ 120 Phase: corev1.PodRunning, 121 PodIP: "ready", 122 Conditions: []corev1.PodCondition{ 123 corev1.PodCondition{ 124 Type: corev1.PodReady, 125 Status: corev1.ConditionTrue, 126 }, 127 }, 128 }, 129 }, 130 131 // Not true 132 corev1.Pod{ 133 Status: corev1.PodStatus{ 134 Phase: corev1.PodRunning, 135 PodIP: "not-ready", 136 Conditions: []corev1.PodCondition{ 137 corev1.PodCondition{ 138 Type: corev1.PodReady, 139 Status: corev1.ConditionUnknown, 140 }, 141 }, 142 }, 143 }, 144 145 // Not ready type, ignored 146 corev1.Pod{ 147 Status: corev1.PodStatus{ 148 Phase: corev1.PodRunning, 149 PodIP: "scheduled", 150 Conditions: []corev1.PodCondition{ 151 corev1.PodCondition{ 152 Type: corev1.PodScheduled, 153 Status: corev1.ConditionUnknown, 154 }, 155 }, 156 }, 157 }, 158 }, 159 []string{"ready", "scheduled"}, 160 }, 161 162 { 163 "Port annotation (named)", 164 nil, 165 []corev1.Pod{ 166 corev1.Pod{ 167 Status: corev1.PodStatus{ 168 Phase: corev1.PodRunning, 169 PodIP: "1.2.3.4", 170 }, 171 172 Spec: corev1.PodSpec{ 173 Containers: []corev1.Container{ 174 corev1.Container{ 175 Ports: []corev1.ContainerPort{ 176 corev1.ContainerPort{ 177 Name: "my-port", 178 HostPort: 1234, 179 ContainerPort: 8500, 180 }, 181 182 corev1.ContainerPort{ 183 Name: "http", 184 HostPort: 80, 185 ContainerPort: 8080, 186 }, 187 }, 188 }, 189 }, 190 }, 191 192 ObjectMeta: metav1.ObjectMeta{ 193 Annotations: map[string]string{ 194 k8s.AnnotationKeyPort: "my-port", 195 }, 196 }, 197 }, 198 }, 199 []string{"1.2.3.4:8500"}, 200 }, 201 202 { 203 "Port annotation (named with host network)", 204 map[string]string{"host_network": "true"}, 205 []corev1.Pod{ 206 corev1.Pod{ 207 Status: corev1.PodStatus{ 208 Phase: corev1.PodRunning, 209 PodIP: "1.2.3.4", 210 HostIP: "2.3.4.5", 211 }, 212 213 Spec: corev1.PodSpec{ 214 Containers: []corev1.Container{ 215 corev1.Container{ 216 Ports: []corev1.ContainerPort{ 217 corev1.ContainerPort{ 218 Name: "http", 219 HostPort: 80, 220 ContainerPort: 8080, 221 }, 222 }, 223 }, 224 }, 225 }, 226 227 ObjectMeta: metav1.ObjectMeta{ 228 Annotations: map[string]string{ 229 k8s.AnnotationKeyPort: "http", 230 }, 231 }, 232 }, 233 }, 234 []string{"2.3.4.5:80"}, 235 }, 236 237 { 238 "Port annotation (direct)", 239 nil, 240 []corev1.Pod{ 241 corev1.Pod{ 242 Status: corev1.PodStatus{ 243 Phase: corev1.PodRunning, 244 PodIP: "1.2.3.4", 245 }, 246 247 Spec: corev1.PodSpec{ 248 Containers: []corev1.Container{ 249 corev1.Container{ 250 Ports: []corev1.ContainerPort{ 251 corev1.ContainerPort{ 252 Name: "http", 253 HostPort: 80, 254 ContainerPort: 8080, 255 }, 256 }, 257 }, 258 }, 259 }, 260 261 ObjectMeta: metav1.ObjectMeta{ 262 Annotations: map[string]string{ 263 k8s.AnnotationKeyPort: "4600", 264 }, 265 }, 266 }, 267 }, 268 []string{"1.2.3.4:4600"}, 269 }, 270 271 { 272 "Port annotation (direct with host network)", 273 map[string]string{"host_network": "true"}, 274 []corev1.Pod{ 275 corev1.Pod{ 276 Status: corev1.PodStatus{ 277 Phase: corev1.PodRunning, 278 PodIP: "1.2.3.4", 279 HostIP: "2.3.4.5", 280 }, 281 282 Spec: corev1.PodSpec{ 283 Containers: []corev1.Container{ 284 corev1.Container{ 285 Ports: []corev1.ContainerPort{ 286 corev1.ContainerPort{ 287 Name: "http", 288 HostPort: 80, 289 ContainerPort: 8080, 290 }, 291 }, 292 }, 293 }, 294 }, 295 296 ObjectMeta: metav1.ObjectMeta{ 297 Annotations: map[string]string{ 298 k8s.AnnotationKeyPort: "4600", 299 }, 300 }, 301 }, 302 }, 303 []string{"2.3.4.5:4600"}, 304 }, 305 } 306 307 for _, tt := range cases { 308 t.Run(tt.Name, func(t *testing.T) { 309 l := log.New(os.Stderr, "", log.LstdFlags) 310 addrs, err := k8s.PodAddrs(&corev1.PodList{Items: tt.Pods}, tt.Args, l) 311 if err != nil { 312 t.Fatalf("err: %s", err) 313 } 314 315 if !reflect.DeepEqual(addrs, tt.Expected) { 316 t.Fatalf("bad: %#v", addrs) 317 } 318 }) 319 } 320} 321