sigs.k8s.io/external-dns@v0.14.1/provider/safedns/safedns_test.go (about) 1 /* 2 Copyright 2021 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 safedns 18 19 import ( 20 "context" 21 "os" 22 "testing" 23 24 ansConnection "github.com/ans-group/sdk-go/pkg/connection" 25 "github.com/ans-group/sdk-go/pkg/service/safedns" 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/mock" 28 "github.com/stretchr/testify/require" 29 30 "sigs.k8s.io/external-dns/endpoint" 31 "sigs.k8s.io/external-dns/plan" 32 ) 33 34 // Create an implementation of the SafeDNS interface for Mocking 35 type MockSafeDNSService struct { 36 mock.Mock 37 } 38 39 func (m *MockSafeDNSService) CreateZoneRecord(zoneName string, req safedns.CreateRecordRequest) (int, error) { 40 args := m.Called(zoneName, req) 41 return args.Int(0), args.Error(1) 42 } 43 44 func (m *MockSafeDNSService) DeleteZoneRecord(zoneName string, recordID int) error { 45 args := m.Called(zoneName, recordID) 46 return args.Error(0) 47 } 48 49 func (m *MockSafeDNSService) GetZone(zoneName string) (safedns.Zone, error) { 50 args := m.Called(zoneName) 51 return args.Get(0).(safedns.Zone), args.Error(1) 52 } 53 54 func (m *MockSafeDNSService) GetZoneRecord(zoneName string, recordID int) (safedns.Record, error) { 55 args := m.Called(zoneName, recordID) 56 return args.Get(0).(safedns.Record), args.Error(1) 57 } 58 59 func (m *MockSafeDNSService) GetZoneRecords(zoneName string, parameters ansConnection.APIRequestParameters) ([]safedns.Record, error) { 60 args := m.Called(zoneName, parameters) 61 return args.Get(0).([]safedns.Record), args.Error(1) 62 } 63 64 func (m *MockSafeDNSService) GetZones(parameters ansConnection.APIRequestParameters) ([]safedns.Zone, error) { 65 args := m.Called(parameters) 66 return args.Get(0).([]safedns.Zone), args.Error(1) 67 } 68 69 func (m *MockSafeDNSService) PatchZoneRecord(zoneName string, recordID int, patch safedns.PatchRecordRequest) (int, error) { 70 args := m.Called(zoneName, recordID, patch) 71 return args.Int(0), args.Error(1) 72 } 73 74 func (m *MockSafeDNSService) UpdateZoneRecord(zoneName string, record safedns.Record) (int, error) { 75 args := m.Called(zoneName, record) 76 return args.Int(0), args.Error(1) 77 } 78 79 // Utility functions 80 func createZones() []safedns.Zone { 81 return []safedns.Zone{ 82 {Name: "foo.com", Description: "Foo dot com"}, 83 {Name: "bar.io", Description: ""}, 84 {Name: "baz.org", Description: "Org"}, 85 } 86 } 87 88 func createFooRecords() []safedns.Record { 89 return []safedns.Record{ 90 { 91 ID: 11, 92 Type: safedns.RecordTypeA, 93 Name: "foo.com", 94 Content: "targetFoo", 95 TTL: safedns.RecordTTL(3600), 96 }, 97 { 98 ID: 12, 99 Type: safedns.RecordTypeTXT, 100 Name: "foo.com", 101 Content: "text", 102 TTL: safedns.RecordTTL(3600), 103 }, 104 { 105 ID: 13, 106 Type: safedns.RecordTypeCAA, 107 Name: "foo.com", 108 Content: "", 109 TTL: safedns.RecordTTL(3600), 110 }, 111 } 112 } 113 114 func createBarRecords() []safedns.Record { 115 return []safedns.Record{} 116 } 117 118 func createBazRecords() []safedns.Record { 119 return []safedns.Record{ 120 { 121 ID: 31, 122 Type: safedns.RecordTypeA, 123 Name: "baz.org", 124 Content: "targetBaz", 125 TTL: safedns.RecordTTL(3600), 126 }, 127 { 128 ID: 32, 129 Type: safedns.RecordTypeTXT, 130 Name: "baz.org", 131 Content: "text", 132 TTL: safedns.RecordTTL(3600), 133 }, 134 { 135 ID: 33, 136 Type: safedns.RecordTypeA, 137 Name: "api.baz.org", 138 Content: "targetBazAPI", 139 TTL: safedns.RecordTTL(3600), 140 }, 141 { 142 ID: 34, 143 Type: safedns.RecordTypeTXT, 144 Name: "api.baz.org", 145 Content: "text", 146 TTL: safedns.RecordTTL(3600), 147 }, 148 } 149 } 150 151 // Actual tests 152 func TestNewSafeDNSProvider(t *testing.T) { 153 _ = os.Setenv("SAFEDNS_TOKEN", "DUMMYVALUE") 154 _, err := NewSafeDNSProvider(endpoint.NewDomainFilter([]string{"ext-dns-test.zalando.to."}), true) 155 require.NoError(t, err) 156 157 _ = os.Unsetenv("SAFEDNS_TOKEN") 158 _, err = NewSafeDNSProvider(endpoint.NewDomainFilter([]string{"ext-dns-test.zalando.to."}), true) 159 require.Error(t, err) 160 } 161 162 func TestRecords(t *testing.T) { 163 mockSafeDNSService := MockSafeDNSService{} 164 165 provider := &SafeDNSProvider{ 166 Client: &mockSafeDNSService, 167 domainFilter: endpoint.NewDomainFilter([]string{}), 168 DryRun: false, 169 } 170 171 mockSafeDNSService.On( 172 "GetZones", 173 mock.Anything, 174 ).Return(createZones(), nil).Once() 175 176 mockSafeDNSService.On( 177 "GetZoneRecords", 178 "foo.com", 179 mock.Anything, 180 ).Return(createFooRecords(), nil).Once() 181 182 mockSafeDNSService.On( 183 "GetZoneRecords", 184 "bar.io", 185 mock.Anything, 186 ).Return(createBarRecords(), nil).Once() 187 188 mockSafeDNSService.On( 189 "GetZoneRecords", 190 "baz.org", 191 mock.Anything, 192 ).Return(createBazRecords(), nil).Once() 193 194 actual, err := provider.Records(context.Background()) 195 require.NoError(t, err) 196 197 expected := []*endpoint.Endpoint{ 198 { 199 DNSName: "foo.com", 200 Targets: []string{"targetFoo"}, 201 RecordType: "A", 202 RecordTTL: 3600, 203 Labels: endpoint.NewLabels(), 204 }, 205 { 206 DNSName: "foo.com", 207 Targets: []string{"text"}, 208 RecordType: "TXT", 209 RecordTTL: 3600, 210 Labels: endpoint.NewLabels(), 211 }, 212 { 213 DNSName: "baz.org", 214 Targets: []string{"targetBaz"}, 215 RecordType: "A", 216 RecordTTL: 3600, 217 Labels: endpoint.NewLabels(), 218 }, 219 { 220 DNSName: "baz.org", 221 Targets: []string{"text"}, 222 RecordType: "TXT", 223 RecordTTL: 3600, 224 Labels: endpoint.NewLabels(), 225 }, 226 { 227 DNSName: "api.baz.org", 228 Targets: []string{"targetBazAPI"}, 229 RecordType: "A", 230 RecordTTL: 3600, 231 Labels: endpoint.NewLabels(), 232 }, 233 { 234 DNSName: "api.baz.org", 235 Targets: []string{"text"}, 236 RecordType: "TXT", 237 RecordTTL: 3600, 238 Labels: endpoint.NewLabels(), 239 }, 240 } 241 242 mockSafeDNSService.AssertExpectations(t) 243 assert.Equal(t, expected, actual) 244 } 245 246 func TestSafeDNSApplyChanges(t *testing.T) { 247 mockSafeDNSService := MockSafeDNSService{} 248 249 provider := &SafeDNSProvider{ 250 Client: &mockSafeDNSService, 251 domainFilter: endpoint.NewDomainFilter([]string{}), 252 DryRun: false, 253 } 254 255 // Dummy data 256 mockSafeDNSService.On( 257 "GetZones", 258 mock.Anything, 259 ).Return(createZones(), nil).Once() 260 mockSafeDNSService.On( 261 "GetZones", 262 mock.Anything, 263 ).Return(createZones(), nil).Once() 264 265 mockSafeDNSService.On( 266 "GetZoneRecords", 267 "foo.com", 268 mock.Anything, 269 ).Return(createFooRecords(), nil).Once() 270 271 mockSafeDNSService.On( 272 "GetZoneRecords", 273 "bar.io", 274 mock.Anything, 275 ).Return(createBarRecords(), nil).Once() 276 277 mockSafeDNSService.On( 278 "GetZoneRecords", 279 "baz.org", 280 mock.Anything, 281 ).Return(createBazRecords(), nil).Once() 282 283 // Apply actions 284 mockSafeDNSService.On( 285 "DeleteZoneRecord", 286 "baz.org", 287 33, 288 ).Return(nil).Once() 289 mockSafeDNSService.On( 290 "DeleteZoneRecord", 291 "baz.org", 292 34, 293 ).Return(nil).Once() 294 295 TTL300 := safedns.RecordTTL(300) 296 mockSafeDNSService.On( 297 "PatchZoneRecord", 298 "foo.com", 299 11, 300 safedns.PatchRecordRequest{ 301 Type: "A", 302 Name: "foo.com", 303 Content: "targetFoo", 304 TTL: &TTL300, 305 }, 306 ).Return(123, nil).Once() 307 308 mockSafeDNSService.On( 309 "CreateZoneRecord", 310 "bar.io", 311 safedns.CreateRecordRequest{ 312 Type: "A", 313 Name: "create.bar.io", 314 Content: "targetBar", 315 }, 316 ).Return(246, nil).Once() 317 318 mockSafeDNSService.On( 319 "CreateZoneRecord", 320 "bar.io", 321 safedns.CreateRecordRequest{ 322 Type: "A", 323 Name: "bar.io", 324 Content: "targetBar", 325 }, 326 ).Return(369, nil).Once() 327 328 err := provider.ApplyChanges(context.Background(), &plan.Changes{ 329 Create: []*endpoint.Endpoint{ 330 { 331 DNSName: "create.bar.io", 332 RecordType: "A", 333 Targets: []string{"targetBar"}, 334 RecordTTL: 3600, 335 }, 336 { 337 DNSName: "bar.io", 338 RecordType: "A", 339 Targets: []string{"targetBar"}, 340 RecordTTL: 3600, 341 }, 342 }, 343 Delete: []*endpoint.Endpoint{ 344 { 345 DNSName: "api.baz.org", 346 RecordType: "A", 347 }, 348 { 349 DNSName: "api.baz.org", 350 RecordType: "TXT", 351 }, 352 }, 353 UpdateNew: []*endpoint.Endpoint{ 354 { 355 DNSName: "foo.com", 356 RecordType: "A", 357 RecordTTL: 300, 358 Targets: []string{"targetFoo"}, 359 }, 360 }, 361 UpdateOld: []*endpoint.Endpoint{}, 362 }) 363 require.NoError(t, err) 364 365 mockSafeDNSService.AssertExpectations(t) 366 }