github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/dns/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/v8/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, http.MethodGet, r.Method) 125 w.WriteHeader(test.responseStatus) 126 _, err := w.Write([]byte(test.responseBody)) 127 assert.NoError(t, err) 128 })) 129 client := mockAPIClient(t, mockServer) 130 result, err := client.ListZones( 131 session.ContextWithOptions( 132 context.Background(), 133 session.WithContextHeaders(test.headers)), test.args...) 134 if test.withError != nil { 135 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 136 return 137 } 138 require.NoError(t, err) 139 assert.Equal(t, test.expectedResponse, result) 140 }) 141 } 142 } 143 144 func TestDNS_GetZone(t *testing.T) { 145 tests := map[string]struct { 146 zone string 147 responseStatus int 148 responseBody string 149 expectedPath string 150 expectedResponse *ZoneResponse 151 withError error 152 }{ 153 "200 OK": { 154 zone: "example.com", 155 responseStatus: http.StatusOK, 156 responseBody: ` 157 { 158 "contractId": "1-2ABCDE", 159 "zone": "example.com", 160 "type": "primary", 161 "aliasCount": 1, 162 "signAndServe": true, 163 "signAndServeAlgorithm": "RSA_SHA256", 164 "versionId": "ae02357c-693d-4ac4-b33d-8352d9b7c786", 165 "lastModifiedDate": "2017-01-03T12:00:00Z", 166 "lastModifiedBy": "user28", 167 "lastActivationDate": "2017-01-03T12:00:00Z", 168 "activationState": "ACTIVE" 169 }`, 170 expectedPath: "/config-dns/v2/zones/example.com", 171 expectedResponse: &ZoneResponse{ 172 ContractID: "1-2ABCDE", 173 Zone: "example.com", 174 Type: "primary", 175 AliasCount: 1, 176 SignAndServe: true, 177 SignAndServeAlgorithm: "RSA_SHA256", 178 VersionID: "ae02357c-693d-4ac4-b33d-8352d9b7c786", 179 LastModifiedDate: "2017-01-03T12:00:00Z", 180 LastModifiedBy: "user28", 181 LastActivationDate: "2017-01-03T12:00:00Z", 182 ActivationState: "ACTIVE", 183 }, 184 }, 185 "500 internal server error": { 186 zone: "example.com", 187 responseStatus: http.StatusInternalServerError, 188 responseBody: ` 189 { 190 "type": "internal_error", 191 "title": "Internal Server Error", 192 "detail": "Error fetching authorities", 193 "status": 500 194 }`, 195 expectedPath: "/config-dns/v2/zones/example.com", 196 withError: &Error{ 197 Type: "internal_error", 198 Title: "Internal Server Error", 199 Detail: "Error fetching authorities", 200 StatusCode: http.StatusInternalServerError, 201 }, 202 }, 203 } 204 205 for name, test := range tests { 206 t.Run(name, func(t *testing.T) { 207 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 208 //assert.Equal(t, test.expectedPath, r.URL.String()) 209 assert.Equal(t, http.MethodGet, r.Method) 210 w.WriteHeader(test.responseStatus) 211 _, err := w.Write([]byte(test.responseBody)) 212 assert.NoError(t, err) 213 })) 214 client := mockAPIClient(t, mockServer) 215 result, err := client.GetZone(context.Background(), test.zone) 216 if test.withError != nil { 217 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 218 return 219 } 220 require.NoError(t, err) 221 assert.Equal(t, test.expectedResponse, result) 222 }) 223 } 224 } 225 226 func TestDNS_GetZoneMasterFile(t *testing.T) { 227 tests := map[string]struct { 228 zone string 229 responseStatus int 230 responseBody string 231 expectedPath string 232 expectedResponse string 233 withError error 234 }{ 235 "200 OK": { 236 zone: "example.com", 237 responseStatus: http.StatusOK, 238 responseBody: `"example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 239 example.com. 10000 IN NS ns1.akamaidns.com. 240 example.com. 10000 IN NS ns2.akamaidns.com. 241 example.com. 300 IN A 10.0.0.1 242 example.com. 300 IN A 10.0.0.2 243 www.example.com. 300 IN A 10.0.0.1 244 www.example.com. 300 IN A 10.0.0.2"`, 245 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 246 expectedResponse: `"example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 247 example.com. 10000 IN NS ns1.akamaidns.com. 248 example.com. 10000 IN NS ns2.akamaidns.com. 249 example.com. 300 IN A 10.0.0.1 250 example.com. 300 IN A 10.0.0.2 251 www.example.com. 300 IN A 10.0.0.1 252 www.example.com. 300 IN A 10.0.0.2"`, 253 }, 254 "500 internal server error": { 255 zone: "example.com", 256 responseStatus: http.StatusInternalServerError, 257 responseBody: ` 258 { 259 "type": "internal_error", 260 "title": "Internal Server Error", 261 "detail": "Error fetching authorities", 262 "status": 500 263 }`, 264 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 265 withError: &Error{ 266 Type: "internal_error", 267 Title: "Internal Server Error", 268 Detail: "Error fetching authorities", 269 StatusCode: http.StatusInternalServerError, 270 }, 271 }, 272 } 273 274 for name, test := range tests { 275 t.Run(name, func(t *testing.T) { 276 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 277 //assert.Equal(t, test.expectedPath, r.URL.String()) 278 assert.Equal(t, http.MethodGet, r.Method) 279 w.WriteHeader(test.responseStatus) 280 _, err := w.Write([]byte(test.responseBody)) 281 assert.NoError(t, err) 282 })) 283 client := mockAPIClient(t, mockServer) 284 result, err := client.GetMasterZoneFile(context.Background(), test.zone) 285 if test.withError != nil { 286 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 287 return 288 } 289 require.NoError(t, err) 290 assert.Equal(t, test.expectedResponse, result) 291 }) 292 } 293 } 294 295 func TestDNS_UpdateZoneMasterFile(t *testing.T) { 296 tests := map[string]struct { 297 zone string 298 masterfile string 299 responseStatus int 300 expectedPath string 301 responseBody string 302 withError error 303 }{ 304 "204 Updated": { 305 zone: "example.com", 306 masterfile: `"example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 307 example.com. 10000 IN NS ns1.akamaidns.com. 308 example.com. 10000 IN NS ns2.akamaidns.com. 309 example.com. 300 IN A 10.0.0.1 310 example.com. 300 IN A 10.0.0.2 311 www.example.com. 300 IN A 10.0.0.1 312 www.example.com. 300 IN A 10.0.0.2"`, 313 responseStatus: http.StatusNoContent, 314 responseBody: "", 315 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 316 }, 317 "500 internal server error": { 318 zone: "example.com", 319 masterfile: `"example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 320 example.com. 10000 IN NS ns1.akamaidns.com. 321 example.com. 10000 IN NS ns2.akamaidns.com. 322 example.com. 300 IN A 10.0.0.1 323 example.com. 300 IN A 10.0.0.2 324 www.example.com. 300 IN A 10.0.0.1 325 www.example.com. 300 IN A 10.0.0.2"`, 326 responseStatus: http.StatusInternalServerError, 327 responseBody: ` 328 { 329 "type": "internal_error", 330 "title": "Internal Server Error", 331 "detail": "Error creating zone", 332 "status": 500 333 }`, 334 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 335 withError: &Error{ 336 Type: "internal_error", 337 Title: "Internal Server Error", 338 Detail: "Error creating zone", 339 StatusCode: http.StatusInternalServerError, 340 }, 341 }, 342 } 343 344 for name, test := range tests { 345 t.Run(name, func(t *testing.T) { 346 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 347 assert.Equal(t, http.MethodPost, r.Method) 348 w.WriteHeader(test.responseStatus) 349 if len(test.responseBody) > 0 { 350 _, err := w.Write([]byte(test.responseBody)) 351 assert.NoError(t, err) 352 } 353 })) 354 client := mockAPIClient(t, mockServer) 355 err := client.PostMasterZoneFile(context.Background(), test.zone, test.masterfile) 356 if test.withError != nil { 357 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 358 return 359 } 360 require.NoError(t, err) 361 }) 362 } 363 } 364 365 func TestDNS_GetChangeList(t *testing.T) { 366 tests := map[string]struct { 367 zone string 368 responseStatus int 369 responseBody string 370 expectedPath string 371 expectedResponse *ChangeListResponse 372 withError error 373 }{ 374 "200 OK": { 375 zone: "example.com", 376 responseStatus: http.StatusOK, 377 responseBody: ` 378 { 379 "zone": "example.com", 380 "changeTag": "476754f4-d605-479f-853b-db854d7254fa", 381 "zoneVersionId": "1d9c887c-49bb-4382-87a6-d1bf690aa58f", 382 "lastModifiedDate": "2017-02-01T12:00:12.524Z", 383 "stale": false 384 }`, 385 expectedPath: "/config-dns/v2/zones/example.com", 386 expectedResponse: &ChangeListResponse{ 387 Zone: "example.com", 388 ChangeTag: "476754f4-d605-479f-853b-db854d7254fa", 389 ZoneVersionID: "1d9c887c-49bb-4382-87a6-d1bf690aa58f", 390 LastModifiedDate: "2017-02-01T12:00:12.524Z", 391 Stale: false, 392 }, 393 }, 394 "500 internal server error": { 395 zone: "example.com", 396 responseStatus: http.StatusInternalServerError, 397 responseBody: ` 398 { 399 "type": "internal_error", 400 "title": "Internal Server Error", 401 "detail": "Error fetching authorities", 402 "status": 500 403 }`, 404 expectedPath: "/config-dns/v2/zones/example.com", 405 withError: &Error{ 406 Type: "internal_error", 407 Title: "Internal Server Error", 408 Detail: "Error fetching authorities", 409 StatusCode: http.StatusInternalServerError, 410 }, 411 }, 412 } 413 414 for name, test := range tests { 415 t.Run(name, func(t *testing.T) { 416 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 417 //assert.Equal(t, test.expectedPath, r.URL.String()) 418 assert.Equal(t, http.MethodGet, r.Method) 419 w.WriteHeader(test.responseStatus) 420 _, err := w.Write([]byte(test.responseBody)) 421 assert.NoError(t, err) 422 })) 423 client := mockAPIClient(t, mockServer) 424 result, err := client.GetChangeList(context.Background(), test.zone) 425 if test.withError != nil { 426 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 427 return 428 } 429 require.NoError(t, err) 430 assert.Equal(t, test.expectedResponse, result) 431 }) 432 } 433 } 434 435 func TestDNS_GetMasterZoneFile(t *testing.T) { 436 tests := map[string]struct { 437 zone string 438 responseStatus int 439 responseBody string 440 expectedPath string 441 expectedResponse string 442 withError error 443 }{ 444 "200 OK": { 445 zone: "example.com", 446 responseStatus: http.StatusOK, 447 responseBody: ` 448 example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 449 example.com. 10000 IN NS ns1.akamaidns.com. 450 example.com. 10000 IN NS ns2.akamaidns.com. 451 example.com. 300 IN A 10.0.0.1 452 example.com. 300 IN A 10.0.0.2 453 www.example.com. 300 IN A 10.0.0.1 454 www.example.com. 300 IN A 10.0.0.2`, 455 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 456 expectedResponse: ` 457 example.com. 10000 IN SOA ns1.akamaidns.com. webmaster.example.com. 1 28800 14400 2419200 86400 458 example.com. 10000 IN NS ns1.akamaidns.com. 459 example.com. 10000 IN NS ns2.akamaidns.com. 460 example.com. 300 IN A 10.0.0.1 461 example.com. 300 IN A 10.0.0.2 462 www.example.com. 300 IN A 10.0.0.1 463 www.example.com. 300 IN A 10.0.0.2`, 464 }, 465 "500 internal server error": { 466 zone: "example.com", 467 responseStatus: http.StatusInternalServerError, 468 responseBody: ` 469 { 470 "type": "internal_error", 471 "title": "Internal Server Error", 472 "detail": "Error fetching master zone file", 473 "status": 500 474 }`, 475 expectedPath: "/config-dns/v2/zones/example.com/zone-file", 476 withError: &Error{ 477 Type: "internal_error", 478 Title: "Internal Server Error", 479 Detail: "Error fetching master zone file", 480 StatusCode: http.StatusInternalServerError, 481 }, 482 }, 483 } 484 485 for name, test := range tests { 486 t.Run(name, func(t *testing.T) { 487 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 488 assert.Equal(t, test.expectedPath, r.URL.String()) 489 assert.Equal(t, http.MethodGet, r.Method) 490 w.WriteHeader(test.responseStatus) 491 if len(test.responseBody) > 0 { 492 _, err := w.Write([]byte(test.responseBody)) 493 assert.NoError(t, err) 494 } 495 })) 496 client := mockAPIClient(t, mockServer) 497 result, err := client.GetMasterZoneFile(context.Background(), test.zone) 498 if test.withError != nil { 499 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 500 return 501 } 502 require.NoError(t, err) 503 assert.Equal(t, test.expectedResponse, result) 504 }) 505 } 506 } 507 508 func TestDNS_CreateZone(t *testing.T) { 509 tests := map[string]struct { 510 zone ZoneCreate 511 query ZoneQueryString 512 responseStatus int 513 responseBody string 514 expectedPath string 515 withError error 516 }{ 517 "201 Created": { 518 zone: ZoneCreate{ 519 Zone: "example.com", 520 ContractID: "1-2ABCDE", 521 Type: "primary", 522 }, 523 responseStatus: http.StatusCreated, 524 responseBody: ` 525 { 526 "contractId": "1-2ABCDE", 527 "zone": "other.com", 528 "type": "primary", 529 "aliasCount": 1, 530 "signAndServe": false, 531 "comment": "Initial add", 532 "versionId": "7949b2db-ac43-4773-a3ec-dc93202142fd", 533 "lastModifiedDate": "2016-12-11T03:21:00Z", 534 "lastModifiedBy": "user31", 535 "lastActivationDate": "2017-01-03T12:00:00Z", 536 "activationState": "ERROR", 537 "masters": [ 538 "1.2.3.4", 539 "1.2.3.5" 540 ], 541 "tsigKey": { 542 "name": "other.com.akamai.com.", 543 "algorithm": "hmac-sha512", 544 "secret": "Ok1qR5IW1ajVka5cHPEJQIXfLyx5V3PSkFBROAzOn21JumDq6nIpoj6H8rfj5Uo+Ok55ZWQ0Wgrf302fDscHLw==" 545 } 546 }`, 547 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 548 }, 549 "500 internal server error": { 550 zone: ZoneCreate{ 551 Zone: "example.com", 552 ContractID: "1-2ABCDE", 553 Type: "secondary", 554 }, 555 responseStatus: http.StatusInternalServerError, 556 responseBody: ` 557 { 558 "type": "internal_error", 559 "title": "Internal Server Error", 560 "detail": "Error creating zone", 561 "status": 500 562 }`, 563 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 564 withError: &Error{ 565 Type: "internal_error", 566 Title: "Internal Server Error", 567 Detail: "Error creating zone", 568 StatusCode: http.StatusInternalServerError, 569 }, 570 }, 571 } 572 573 for name, test := range tests { 574 t.Run(name, func(t *testing.T) { 575 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 576 assert.Equal(t, http.MethodPost, r.Method) 577 w.WriteHeader(test.responseStatus) 578 if len(test.responseBody) > 0 { 579 _, err := w.Write([]byte(test.responseBody)) 580 assert.NoError(t, err) 581 } 582 })) 583 client := mockAPIClient(t, mockServer) 584 err := client.CreateZone(context.Background(), &test.zone, test.query, true) 585 if test.withError != nil { 586 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 587 return 588 } 589 require.NoError(t, err) 590 }) 591 } 592 } 593 594 func TestDNS_SaveChangelist(t *testing.T) { 595 tests := map[string]struct { 596 zone ZoneCreate 597 responseStatus int 598 responseBody string 599 expectedPath string 600 withError error 601 }{ 602 "201 Created": { 603 zone: ZoneCreate{ 604 Zone: "example.com", 605 ContractID: "1-2ABCDE", 606 Type: "primary", 607 }, 608 responseStatus: http.StatusCreated, 609 expectedPath: "/config-dns/v2/changelists?zone=example.com", 610 }, 611 "500 internal server error": { 612 zone: ZoneCreate{ 613 Zone: "example.com", 614 ContractID: "1-2ABCDE", 615 Type: "secondary", 616 }, 617 responseStatus: http.StatusInternalServerError, 618 responseBody: ` 619 { 620 "type": "internal_error", 621 "title": "Internal Server Error", 622 "detail": "Error creating zone", 623 "status": 500 624 }`, 625 expectedPath: "/config-dns/v2/changelists?zone=example.com", 626 withError: &Error{ 627 Type: "internal_error", 628 Title: "Internal Server Error", 629 Detail: "Error creating zone", 630 StatusCode: http.StatusInternalServerError, 631 }, 632 }, 633 } 634 635 for name, test := range tests { 636 t.Run(name, func(t *testing.T) { 637 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 638 assert.Equal(t, http.MethodPost, r.Method) 639 w.WriteHeader(test.responseStatus) 640 if len(test.responseBody) > 0 { 641 _, err := w.Write([]byte(test.responseBody)) 642 assert.NoError(t, err) 643 } 644 })) 645 client := mockAPIClient(t, mockServer) 646 err := client.SaveChangelist(context.Background(), &test.zone) 647 if test.withError != nil { 648 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 649 return 650 } 651 require.NoError(t, err) 652 }) 653 } 654 } 655 656 func TestDNS_SubmitChangelist(t *testing.T) { 657 tests := map[string]struct { 658 zone ZoneCreate 659 responseStatus int 660 responseBody string 661 expectedPath string 662 withError error 663 }{ 664 "204 No Content": { 665 zone: ZoneCreate{ 666 Zone: "example.com", 667 ContractID: "1-2ABCDE", 668 Type: "primary", 669 }, 670 responseStatus: http.StatusNoContent, 671 expectedPath: "/config-dns/v2/changelists?zone=example.com", 672 }, 673 "500 internal server error": { 674 zone: ZoneCreate{ 675 Zone: "example.com", 676 ContractID: "1-2ABCDE", 677 Type: "secondary", 678 }, 679 responseStatus: http.StatusInternalServerError, 680 responseBody: ` 681 { 682 "type": "internal_error", 683 "title": "Internal Server Error", 684 "detail": "Error creating zone", 685 "status": 500 686 }`, 687 expectedPath: "/config-dns/v2/changelists?zone=example.com", 688 withError: &Error{ 689 Type: "internal_error", 690 Title: "Internal Server Error", 691 Detail: "Error creating zone", 692 StatusCode: http.StatusInternalServerError, 693 }, 694 }, 695 } 696 697 for name, test := range tests { 698 t.Run(name, func(t *testing.T) { 699 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 700 assert.Equal(t, http.MethodPost, r.Method) 701 w.WriteHeader(test.responseStatus) 702 if len(test.responseBody) > 0 { 703 _, err := w.Write([]byte(test.responseBody)) 704 assert.NoError(t, err) 705 } 706 })) 707 client := mockAPIClient(t, mockServer) 708 err := client.SubmitChangelist(context.Background(), &test.zone) 709 if test.withError != nil { 710 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 711 return 712 } 713 require.NoError(t, err) 714 }) 715 } 716 } 717 718 func TestDNS_UpdateZone(t *testing.T) { 719 tests := map[string]struct { 720 zone ZoneCreate 721 query ZoneQueryString 722 responseStatus int 723 responseBody string 724 expectedPath string 725 withError error 726 }{ 727 "200 OK": { 728 zone: ZoneCreate{ 729 Zone: "example.com", 730 ContractID: "1-2ABCDE", 731 Type: "primary", 732 }, 733 responseStatus: http.StatusOK, 734 responseBody: ` 735 { 736 "contractId": "1-2ABCDE", 737 "zone": "other.com", 738 "type": "primary", 739 "aliasCount": 1, 740 "signAndServe": false, 741 "comment": "Initial add", 742 "versionId": "7949b2db-ac43-4773-a3ec-dc93202142fd", 743 "lastModifiedDate": "2016-12-11T03:21:00Z", 744 "lastModifiedBy": "user31", 745 "lastActivationDate": "2017-01-03T12:00:00Z", 746 "activationState": "ERROR", 747 "masters": [ 748 "1.2.3.4", 749 "1.2.3.5" 750 ], 751 "tsigKey": { 752 "name": "other.com.akamai.com.", 753 "algorithm": "hmac-sha512", 754 "secret": "Ok1qR5IW1ajVka5cHPEJQIXfLyx5V3PSkFBROAzOn21JumDq6nIpoj6H8rfj5Uo+Ok55ZWQ0Wgrf302fDscHLw==" 755 } 756 }`, 757 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 758 }, 759 "500 internal server error": { 760 zone: ZoneCreate{ 761 Zone: "example.com", 762 ContractID: "1-2ABCDE", 763 Type: "secondary", 764 }, 765 responseStatus: http.StatusInternalServerError, 766 responseBody: ` 767 { 768 "type": "internal_error", 769 "title": "Internal Server Error", 770 "detail": "Error creating zone", 771 "status": 500 772 }`, 773 expectedPath: "/config-dns/v2/zones?contractId=1-2ABCDE", 774 withError: &Error{ 775 Type: "internal_error", 776 Title: "Internal Server Error", 777 Detail: "Error creating zone", 778 StatusCode: http.StatusInternalServerError, 779 }, 780 }, 781 } 782 783 for name, test := range tests { 784 t.Run(name, func(t *testing.T) { 785 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 786 assert.Equal(t, http.MethodPut, r.Method) 787 w.WriteHeader(test.responseStatus) 788 if len(test.responseBody) > 0 { 789 _, err := w.Write([]byte(test.responseBody)) 790 assert.NoError(t, err) 791 } 792 })) 793 client := mockAPIClient(t, mockServer) 794 err := client.UpdateZone(context.Background(), &test.zone, test.query) 795 if test.withError != nil { 796 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 797 return 798 } 799 require.NoError(t, err) 800 }) 801 } 802 } 803 804 func TestDNS_GetZoneNames(t *testing.T) { 805 tests := map[string]struct { 806 zone string 807 responseStatus int 808 responseBody string 809 expectedPath string 810 expectedResponse *ZoneNamesResponse 811 withError error 812 }{ 813 "200 OK": { 814 zone: "example.com", 815 responseStatus: http.StatusOK, 816 responseBody: ` 817 { 818 "names": [ 819 "example.com", 820 "www.example.com", 821 "ftp.example.com", 822 "space.example.com", 823 "bar.example.com" 824 ] 825 }`, 826 expectedPath: "/config-dns/v2/zones/example.com/names", 827 expectedResponse: &ZoneNamesResponse{ 828 Names: []string{"example.com", "www.example.com", "ftp.example.com", "space.example.com", "bar.example.com"}, 829 }, 830 }, 831 "500 internal server error": { 832 zone: "example.com", 833 responseStatus: http.StatusInternalServerError, 834 responseBody: ` 835 { 836 "type": "internal_error", 837 "title": "Internal Server Error", 838 "detail": "Error fetching authorities", 839 "status": 500 840 }`, 841 expectedPath: "/config-dns/v2/zones/example.com/names", 842 withError: &Error{ 843 Type: "internal_error", 844 Title: "Internal Server Error", 845 Detail: "Error fetching authorities", 846 StatusCode: http.StatusInternalServerError, 847 }, 848 }, 849 } 850 851 for name, test := range tests { 852 t.Run(name, func(t *testing.T) { 853 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 854 //assert.Equal(t, test.expectedPath, r.URL.String()) 855 assert.Equal(t, http.MethodGet, r.Method) 856 w.WriteHeader(test.responseStatus) 857 _, err := w.Write([]byte(test.responseBody)) 858 assert.NoError(t, err) 859 })) 860 client := mockAPIClient(t, mockServer) 861 result, err := client.GetZoneNames(context.Background(), test.zone) 862 if test.withError != nil { 863 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 864 return 865 } 866 require.NoError(t, err) 867 assert.Equal(t, test.expectedResponse, result) 868 }) 869 } 870 } 871 872 func TestDNS_GetZoneNameTypes(t *testing.T) { 873 tests := map[string]struct { 874 zone string 875 zname string 876 responseStatus int 877 responseBody string 878 expectedPath string 879 expectedResponse *ZoneNameTypesResponse 880 withError error 881 }{ 882 "200 OK": { 883 zone: "example.com", 884 zname: "names", 885 responseStatus: http.StatusOK, 886 responseBody: ` 887 { 888 "types": [ 889 "A", 890 "AAAA", 891 "MX" 892 ] 893 }`, 894 expectedPath: "/config-dns/v2/zones/example.com/names/www.example.com/types", 895 expectedResponse: &ZoneNameTypesResponse{ 896 Types: []string{"A", "AAAA", "MX"}, 897 }, 898 }, 899 "500 internal server error": { 900 zone: "example.com", 901 zname: "names", 902 responseStatus: http.StatusInternalServerError, 903 responseBody: ` 904 { 905 "type": "internal_error", 906 "title": "Internal Server Error", 907 "detail": "Error fetching authorities", 908 "status": 500 909 }`, 910 expectedPath: "/config-dns/v2/zones/example.com/names/www.example.com/types", 911 withError: &Error{ 912 Type: "internal_error", 913 Title: "Internal Server Error", 914 Detail: "Error fetching authorities", 915 StatusCode: http.StatusInternalServerError, 916 }, 917 }, 918 } 919 920 for name, test := range tests { 921 t.Run(name, func(t *testing.T) { 922 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 923 //assert.Equal(t, test.expectedPath, r.URL.String()) 924 assert.Equal(t, http.MethodGet, r.Method) 925 w.WriteHeader(test.responseStatus) 926 _, err := w.Write([]byte(test.responseBody)) 927 assert.NoError(t, err) 928 })) 929 client := mockAPIClient(t, mockServer) 930 result, err := client.GetZoneNameTypes(context.Background(), test.zname, test.zone) 931 if test.withError != nil { 932 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 933 return 934 } 935 require.NoError(t, err) 936 assert.Equal(t, test.expectedResponse, result) 937 }) 938 } 939 } 940 941 func Test_ValidateZoneErrors(t *testing.T) { 942 tests := map[string]ZoneCreate{ 943 "empty zone": {}, 944 "bad type": { 945 Zone: "example.com", 946 Type: "BAD", 947 }, 948 "secondary tsig": { 949 Zone: "example.com", 950 Type: "PRIMARY", 951 TSIGKey: &TSIGKey{ 952 Name: "example.com", 953 }, 954 }, 955 "alias empty target": { 956 Zone: "example.com", 957 Type: "ALIAS", 958 Target: "", 959 }, 960 "alias masters": { 961 Zone: "example.com", 962 Type: "ALIAS", 963 Target: "10.0.0.1", 964 Masters: []string{"master"}, 965 }, 966 "alias sign": { 967 Zone: "example.com", 968 Type: "ALIAS", 969 Target: "10.0.0.1", 970 SignAndServe: true, 971 }, 972 "alias sign algo": { 973 Zone: "example.com", 974 Type: "ALIAS", 975 Target: "10.0.0.1", 976 SignAndServe: false, 977 SignAndServeAlgorithm: "foo", 978 }, 979 "primary bad target": { 980 Zone: "example.com", 981 Type: "PRIMARY", 982 Target: "10.0.0.1", 983 }, 984 "primary bad masters": { 985 Zone: "example.com", 986 Type: "PRIMARY", 987 Masters: []string{"foo"}, 988 }, 989 } 990 991 for name, test := range tests { 992 t.Run(name, func(t *testing.T) { 993 err := ValidateZone(&test) 994 assert.NotNil(t, err) 995 }) 996 } 997 }