sigs.k8s.io/external-dns@v0.14.1/source/f5_virtualserver_test.go (about) 1 /* 2 Copyright 2022 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 source 18 19 import ( 20 "context" 21 "encoding/json" 22 "testing" 23 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 28 "k8s.io/apimachinery/pkg/runtime" 29 fakeDynamic "k8s.io/client-go/dynamic/fake" 30 fakeKube "k8s.io/client-go/kubernetes/fake" 31 "sigs.k8s.io/external-dns/endpoint" 32 33 f5 "github.com/F5Networks/k8s-bigip-ctlr/v2/config/apis/cis/v1" 34 ) 35 36 const defaultF5VirtualServerNamespace = "virtualserver" 37 38 func TestF5VirtualServerEndpoints(t *testing.T) { 39 t.Parallel() 40 41 tests := []struct { 42 name string 43 annotationFilter string 44 virtualServer f5.VirtualServer 45 expected []*endpoint.Endpoint 46 }{ 47 { 48 name: "F5 VirtualServer with target annotation", 49 annotationFilter: "", 50 virtualServer: f5.VirtualServer{ 51 TypeMeta: metav1.TypeMeta{ 52 APIVersion: f5VirtualServerGVR.GroupVersion().String(), 53 Kind: "VirtualServer", 54 }, 55 ObjectMeta: metav1.ObjectMeta{ 56 Name: "test-vs", 57 Namespace: defaultF5VirtualServerNamespace, 58 Annotations: map[string]string{ 59 targetAnnotationKey: "192.168.1.150", 60 }, 61 }, 62 Spec: f5.VirtualServerSpec{ 63 Host: "www.example.com", 64 VirtualServerAddress: "192.168.1.100", 65 }, 66 Status: f5.VirtualServerStatus{ 67 VSAddress: "192.168.1.200", 68 }, 69 }, 70 expected: []*endpoint.Endpoint{ 71 { 72 DNSName: "www.example.com", 73 Targets: []string{"192.168.1.150"}, 74 RecordType: endpoint.RecordTypeA, 75 RecordTTL: 0, 76 Labels: endpoint.Labels{ 77 "resource": "f5-virtualserver/virtualserver/test-vs", 78 }, 79 }, 80 }, 81 }, 82 { 83 name: "F5 VirtualServer with host and virtualServerAddress set", 84 annotationFilter: "", 85 virtualServer: f5.VirtualServer{ 86 TypeMeta: metav1.TypeMeta{ 87 APIVersion: f5VirtualServerGVR.GroupVersion().String(), 88 Kind: "VirtualServer", 89 }, 90 ObjectMeta: metav1.ObjectMeta{ 91 Name: "test-vs", 92 Namespace: defaultF5VirtualServerNamespace, 93 }, 94 Spec: f5.VirtualServerSpec{ 95 Host: "www.example.com", 96 VirtualServerAddress: "192.168.1.100", 97 }, 98 Status: f5.VirtualServerStatus{ 99 VSAddress: "192.168.1.200", 100 }, 101 }, 102 expected: []*endpoint.Endpoint{ 103 { 104 DNSName: "www.example.com", 105 Targets: []string{"192.168.1.100"}, 106 RecordType: endpoint.RecordTypeA, 107 RecordTTL: 0, 108 Labels: endpoint.Labels{ 109 "resource": "f5-virtualserver/virtualserver/test-vs", 110 }, 111 }, 112 }, 113 }, 114 { 115 name: "F5 VirtualServer with host set and IP address from the status field", 116 annotationFilter: "", 117 virtualServer: f5.VirtualServer{ 118 TypeMeta: metav1.TypeMeta{ 119 APIVersion: f5VirtualServerGVR.GroupVersion().String(), 120 Kind: "VirtualServer", 121 }, 122 ObjectMeta: metav1.ObjectMeta{ 123 Name: "test-vs", 124 Namespace: defaultF5VirtualServerNamespace, 125 }, 126 Spec: f5.VirtualServerSpec{ 127 Host: "www.example.com", 128 }, 129 Status: f5.VirtualServerStatus{ 130 VSAddress: "192.168.1.100", 131 }, 132 }, 133 expected: []*endpoint.Endpoint{ 134 { 135 DNSName: "www.example.com", 136 Targets: []string{"192.168.1.100"}, 137 RecordType: endpoint.RecordTypeA, 138 RecordTTL: 0, 139 Labels: endpoint.Labels{ 140 "resource": "f5-virtualserver/virtualserver/test-vs", 141 }, 142 }, 143 }, 144 }, 145 { 146 name: "F5 VirtualServer with no IP address set", 147 annotationFilter: "", 148 virtualServer: f5.VirtualServer{ 149 TypeMeta: metav1.TypeMeta{ 150 APIVersion: f5VirtualServerGVR.GroupVersion().String(), 151 Kind: "VirtualServer", 152 }, 153 ObjectMeta: metav1.ObjectMeta{ 154 Name: "test-vs", 155 Namespace: defaultF5VirtualServerNamespace, 156 }, 157 Spec: f5.VirtualServerSpec{ 158 Host: "www.example.com", 159 }, 160 Status: f5.VirtualServerStatus{ 161 VSAddress: "", 162 }, 163 }, 164 expected: nil, 165 }, 166 { 167 name: "F5 VirtualServer with matching annotation filter", 168 annotationFilter: "foo=bar", 169 virtualServer: f5.VirtualServer{ 170 TypeMeta: metav1.TypeMeta{ 171 APIVersion: f5VirtualServerGVR.GroupVersion().String(), 172 Kind: "VirtualServer", 173 }, 174 ObjectMeta: metav1.ObjectMeta{ 175 Name: "test-vs", 176 Namespace: defaultF5VirtualServerNamespace, 177 Annotations: map[string]string{ 178 "foo": "bar", 179 }, 180 }, 181 Spec: f5.VirtualServerSpec{ 182 Host: "www.example.com", 183 VirtualServerAddress: "192.168.1.100", 184 }, 185 }, 186 expected: []*endpoint.Endpoint{ 187 { 188 DNSName: "www.example.com", 189 Targets: []string{"192.168.1.100"}, 190 RecordType: endpoint.RecordTypeA, 191 RecordTTL: 0, 192 Labels: endpoint.Labels{ 193 "resource": "f5-virtualserver/virtualserver/test-vs", 194 }, 195 }, 196 }, 197 }, 198 { 199 name: "F5 VirtualServer with non-matching annotation filter", 200 annotationFilter: "foo=bar", 201 virtualServer: f5.VirtualServer{ 202 TypeMeta: metav1.TypeMeta{ 203 APIVersion: f5VirtualServerGVR.GroupVersion().String(), 204 Kind: "VirtualServer", 205 }, 206 ObjectMeta: metav1.ObjectMeta{ 207 Name: "test-vs", 208 Namespace: defaultF5VirtualServerNamespace, 209 Annotations: map[string]string{ 210 "bar": "foo", 211 }, 212 }, 213 Spec: f5.VirtualServerSpec{ 214 Host: "www.example.com", 215 VirtualServerAddress: "192.168.1.100", 216 }, 217 }, 218 expected: nil, 219 }, 220 { 221 name: "F5 VirtualServer TTL annotation", 222 virtualServer: f5.VirtualServer{ 223 TypeMeta: metav1.TypeMeta{ 224 APIVersion: f5VirtualServerGVR.GroupVersion().String(), 225 Kind: "VirtualServer", 226 }, 227 ObjectMeta: metav1.ObjectMeta{ 228 Name: "test-vs", 229 Namespace: defaultF5VirtualServerNamespace, 230 Annotations: map[string]string{ 231 "external-dns.alpha.kubernetes.io/ttl": "600", 232 }, 233 }, 234 Spec: f5.VirtualServerSpec{ 235 Host: "www.example.com", 236 VirtualServerAddress: "192.168.1.100", 237 }, 238 }, 239 expected: []*endpoint.Endpoint{ 240 { 241 DNSName: "www.example.com", 242 Targets: []string{"192.168.1.100"}, 243 RecordType: endpoint.RecordTypeA, 244 RecordTTL: 600, 245 Labels: endpoint.Labels{ 246 "resource": "f5-virtualserver/virtualserver/test-vs", 247 }, 248 }, 249 }, 250 }, 251 } 252 253 for _, tc := range tests { 254 t.Run(tc.name, func(t *testing.T) { 255 fakeKubernetesClient := fakeKube.NewSimpleClientset() 256 scheme := runtime.NewScheme() 257 scheme.AddKnownTypes(f5VirtualServerGVR.GroupVersion(), &f5.VirtualServer{}, &f5.VirtualServerList{}) 258 fakeDynamicClient := fakeDynamic.NewSimpleDynamicClient(scheme) 259 260 virtualServer := unstructured.Unstructured{} 261 262 virtualServerJSON, err := json.Marshal(tc.virtualServer) 263 require.NoError(t, err) 264 assert.NoError(t, virtualServer.UnmarshalJSON(virtualServerJSON)) 265 266 // Create VirtualServer resources 267 _, err = fakeDynamicClient.Resource(f5VirtualServerGVR).Namespace(defaultF5VirtualServerNamespace).Create(context.Background(), &virtualServer, metav1.CreateOptions{}) 268 assert.NoError(t, err) 269 270 source, err := NewF5VirtualServerSource(context.TODO(), fakeDynamicClient, fakeKubernetesClient, defaultF5VirtualServerNamespace, tc.annotationFilter) 271 require.NoError(t, err) 272 assert.NotNil(t, source) 273 274 count := &unstructured.UnstructuredList{} 275 for len(count.Items) < 1 { 276 count, _ = fakeDynamicClient.Resource(f5VirtualServerGVR).Namespace(defaultF5VirtualServerNamespace).List(context.Background(), metav1.ListOptions{}) 277 } 278 279 endpoints, err := source.Endpoints(context.Background()) 280 require.NoError(t, err) 281 assert.Len(t, endpoints, len(tc.expected)) 282 assert.Equal(t, endpoints, tc.expected) 283 }) 284 } 285 }