1// +build integration
2
3/*
4Copyright 2018 Comcast Cable Communications Management, LLC
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8Unless required by applicable law or agreed to in writing, software
9distributed under the License is distributed on an "AS IS" BASIS,
10WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11See the License for the specific language governing permissions and
12limitations under the License.
13*/
14
15package vinyldns
16
17import (
18	"fmt"
19	"testing"
20	"time"
21)
22
23// client() assumes a VinylDNS is running on localhost:9000 with the default access and secret keys
24// see `make start-api` for a Make task in starting VinylDNS
25func client() *Client {
26	return NewClient(ClientConfiguration{
27		"okAccessKey",
28		"okSecretKey",
29		"http://localhost:9000",
30		"go-vinyldns integration testing",
31	})
32}
33
34func TestGroupCreateIntegration(t *testing.T) {
35	c := client()
36	users := []User{
37		{
38			UserName:  "ok",
39			FirstName: "ok",
40			LastName:  "ok",
41			Email:     "test@test.com",
42			ID:        "ok",
43		},
44	}
45	gc, err := c.GroupCreate(&Group{
46		Name:        "test-group",
47		Description: "a test group",
48		Email:       "test@vinyldns.com",
49		Admins:      users,
50		Members:     users,
51	})
52	if err != nil {
53		t.Error(err)
54	}
55
56	gg, err := c.Group(gc.ID)
57	if err != nil {
58		t.Error(err)
59	}
60
61	if gg.ID != gc.ID {
62		t.Error(err)
63	}
64}
65
66func TestGroupsListAllIntegrationFilterForNonexistentName(t *testing.T) {
67	c := client()
68	zones, err := c.ZonesListAll(ListFilter{
69		NameFilter: "foo",
70	})
71	if err != nil {
72		t.Error(err)
73	}
74
75	if len(zones) > 0 {
76		t.Error("Expected GroupsListAll for groups named 'foo' to yield no results")
77	}
78}
79
80func TestGroupAdminsIntegration(t *testing.T) {
81	c := client()
82	groups, err := c.Groups()
83	if err != nil {
84		t.Error(err)
85	}
86
87	gID := groups[0].ID
88	admins, err := c.GroupAdmins(gID)
89	if err != nil {
90		t.Error(err)
91	}
92
93	if admins[0].UserName != "ok" {
94		t.Error(fmt.Sprintf("unable to get group admins for group %s", gID))
95	}
96}
97
98func TestZoneNameExistsForNonexistentZoneIntegration(t *testing.T) {
99	c := client()
100	exists, err := c.ZoneNameExists("foo")
101	if err != nil {
102		t.Error(err)
103	}
104	if exists != false {
105		t.Error(fmt.Sprintf("expected ZoneNameExists to return false; got %t", exists))
106	}
107}
108
109func TestZoneCreateIntegration(t *testing.T) {
110	c := client()
111	groups, err := c.Groups()
112	if err != nil {
113		t.Error(err)
114	}
115	connection := &ZoneConnection{
116		Name:          "ok.",
117		KeyName:       "vinyldns.",
118		Key:           "nzisn+4G2ldMn0q1CV3vsg==",
119		PrimaryServer: "vinyldns-bind9",
120	}
121
122	zone := &Zone{
123		Name:               "ok.",
124		Email:              "email@email.com",
125		AdminGroupID:       groups[0].ID,
126		Connection:         connection,
127		TransferConnection: connection,
128	}
129
130	zc, err := c.ZoneCreate(zone)
131	if err != nil {
132		t.Error(err)
133	}
134
135	createdZoneID := zc.Zone.ID
136	limit := 10
137	for i := 0; i < limit; time.Sleep(10 * time.Second) {
138		i++
139
140		zg, err := c.Zone(createdZoneID)
141		if err == nil && zg.ID != createdZoneID {
142			t.Error(fmt.Sprintf("unable to get zone %s", createdZoneID))
143		}
144		if err == nil && zg.ID == createdZoneID {
145			break
146		}
147
148		if i == (limit - 1) {
149			fmt.Printf("%d retries reached in polling for zone %s", limit, createdZoneID)
150			t.Error(err)
151		}
152	}
153}
154
155func TestZoneNameExistsForExistentZoneIntegration(t *testing.T) {
156	c := client()
157	exists, err := c.ZoneNameExists("ok.")
158	if err != nil {
159		t.Error(err)
160	}
161	if exists != true {
162		t.Error(fmt.Sprintf("expected ZoneNameExists to return true; got %t", exists))
163	}
164}
165
166func TestZoneByNameIntegration(t *testing.T) {
167	c := client()
168	z, err := c.ZoneByName("ok")
169	if err != nil {
170		t.Error(err)
171	}
172
173	if z.Name != "ok." {
174		t.Error(fmt.Sprintf("unable to get ZoneByName %s", "ok."))
175	}
176}
177
178func TestZonesListAllIntegrationFilterForNonexistentName(t *testing.T) {
179	c := client()
180	zones, err := c.ZonesListAll(ListFilter{
181		NameFilter: "foo",
182	})
183	if err != nil {
184		t.Error(err)
185	}
186
187	if len(zones) > 0 {
188		t.Error("Expected ZonesListAll for zones named 'foo' to yield no results")
189	}
190}
191
192func TestZoneChangesIntegration(t *testing.T) {
193	c := client()
194	zones, err := c.ZonesListAll(ListFilter{})
195	if err != nil {
196		t.Error(err)
197	}
198
199	changes, err := c.ZoneChanges(zones[0].ID)
200	if err != nil {
201		t.Error(err)
202	}
203
204	if changes.ZoneID != zones[0].ID {
205		t.Error("Expected ZoneChanges to yield correct ID")
206	}
207
208	if len(changes.ZoneChanges) <= 0 {
209		t.Error("Expected ZoneChanges to yield results")
210	}
211}
212
213func TestZoneChangesListAllIntegration(t *testing.T) {
214	c := client()
215	zones, err := c.ZonesListAll(ListFilter{})
216	if err != nil {
217		t.Error(err)
218	}
219
220	changes, err := c.ZoneChangesListAll(zones[0].ID, ListFilter{})
221	if err != nil {
222		t.Error(err)
223	}
224
225	if changes[0].Zone.ID != zones[0].ID {
226		t.Error("Expected ZoneChangesListAll to yield correct ID")
227	}
228
229	if len(changes) <= 0 {
230		t.Error("Expected ZoneChangesListAll to yield results")
231	}
232}
233
234func TestRecordSetCreateIntegrationARecord(t *testing.T) {
235	c := client()
236	zs, err := c.ZonesListAll(ListFilter{})
237	if err != nil {
238		t.Error(err)
239	}
240	rc, err := c.RecordSetCreate(&RecordSet{
241		Name:   "integration-test",
242		ZoneID: zs[0].ID,
243		Type:   "A",
244		TTL:    60,
245		Records: []Record{
246			{
247				Address: "127.0.0.1",
248			},
249		},
250	})
251	if err != nil {
252		t.Error(err)
253	}
254	createdID := rc.RecordSet.ID
255	limit := 10
256	for i := 0; i < limit; time.Sleep(10 * time.Second) {
257		i++
258
259		rg, err := c.RecordSet(zs[0].ID, createdID)
260		if err == nil && rg.ID != createdID {
261			t.Error(fmt.Sprintf("unable to get record set %s", createdID))
262		}
263		if err == nil && rg.ID == createdID {
264			break
265		}
266
267		if i == (limit - 1) {
268			fmt.Printf("%d retries reached in polling for record set %s", limit, createdID)
269			t.Error(err)
270		}
271	}
272}
273
274func TestRecordSetCreateIntegrationNSRecord(t *testing.T) {
275	c := client()
276	zs, err := c.ZonesListAll(ListFilter{})
277	if err != nil {
278		t.Error(err)
279	}
280	rc, err := c.RecordSetCreate(&RecordSet{
281		Name:   "integration-test",
282		ZoneID: zs[0].ID,
283		Type:   "NS",
284		TTL:    60,
285		Records: []Record{
286			{
287				NSDName: "ns1.parent.com.",
288			},
289		},
290	})
291	if err != nil {
292		t.Error(err)
293	}
294	createdID := rc.RecordSet.ID
295	limit := 10
296	for i := 0; i < limit; time.Sleep(10 * time.Second) {
297		i++
298
299		rg, err := c.RecordSet(zs[0].ID, createdID)
300		if err == nil && rg.ID != createdID {
301			t.Error(fmt.Sprintf("unable to get record set %s", createdID))
302		}
303		if err == nil && rg.ID == createdID {
304			break
305		}
306
307		if i == (limit - 1) {
308			fmt.Printf("%d retries reached in polling for record set %s", limit, createdID)
309			t.Error(err)
310		}
311	}
312}
313
314func TestRecordSetUpdateIntegrationARecord(t *testing.T) {
315	c := client()
316	zs, err := c.ZonesListAll(ListFilter{})
317	if err != nil {
318		t.Error(err)
319	}
320	rs := &RecordSet{
321		Name:   "integration-test-record-set-update",
322		ZoneID: zs[0].ID,
323		Type:   "A",
324		TTL:    60,
325		Records: []Record{
326			{
327				Address: "127.0.0.1",
328			},
329		},
330	}
331	rc, err := c.RecordSetCreate(rs)
332	if err != nil {
333		t.Error(err)
334	}
335	createdID := rc.RecordSet.ID
336	limit := 10
337	for i := 0; i < limit; time.Sleep(10 * time.Second) {
338		i++
339
340		rg, err := c.RecordSet(zs[0].ID, createdID)
341		if err == nil && rg.ID != createdID {
342			t.Error(fmt.Sprintf("unable to get record set %s", createdID))
343		}
344		if err == nil && rg.ID == createdID {
345			updatedName := "updated-integration-test-record-set-update"
346			rs.ID = createdID
347			rs.Name = updatedName
348			u, err := c.RecordSetUpdate(rs)
349			if err == nil && u.RecordSet.ID != createdID && u.RecordSet.Name != updatedName {
350				t.Error(fmt.Sprintf("unable to updated record set %s", createdID))
351			}
352			break
353		}
354
355		if i == (limit - 1) {
356			fmt.Printf("%d retries reached in polling for record set %s", limit, createdID)
357			t.Error(err)
358		}
359	}
360}
361
362func TestRecordSetsListAllIntegrationFilterForExistentName(t *testing.T) {
363	c := client()
364	zs, err := c.ZonesListAll(ListFilter{})
365	if err != nil {
366		t.Error(err)
367	}
368
369	records, err := c.RecordSetsListAll(zs[0].ID, ListFilter{
370		NameFilter: "foo",
371	})
372	if err != nil {
373		t.Error(err)
374	}
375
376	if len(records) < 1 {
377		t.Error("Expected RecordSetsListAll for records named 'foo' to yield results")
378	}
379}
380
381func TestRecordSetsListAllIntegrationFilterForNonexistentName(t *testing.T) {
382	c := client()
383	zs, err := c.ZonesListAll(ListFilter{})
384	if err != nil {
385		t.Error(err)
386	}
387
388	records, err := c.RecordSetsListAll(zs[0].ID, ListFilter{
389		NameFilter: "thisdoesnotexist",
390	})
391	if err != nil {
392		t.Error(err)
393	}
394
395	if len(records) > 0 {
396		t.Error("Expected RecordSetsListAll for records named 'thisdoesnotexist' to yield no results")
397	}
398}
399
400func TestRecordSetsGlobalListAllIntegrationFilterForExistentName(t *testing.T) {
401	c := client()
402	rName := "foo"
403
404	records, err := c.RecordSetsGlobalListAll(GlobalListFilter{
405		RecordNameFilter: "*" + rName + "*",
406	})
407	if err != nil {
408		t.Error(err)
409	}
410
411	if len(records) < 1 {
412		t.Error(fmt.Sprintf("Expected RecordSetsGlobalListAll for records named '%s' to yield results", rName))
413	}
414
415	if records[0].Name != rName {
416		t.Error(fmt.Sprintf("Expected RecordSetsGlobalListAll for records named '%s' to return the matching record", rName))
417	}
418}
419
420func TestRecordSetsGlobalListAllIntegrationFilterForNonexistentName(t *testing.T) {
421	c := client()
422	records, err := c.RecordSetsGlobalListAll(GlobalListFilter{
423		RecordNameFilter: "thisdoesnotexist",
424	})
425	if err != nil {
426		t.Error(err)
427	}
428
429	if len(records) > 0 {
430		t.Error("Expected RecordSetsListAll for records named 'thisdoesnotexist' to yield no results")
431	}
432}
433
434func TestRecordSetDeleteIntegration(t *testing.T) {
435	c := client()
436	zs, err := c.ZonesListAll(ListFilter{})
437	if err != nil {
438		t.Error(err)
439	}
440	z := zs[0].ID
441
442	rs, err := c.RecordSetsListAll(z, ListFilter{})
443	if err != nil {
444		t.Error(err)
445	}
446
447	var r string
448	for _, rec := range rs {
449		if rec.Name == "integration-test" {
450			r = rec.ID
451			break
452		}
453	}
454
455	_, err = c.RecordSetDelete(z, r)
456	if err != nil {
457		t.Error(err)
458	}
459}
460
461func TestRecordSetChangesIntegration(t *testing.T) {
462	c := client()
463	zones, err := c.ZonesListAll(ListFilter{})
464	if err != nil {
465		t.Error(err)
466	}
467
468	changes, err := c.RecordSetChanges(zones[0].ID, ListFilter{})
469	if err != nil {
470		t.Error(err)
471	}
472
473	if len(changes.RecordSetChanges) <= 0 {
474		t.Error("Expected RecordSetChanges to return results")
475	}
476}
477
478func TestRecordSetChangesIntegrationWithMaxItems(t *testing.T) {
479	c := client()
480	zones, err := c.ZonesListAll(ListFilter{})
481	if err != nil {
482		t.Error(err)
483	}
484
485	changes, err := c.RecordSetChanges(zones[0].ID, ListFilter{
486		MaxItems: 1,
487	})
488	if err != nil {
489		t.Error(err)
490	}
491
492	if len(changes.RecordSetChanges) > 1 {
493		t.Error("Expected RecordSetChanges to return only 1 results")
494	}
495}
496
497func TestRecordSetChangesListAllIntegration(t *testing.T) {
498	c := client()
499	zones, err := c.ZonesListAll(ListFilter{})
500	if err != nil {
501		t.Error(err)
502	}
503
504	changes, err := c.RecordSetChangesListAll(zones[0].ID, ListFilter{})
505	if err != nil {
506		t.Error(err)
507	}
508
509	if len(changes) <= 0 {
510		t.Error("Expected RecordSetChangesListAll to yield results")
511	}
512}
513
514func TestZoneDeleteIntegration(t *testing.T) {
515	c := client()
516	zs, err := c.ZonesListAll(ListFilter{})
517	if err != nil {
518		t.Error(err)
519	}
520	z := zs[0].ID
521
522	_, err = c.ZoneDelete(z)
523	if err != nil {
524		t.Error(err)
525	}
526
527	limit := 10
528	for i := 0; i < limit; time.Sleep(10 * time.Second) {
529		i++
530
531		exists, err := c.ZoneExists(z)
532		if err != nil {
533			t.Error(err)
534			break
535		}
536
537		if !exists {
538			break
539		}
540
541		if i == (limit - 1) {
542			fmt.Printf("%d retries reached in waiting for zone deletion of %s", limit, z)
543			t.Error(err)
544		}
545	}
546}
547
548func TestGroupDeleteIntegration(t *testing.T) {
549	c := client()
550	gs, err := c.Groups()
551	if err != nil {
552		t.Error(err)
553	}
554	g := gs[0].ID
555	_, err = c.GroupDelete(g)
556	if err != nil {
557		t.Error(err)
558	}
559}
560