github.com/akamai/AkamaiOPEN-edgegrid-golang/v2@v2.17.0/pkg/configdns/zone_test.go (about) 1 package dns 2 3 import ( 4 "context" 5 "errors" 6 "net/http" 7 "net/http/httptest" 8 "testing" 9 10 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v2/pkg/session" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestDns_ListZones(t *testing.T) { 16 17 tests := map[string]struct { 18 args []ZoneListQueryArgs 19 responseStatus int 20 responseBody string 21 expectedPath string 22 expectedResponse *ZoneListResponse 23 withError error 24 headers http.Header 25 }{ 26 "200 OK": { 27 args: []ZoneListQueryArgs{ 28 { 29 ContractIDs: "1-1ACYUM", 30 Search: "org", 31 SortBy: "-contractId,zone", 32 Types: "primary,alias", 33 Page: 1, 34 PageSize: 25, 35 }, 36 }, 37 headers: http.Header{ 38 "Accept": []string{"application/json"}, 39 }, 40 responseStatus: http.StatusOK, 41 responseBody: ` 42 { 43 "metadata": { 44 "page": 1, 45 "pageSize": 3, 46 "showAll": false, 47 "totalElements": 17, 48 "contractIds": [ 49 "1-2ABCDE" 50 ] 51 }, 52 "zones": [ 53 { 54 "contractId": "1-2ABCDE", 55 "zone": "example.com", 56 "type": "primary", 57 "aliasCount": 1, 58 "signAndServe": false, 59 "versionId": "ae02357c-693d-4ac4-b33d-8352d9b7c786", 60 "lastModifiedDate": "2017-01-03T12:00:00Z", 61 "lastModifiedBy": "user28", 62 "lastActivationDate": "2017-01-03T12:00:00Z", 63 "activationState": "ACTIVE" 64 } 65 ] 66 }`, 67 expectedPath: "/config-dns/v2/zones?contractIds=1-1ACYUM&search=org&sortBy=-contractId%2Czone&types=primary%2Calias&page=1&pageSize=25&showAll=false", 68 expectedResponse: &ZoneListResponse{ 69 Metadata: &ListMetadata{ 70 Page: 1, 71 PageSize: 3, 72 ShowAll: false, 73 TotalElements: 17, 74 ContractIDs: []string{"1-2ABCDE"}, 75 }, 76 Zones: []*ZoneResponse{ 77 { 78 ContractID: "1-2ABCDE", 79 Zone: "example.com", 80 Type: "primary", 81 AliasCount: 1, 82 SignAndServe: false, 83 VersionId: "ae02357c-693d-4ac4-b33d-8352d9b7c786", 84 LastModifiedDate: "2017-01-03T12:00:00Z", 85 LastModifiedBy: "user28", 86 LastActivationDate: "2017-01-03T12:00:00Z", 87 ActivationState: "ACTIVE", 88 }, 89 }, 90 }, 91 }, 92 "500 internal server error": { 93 args: []ZoneListQueryArgs{ 94 { 95 ContractIDs: "1-1ACYUM", 96 Search: "org", 97 SortBy: "-contractId,zone", 98 Types: "primary,alias", 99 Page: 1, 100 PageSize: 25, 101 }, 102 }, 103 responseStatus: http.StatusInternalServerError, 104 responseBody: ` 105 { 106 "type": "internal_error", 107 "title": "Internal Server Error", 108 "detail": "Error fetching authorities", 109 "status": 500 110 }`, 111 expectedPath: "/config-dns/v2/zones?contractIds=1-1ACYUM&search=org&sortBy=-contractId%2Czone&types=primary%2Calias&page=1&pageSize=25&showAll=false", 112 withError: &Error{ 113 Type: "internal_error", 114 Title: "Internal Server Error", 115 Detail: "Error fetching authorities", 116 StatusCode: http.StatusInternalServerError, 117 }, 118 }, 119 } 120 121 for name, test := range tests { 122 t.Run(name, func(t *testing.T) { 123 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 124 //assert.Equal(t, test.expectedPath, r.URL.String()) 125 assert.Equal(t, http.MethodGet, r.Method) 126 w.WriteHeader(test.responseStatus) 127 _, err := w.Write([]byte(test.responseBody)) 128 assert.NoError(t, err) 129 })) 130 client := mockAPIClient(t, mockServer) 131 result, err := client.ListZones( 132 session.ContextWithOptions( 133 context.Background(), 134 session.WithContextHeaders(test.headers)), test.args...) 135 if test.withError != nil { 136 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 137 return 138 } 139 require.NoError(t, err) 140 assert.Equal(t, test.expectedResponse, result) 141 }) 142 } 143 } 144 145 func TestDns_NewZone(t *testing.T) { 146 client := Client(session.Must(session.New())) 147 148 inp := ZoneCreate{ 149 Type: "A", 150 Target: "10.0.0.1", 151 } 152 153 out := client.NewZone(context.Background(), inp) 154 155 assert.Equal(t, &inp, out) 156 } 157 158 func TestDns_NewZoneResponse(t *testing.T) { 159 client := Client(session.Must(session.New())) 160 161 out := client.NewZoneResponse(context.Background(), "example.com") 162 163 assert.Equal(t, out.Zone, "example.com") 164 } 165 166 func TestDns_NewChangeListResponse(t *testing.T) { 167 client := Client(session.Must(session.New())) 168 169 out := client.NewChangeListResponse(context.Background(), "example.com") 170 171 assert.Equal(t, out.Zone, "example.com") 172 } 173 174 func TestDns_NewZoneQueryString(t *testing.T) { 175 client := Client(session.Must(session.New())) 176 177 out := client.NewZoneQueryString(context.Background(), "foo", "bar") 178 179 assert.Equal(t, out.Contract, "foo") 180 assert.Equal(t, out.Group, "bar") 181 } 182 183 func TestDns_GetZone(t *testing.T) { 184 tests := map[string]struct { 185 zone string 186 responseStatus int 187 responseBody string 188 expectedPath string 189 expectedResponse *ZoneResponse 190 withError error 191 }{ 192 "200 OK": { 193 zone: "example.com", 194 responseStatus: http.StatusOK, 195 responseBody: ` 196 { 197 "contractId": "1-2ABCDE", 198 "zone": "example.com", 199 "type": "primary", 200 "aliasCount": 1, 201 "signAndServe": true, 202 "signAndServeAlgorithm": "RSA_SHA256", 203 "versionId": "ae02357c-693d-4ac4-b33d-8352d9b7c786", 204 "lastModifiedDate": "2017-01-03T12:00:00Z", 205 "lastModifiedBy": "user28", 206 "lastActivationDate": "2017-01-03T12:00:00Z", 207 "activationState": "ACTIVE" 208 }`, 209 expectedPath: "/config-dns/v2/zones/example.com", 210 expectedResponse: &ZoneResponse{ 211 ContractID: "1-2ABCDE", 212 Zone: "example.com", 213 Type: "primary", 214 AliasCount: 1, 215 SignAndServe: true, 216 SignAndServeAlgorithm: "RSA_SHA256", 217 VersionId: "ae02357c-693d-4ac4-b33d-8352d9b7c786", 218 LastModifiedDate: "2017-01-03T12:00:00Z", 219 LastModifiedBy: "user28", 220 LastActivationDate: "2017-01-03T12:00:00Z", 221 ActivationState: "ACTIVE", 222 }, 223 }, 224 "500 internal server error": { 225 zone: "example.com", 226 responseStatus: http.StatusInternalServerError, 227 responseBody: ` 228 { 229 "type": "internal_error", 230 "title": "Internal Server Error", 231 "detail": "Error fetching authorities", 232 "status": 500 233 }`, 234 expectedPath: "/config-dns/v2/zones/example.com", 235 withError: &Error{ 236 Type: "internal_error", 237 Title: "Internal Server Error", 238 Detail: "Error fetching authorities", 239 StatusCode: http.StatusInternalServerError, 240 }, 241 }, 242 } 243 244 for name, test := range tests { 245 t.Run(name, func(t *testing.T) { 246 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 247 //assert.Equal(t, test.expectedPath, r.URL.String()) 248 assert.Equal(t, http.MethodGet, r.Method) 249 w.WriteHeader(test.responseStatus) 250 _, err := w.Write([]byte(test.responseBody)) 251 assert.NoError(t, err) 252 })) 253 client := mockAPIClient(t, mockServer) 254 result, err := client.GetZone(context.Background(), test.zone) 255 if test.withError != nil { 256 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 257 return 258 } 259 require.NoError(t, err) 260 assert.Equal(t, test.expectedResponse, result) 261 }) 262 } 263 } 264 265 func TestDns_GetZoneMasterFile(t *testing.T) { 266 tests := map[string]struct { 267 zone string 268 responseStatus int 269 responseBody string 270 expectedPath string 271 expectedResponse string 272 withError error 273 }{ 274 "200 OK": { 275 zone: "example.com", 276 responseStatus: http.StatusOK, 277 responseBody: `"example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 278 example.com. 10000 IN NS ns1.akamaidns.com. 279 example.com. 10000 IN NS ns2.akamaidns.com. 280 example.com. 300 IN A 10.0.0.1 281 example.com. 300 IN A 10.0.0.2 282 www.example.com. 300 IN A 10.0.0.1 283 www.example.com. 300 IN A 10.0.0.2"`, 284 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 285 expectedResponse: `"example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 286 example.com. 10000 IN NS ns1.akamaidns.com. 287 example.com. 10000 IN NS ns2.akamaidns.com. 288 example.com. 300 IN A 10.0.0.1 289 example.com. 300 IN A 10.0.0.2 290 www.example.com. 300 IN A 10.0.0.1 291 www.example.com. 300 IN A 10.0.0.2"`, 292 }, 293 "500 internal server error": { 294 zone: "example.com", 295 responseStatus: http.StatusInternalServerError, 296 responseBody: ` 297 { 298 "type": "internal_error", 299 "title": "Internal Server Error", 300 "detail": "Error fetching authorities", 301 "status": 500 302 }`, 303 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 304 withError: &Error{ 305 Type: "internal_error", 306 Title: "Internal Server Error", 307 Detail: "Error fetching authorities", 308 StatusCode: http.StatusInternalServerError, 309 }, 310 }, 311 } 312 313 for name, test := range tests { 314 t.Run(name, func(t *testing.T) { 315 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 316 //assert.Equal(t, test.expectedPath, r.URL.String()) 317 assert.Equal(t, http.MethodGet, r.Method) 318 w.WriteHeader(test.responseStatus) 319 _, err := w.Write([]byte(test.responseBody)) 320 assert.NoError(t, err) 321 })) 322 client := mockAPIClient(t, mockServer) 323 result, err := client.GetMasterZoneFile(context.Background(), test.zone) 324 if test.withError != nil { 325 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 326 return 327 } 328 require.NoError(t, err) 329 assert.Equal(t, test.expectedResponse, result) 330 }) 331 } 332 } 333 334 func TestDns_UpdateZoneMasterFile(t *testing.T) { 335 tests := map[string]struct { 336 zone string 337 masterfile string 338 responseStatus int 339 expectedPath string 340 responseBody string 341 withError error 342 }{ 343 "204 Updated": { 344 zone: "example.com", 345 masterfile: `"example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 346 example.com. 10000 IN NS ns1.akamaidns.com. 347 example.com. 10000 IN NS ns2.akamaidns.com. 348 example.com. 300 IN A 10.0.0.1 349 example.com. 300 IN A 10.0.0.2 350 www.example.com. 300 IN A 10.0.0.1 351 www.example.com. 300 IN A 10.0.0.2"`, 352 responseStatus: http.StatusNoContent, 353 responseBody: "", 354 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 355 }, 356 "500 internal server error": { 357 zone: "example.com", 358 masterfile: `"example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 359 example.com. 10000 IN NS ns1.akamaidns.com. 360 example.com. 10000 IN NS ns2.akamaidns.com. 361 example.com. 300 IN A 10.0.0.1 362 example.com. 300 IN A 10.0.0.2 363 www.example.com. 300 IN A 10.0.0.1 364 www.example.com. 300 IN A 10.0.0.2"`, 365 responseStatus: http.StatusInternalServerError, 366 responseBody: ` 367 { 368 "type": "internal_error", 369 "title": "Internal Server Error", 370 "detail": "Error creating zone", 371 "status": 500 372 }`, 373 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 374 withError: &Error{ 375 Type: "internal_error", 376 Title: "Internal Server Error", 377 Detail: "Error creating zone", 378 StatusCode: http.StatusInternalServerError, 379 }, 380 }, 381 } 382 383 for name, test := range tests { 384 t.Run(name, func(t *testing.T) { 385 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 386 assert.Equal(t, http.MethodPost, r.Method) 387 w.WriteHeader(test.responseStatus) 388 if len(test.responseBody) > 0 { 389 _, err := w.Write([]byte(test.responseBody)) 390 assert.NoError(t, err) 391 } 392 })) 393 client := mockAPIClient(t, mockServer) 394 err := client.PostMasterZoneFile(context.Background(), test.zone, test.masterfile) 395 if test.withError != nil { 396 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 397 return 398 } 399 require.NoError(t, err) 400 }) 401 } 402 } 403 404 func TestDns_GetChangeList(t *testing.T) { 405 tests := map[string]struct { 406 zone string 407 responseStatus int 408 responseBody string 409 expectedPath string 410 expectedResponse *ChangeListResponse 411 withError error 412 }{ 413 "200 OK": { 414 zone: "example.com", 415 responseStatus: http.StatusOK, 416 responseBody: ` 417 { 418 "zone": "example.com", 419 "changeTag": "476754f4-d605-479f-853b-db854d7254fa", 420 "zoneVersionId": "1d9c887c-49bb-4382-87a6-d1bf690aa58f", 421 "lastModifiedDate": "2017-02-01T12:00:12.524Z", 422 "stale": false 423 }`, 424 expectedPath: "/config-dns/v2/zones/example.com", 425 expectedResponse: &ChangeListResponse{ 426 Zone: "example.com", 427 ChangeTag: "476754f4-d605-479f-853b-db854d7254fa", 428 ZoneVersionID: "1d9c887c-49bb-4382-87a6-d1bf690aa58f", 429 LastModifiedDate: "2017-02-01T12:00:12.524Z", 430 Stale: false, 431 }, 432 }, 433 "500 internal server error": { 434 zone: "example.com", 435 responseStatus: http.StatusInternalServerError, 436 responseBody: ` 437 { 438 "type": "internal_error", 439 "title": "Internal Server Error", 440 "detail": "Error fetching authorities", 441 "status": 500 442 }`, 443 expectedPath: "/config-dns/v2/zones/example.com", 444 withError: &Error{ 445 Type: "internal_error", 446 Title: "Internal Server Error", 447 Detail: "Error fetching authorities", 448 StatusCode: http.StatusInternalServerError, 449 }, 450 }, 451 } 452 453 for name, test := range tests { 454 t.Run(name, func(t *testing.T) { 455 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 456 //assert.Equal(t, test.expectedPath, r.URL.String()) 457 assert.Equal(t, http.MethodGet, r.Method) 458 w.WriteHeader(test.responseStatus) 459 _, err := w.Write([]byte(test.responseBody)) 460 assert.NoError(t, err) 461 })) 462 client := mockAPIClient(t, mockServer) 463 result, err := client.GetChangeList(context.Background(), test.zone) 464 if test.withError != nil { 465 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 466 return 467 } 468 require.NoError(t, err) 469 assert.Equal(t, test.expectedResponse, result) 470 }) 471 } 472 } 473 474 func TestDns_GetMasterZoneFile(t *testing.T) { 475 tests := map[string]struct { 476 zone string 477 responseStatus int 478 responseBody string 479 expectedPath string 480 expectedResponse string 481 withError error 482 }{ 483 "200 OK": { 484 zone: "example.com", 485 responseStatus: http.StatusOK, 486 responseBody: ` 487 example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 488 example.com. 10000 IN NS ns1.akamaidns.com. 489 example.com. 10000 IN NS ns2.akamaidns.com. 490 example.com. 300 IN A 10.0.0.1 491 example.com. 300 IN A 10.0.0.2 492 www.example.com. 300 IN A 10.0.0.1 493 www.example.com. 300 IN A 10.0.0.2`, 494 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 495 expectedResponse: ` 496 example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 497 example.com. 10000 IN NS ns1.akamaidns.com. 498 example.com. 10000 IN NS ns2.akamaidns.com. 499 example.com. 300 IN A 10.0.0.1 500 example.com. 300 IN A 10.0.0.2 501 www.example.com. 300 IN A 10.0.0.1 502 www.example.com. 300 IN A 10.0.0.2`, 503 }, 504 "500 internal server error": { 505 zone: "example.com", 506 responseStatus: http.StatusInternalServerError, 507 responseBody: ` 508 { 509 "type": "internal_error", 510 "title": "Internal Server Error", 511 "detail": "Error fetching master zone file", 512 "status": 500 513 }`, 514 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 515 withError: &Error{ 516 Type: "internal_error", 517 Title: "Internal Server Error", 518 Detail: "Error fetching master zone file", 519 StatusCode: http.StatusInternalServerError, 520 }, 521 }, 522 } 523 524 for name, test := range tests { 525 t.Run(name, func(t *testing.T) { 526 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 527 assert.Equal(t, test.expectedPath, r.URL.String()) 528 assert.Equal(t, http.MethodGet, r.Method) 529 w.WriteHeader(test.responseStatus) 530 if len(test.responseBody) > 0 { 531 _, err := w.Write([]byte(test.responseBody)) 532 assert.NoError(t, err) 533 } 534 })) 535 client := mockAPIClient(t, mockServer) 536 result, err := client.GetMasterZoneFile(context.Background(), test.zone) 537 if test.withError != nil { 538 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 539 return 540 } 541 require.NoError(t, err) 542 assert.Equal(t, test.expectedResponse, result) 543 }) 544 } 545 } 546 547 func TestDns_CreateZone(t *testing.T) { 548 tests := map[string]struct { 549 zone ZoneCreate 550 query ZoneQueryString 551 responseStatus int 552 responseBody string 553 expectedPath string 554 withError error 555 }{ 556 "201 Created": { 557 zone: ZoneCreate{ 558 Zone: "example.com", 559 ContractID: "1-2ABCDE", 560 Type: "primary", 561 }, 562 responseStatus: http.StatusCreated, 563 responseBody: ` 564 { 565 "contractId": "1-2ABCDE", 566 "zone": "other.com", 567 "type": "primary", 568 "aliasCount": 1, 569 "signAndServe": false, 570 "comment": "Initial add", 571 "versionId": "7949b2db-ac43-4773-a3ec-dc93202142fd", 572 "lastModifiedDate": "2016-12-11T03:21:00Z", 573 "lastModifiedBy": "user31", 574 "lastActivationDate": "2017-01-03T12:00:00Z", 575 "activationState": "ERROR", 576 "masters": [ 577 "1.2.3.4", 578 "1.2.3.5" 579 ], 580 "tsigKey": { 581 "name": "other.com.akamai.com.", 582 "algorithm": "hmac-sha512", 583 "secret": "Ok1qR5IW1ajVka5cHPEJQIXfLyx5V3PSkFBROAzOn21JumDq6nIpoj6H8rfj5Uo+Ok55ZWQ0Wgrf302fDscHLw==" 584 } 585 }`, 586 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 587 }, 588 "500 internal server error": { 589 zone: ZoneCreate{ 590 Zone: "example.com", 591 ContractID: "1-2ABCDE", 592 Type: "secondary", 593 }, 594 responseStatus: http.StatusInternalServerError, 595 responseBody: ` 596 { 597 "type": "internal_error", 598 "title": "Internal Server Error", 599 "detail": "Error creating zone", 600 "status": 500 601 }`, 602 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 603 withError: &Error{ 604 Type: "internal_error", 605 Title: "Internal Server Error", 606 Detail: "Error creating zone", 607 StatusCode: http.StatusInternalServerError, 608 }, 609 }, 610 } 611 612 for name, test := range tests { 613 t.Run(name, func(t *testing.T) { 614 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 615 assert.Equal(t, http.MethodPost, r.Method) 616 w.WriteHeader(test.responseStatus) 617 if len(test.responseBody) > 0 { 618 _, err := w.Write([]byte(test.responseBody)) 619 assert.NoError(t, err) 620 } 621 })) 622 client := mockAPIClient(t, mockServer) 623 err := client.CreateZone(context.Background(), &test.zone, test.query, true) 624 if test.withError != nil { 625 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 626 return 627 } 628 require.NoError(t, err) 629 }) 630 } 631 } 632 633 func TestDns_SaveChangelist(t *testing.T) { 634 tests := map[string]struct { 635 zone ZoneCreate 636 responseStatus int 637 responseBody string 638 expectedPath string 639 withError error 640 }{ 641 "201 Created": { 642 zone: ZoneCreate{ 643 Zone: "example.com", 644 ContractID: "1-2ABCDE", 645 Type: "primary", 646 }, 647 responseStatus: http.StatusCreated, 648 expectedPath: "/config-dns/v2/changelists?zone=example.com", 649 }, 650 "500 internal server error": { 651 zone: ZoneCreate{ 652 Zone: "example.com", 653 ContractID: "1-2ABCDE", 654 Type: "secondary", 655 }, 656 responseStatus: http.StatusInternalServerError, 657 responseBody: ` 658 { 659 "type": "internal_error", 660 "title": "Internal Server Error", 661 "detail": "Error creating zone", 662 "status": 500 663 }`, 664 expectedPath: "/config-dns/v2/changelists?zone=example.com", 665 withError: &Error{ 666 Type: "internal_error", 667 Title: "Internal Server Error", 668 Detail: "Error creating zone", 669 StatusCode: http.StatusInternalServerError, 670 }, 671 }, 672 } 673 674 for name, test := range tests { 675 t.Run(name, func(t *testing.T) { 676 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 677 assert.Equal(t, http.MethodPost, r.Method) 678 w.WriteHeader(test.responseStatus) 679 if len(test.responseBody) > 0 { 680 _, err := w.Write([]byte(test.responseBody)) 681 assert.NoError(t, err) 682 } 683 })) 684 client := mockAPIClient(t, mockServer) 685 err := client.SaveChangelist(context.Background(), &test.zone) 686 if test.withError != nil { 687 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 688 return 689 } 690 require.NoError(t, err) 691 }) 692 } 693 } 694 695 func TestDns_SubmitChangelist(t *testing.T) { 696 tests := map[string]struct { 697 zone ZoneCreate 698 responseStatus int 699 responseBody string 700 expectedPath string 701 withError error 702 }{ 703 "204 No Content": { 704 zone: ZoneCreate{ 705 Zone: "example.com", 706 ContractID: "1-2ABCDE", 707 Type: "primary", 708 }, 709 responseStatus: http.StatusNoContent, 710 expectedPath: "/config-dns/v2/changelists?zone=example.com", 711 }, 712 "500 internal server error": { 713 zone: ZoneCreate{ 714 Zone: "example.com", 715 ContractID: "1-2ABCDE", 716 Type: "secondary", 717 }, 718 responseStatus: http.StatusInternalServerError, 719 responseBody: ` 720 { 721 "type": "internal_error", 722 "title": "Internal Server Error", 723 "detail": "Error creating zone", 724 "status": 500 725 }`, 726 expectedPath: "/config-dns/v2/changelists?zone=example.com", 727 withError: &Error{ 728 Type: "internal_error", 729 Title: "Internal Server Error", 730 Detail: "Error creating zone", 731 StatusCode: http.StatusInternalServerError, 732 }, 733 }, 734 } 735 736 for name, test := range tests { 737 t.Run(name, func(t *testing.T) { 738 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 739 assert.Equal(t, http.MethodPost, r.Method) 740 w.WriteHeader(test.responseStatus) 741 if len(test.responseBody) > 0 { 742 _, err := w.Write([]byte(test.responseBody)) 743 assert.NoError(t, err) 744 } 745 })) 746 client := mockAPIClient(t, mockServer) 747 err := client.SubmitChangelist(context.Background(), &test.zone) 748 if test.withError != nil { 749 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 750 return 751 } 752 require.NoError(t, err) 753 }) 754 } 755 } 756 757 func TestDns_UpdateZone(t *testing.T) { 758 tests := map[string]struct { 759 zone ZoneCreate 760 query ZoneQueryString 761 responseStatus int 762 responseBody string 763 expectedPath string 764 withError error 765 }{ 766 "200 OK": { 767 zone: ZoneCreate{ 768 Zone: "example.com", 769 ContractID: "1-2ABCDE", 770 Type: "primary", 771 }, 772 responseStatus: http.StatusOK, 773 responseBody: ` 774 { 775 "contractId": "1-2ABCDE", 776 "zone": "other.com", 777 "type": "primary", 778 "aliasCount": 1, 779 "signAndServe": false, 780 "comment": "Initial add", 781 "versionId": "7949b2db-ac43-4773-a3ec-dc93202142fd", 782 "lastModifiedDate": "2016-12-11T03:21:00Z", 783 "lastModifiedBy": "user31", 784 "lastActivationDate": "2017-01-03T12:00:00Z", 785 "activationState": "ERROR", 786 "masters": [ 787 "1.2.3.4", 788 "1.2.3.5" 789 ], 790 "tsigKey": { 791 "name": "other.com.akamai.com.", 792 "algorithm": "hmac-sha512", 793 "secret": "Ok1qR5IW1ajVka5cHPEJQIXfLyx5V3PSkFBROAzOn21JumDq6nIpoj6H8rfj5Uo+Ok55ZWQ0Wgrf302fDscHLw==" 794 } 795 }`, 796 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 797 }, 798 "500 internal server error": { 799 zone: ZoneCreate{ 800 Zone: "example.com", 801 ContractID: "1-2ABCDE", 802 Type: "secondary", 803 }, 804 responseStatus: http.StatusInternalServerError, 805 responseBody: ` 806 { 807 "type": "internal_error", 808 "title": "Internal Server Error", 809 "detail": "Error creating zone", 810 "status": 500 811 }`, 812 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 813 withError: &Error{ 814 Type: "internal_error", 815 Title: "Internal Server Error", 816 Detail: "Error creating zone", 817 StatusCode: http.StatusInternalServerError, 818 }, 819 }, 820 } 821 822 for name, test := range tests { 823 t.Run(name, func(t *testing.T) { 824 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 825 assert.Equal(t, http.MethodPut, r.Method) 826 w.WriteHeader(test.responseStatus) 827 if len(test.responseBody) > 0 { 828 _, err := w.Write([]byte(test.responseBody)) 829 assert.NoError(t, err) 830 } 831 })) 832 client := mockAPIClient(t, mockServer) 833 err := client.UpdateZone(context.Background(), &test.zone, test.query) 834 if test.withError != nil { 835 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 836 return 837 } 838 require.NoError(t, err) 839 }) 840 } 841 } 842 843 func TestDns_DeleteZone(t *testing.T) { 844 tests := map[string]struct { 845 zone ZoneCreate 846 query ZoneQueryString 847 responseStatus int 848 responseBody string 849 expectedPath string 850 withError error 851 }{ 852 "204 No Content": { 853 zone: ZoneCreate{ 854 Zone: "example.com", 855 ContractID: "1-2ABCDE", 856 Type: "primary", 857 }, 858 responseStatus: http.StatusNoContent, 859 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 860 }, 861 "500 internal server error": { 862 zone: ZoneCreate{ 863 Zone: "example.com", 864 ContractID: "1-2ABCDE", 865 Type: "secondary", 866 }, 867 responseStatus: http.StatusInternalServerError, 868 responseBody: ` 869 { 870 "type": "internal_error", 871 "title": "Internal Server Error", 872 "detail": "Error creating zone", 873 "status": 500 874 }`, 875 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 876 withError: &Error{ 877 Type: "internal_error", 878 Title: "Internal Server Error", 879 Detail: "Error creating zone", 880 StatusCode: http.StatusInternalServerError, 881 }, 882 }, 883 } 884 885 for name, test := range tests { 886 t.Run(name, func(t *testing.T) { 887 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 888 assert.Equal(t, http.MethodDelete, r.Method) 889 w.WriteHeader(test.responseStatus) 890 if len(test.responseBody) > 0 { 891 _, err := w.Write([]byte(test.responseBody)) 892 assert.NoError(t, err) 893 } 894 })) 895 client := mockAPIClient(t, mockServer) 896 err := client.DeleteZone(context.Background(), &test.zone, test.query) 897 if test.withError != nil { 898 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 899 return 900 } 901 require.NoError(t, err) 902 }) 903 } 904 } 905 906 func TestDns_GetZoneNames(t *testing.T) { 907 tests := map[string]struct { 908 zone string 909 responseStatus int 910 responseBody string 911 expectedPath string 912 expectedResponse *ZoneNamesResponse 913 withError error 914 }{ 915 "200 OK": { 916 zone: "example.com", 917 responseStatus: http.StatusOK, 918 responseBody: ` 919 { 920 "names": [ 921 "example.com", 922 "www.example.com", 923 "ftp.example.com", 924 "space.example.com", 925 "bar.example.com" 926 ] 927 }`, 928 expectedPath: "/config-dns/v2/zones/example.com/names", 929 expectedResponse: &ZoneNamesResponse{ 930 Names: []string{"example.com", "www.example.com", "ftp.example.com", "space.example.com", "bar.example.com"}, 931 }, 932 }, 933 "500 internal server error": { 934 zone: "example.com", 935 responseStatus: http.StatusInternalServerError, 936 responseBody: ` 937 { 938 "type": "internal_error", 939 "title": "Internal Server Error", 940 "detail": "Error fetching authorities", 941 "status": 500 942 }`, 943 expectedPath: "/config-dns/v2/zones/example.com/names", 944 withError: &Error{ 945 Type: "internal_error", 946 Title: "Internal Server Error", 947 Detail: "Error fetching authorities", 948 StatusCode: http.StatusInternalServerError, 949 }, 950 }, 951 } 952 953 for name, test := range tests { 954 t.Run(name, func(t *testing.T) { 955 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 956 //assert.Equal(t, test.expectedPath, r.URL.String()) 957 assert.Equal(t, http.MethodGet, r.Method) 958 w.WriteHeader(test.responseStatus) 959 _, err := w.Write([]byte(test.responseBody)) 960 assert.NoError(t, err) 961 })) 962 client := mockAPIClient(t, mockServer) 963 result, err := client.GetZoneNames(context.Background(), test.zone) 964 if test.withError != nil { 965 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 966 return 967 } 968 require.NoError(t, err) 969 assert.Equal(t, test.expectedResponse, result) 970 }) 971 } 972 } 973 974 func TestDns_GetZoneNameTypes(t *testing.T) { 975 tests := map[string]struct { 976 zone string 977 zname string 978 responseStatus int 979 responseBody string 980 expectedPath string 981 expectedResponse *ZoneNameTypesResponse 982 withError error 983 }{ 984 "200 OK": { 985 zone: "example.com", 986 zname: "names", 987 responseStatus: http.StatusOK, 988 responseBody: ` 989 { 990 "types": [ 991 "A", 992 "AAAA", 993 "MX" 994 ] 995 }`, 996 expectedPath: "/config-dns/v2/zones/example.com/names/www.example.com/types", 997 expectedResponse: &ZoneNameTypesResponse{ 998 Types: []string{"A", "AAAA", "MX"}, 999 }, 1000 }, 1001 "500 internal server error": { 1002 zone: "example.com", 1003 zname: "names", 1004 responseStatus: http.StatusInternalServerError, 1005 responseBody: ` 1006 { 1007 "type": "internal_error", 1008 "title": "Internal Server Error", 1009 "detail": "Error fetching authorities", 1010 "status": 500 1011 }`, 1012 expectedPath: "/config-dns/v2/zones/example.com/names/www.example.com/types", 1013 withError: &Error{ 1014 Type: "internal_error", 1015 Title: "Internal Server Error", 1016 Detail: "Error fetching authorities", 1017 StatusCode: http.StatusInternalServerError, 1018 }, 1019 }, 1020 } 1021 1022 for name, test := range tests { 1023 t.Run(name, func(t *testing.T) { 1024 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 1025 //assert.Equal(t, test.expectedPath, r.URL.String()) 1026 assert.Equal(t, http.MethodGet, r.Method) 1027 w.WriteHeader(test.responseStatus) 1028 _, err := w.Write([]byte(test.responseBody)) 1029 assert.NoError(t, err) 1030 })) 1031 client := mockAPIClient(t, mockServer) 1032 result, err := client.GetZoneNameTypes(context.Background(), test.zname, test.zone) 1033 if test.withError != nil { 1034 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 1035 return 1036 } 1037 require.NoError(t, err) 1038 assert.Equal(t, test.expectedResponse, result) 1039 }) 1040 } 1041 } 1042 1043 func Test_ValidateZoneErrors(t *testing.T) { 1044 client := Client(session.Must(session.New())) 1045 1046 tests := map[string]ZoneCreate{ 1047 "empty zone": {}, 1048 "bad type": { 1049 Zone: "example.com", 1050 Type: "BAD", 1051 }, 1052 "secondary tsig": { 1053 Zone: "example.com", 1054 Type: "PRIMARY", 1055 TsigKey: &TSIGKey{ 1056 Name: "example.com", 1057 }, 1058 }, 1059 "alias empty target": { 1060 Zone: "example.com", 1061 Type: "ALIAS", 1062 Target: "", 1063 }, 1064 "alias masters": { 1065 Zone: "example.com", 1066 Type: "ALIAS", 1067 Target: "10.0.0.1", 1068 Masters: []string{"master"}, 1069 }, 1070 "alias sign": { 1071 Zone: "example.com", 1072 Type: "ALIAS", 1073 Target: "10.0.0.1", 1074 SignAndServe: true, 1075 }, 1076 "alias sign algo": { 1077 Zone: "example.com", 1078 Type: "ALIAS", 1079 Target: "10.0.0.1", 1080 SignAndServe: false, 1081 SignAndServeAlgorithm: "foo", 1082 }, 1083 "primary bad target": { 1084 Zone: "example.com", 1085 Type: "PRIMARY", 1086 Target: "10.0.0.1", 1087 }, 1088 "primary bad masters": { 1089 Zone: "example.com", 1090 Type: "PRIMARY", 1091 Masters: []string{"foo"}, 1092 }, 1093 } 1094 1095 for name, test := range tests { 1096 t.Run(name, func(t *testing.T) { 1097 err := client.ValidateZone(context.Background(), &test) 1098 assert.NotNil(t, err) 1099 }) 1100 } 1101 }