/* Copyright 2022 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package ibmcloud import ( "context" "fmt" "net/http" "net/http/httptest" "testing" "time" "github.com/IBM/go-sdk-core/v5/core" "github.com/IBM/networking-go-sdk/dnsrecordsv1" "github.com/IBM/networking-go-sdk/dnssvcsv1" . "github.com/onsi/ginkgo" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "sigs.k8s.io/external-dns/endpoint" "sigs.k8s.io/external-dns/plan" "sigs.k8s.io/external-dns/provider" ) func NewMockIBMCloudDNSAPI() *mockIbmcloudClientInterface { // Setup public example responses firstPublicRecord := dnsrecordsv1.DnsrecordDetails{ ID: core.StringPtr("123"), Name: core.StringPtr("test.example.com"), Type: core.StringPtr("A"), Content: core.StringPtr("1.2.3.4"), Proxied: core.BoolPtr(true), TTL: core.Int64Ptr(int64(120)), } secondPublicRecord := dnsrecordsv1.DnsrecordDetails{ ID: core.StringPtr("456"), Name: core.StringPtr("test.example.com"), Type: core.StringPtr("TXT"), Proxied: core.BoolPtr(false), Content: core.StringPtr("\"heritage=external-dns,external-dns/owner=tower-pdns\""), TTL: core.Int64Ptr(int64(120)), } publicRecordsResult := []dnsrecordsv1.DnsrecordDetails{firstPublicRecord, secondPublicRecord} publicRecordsResultInfo := &dnsrecordsv1.ResultInfo{ Page: core.Int64Ptr(int64(1)), TotalCount: core.Int64Ptr(int64(1)), } publicRecordsResp := &dnsrecordsv1.ListDnsrecordsResp{ Result: publicRecordsResult, ResultInfo: publicRecordsResultInfo, } // Setup private example responses firstPrivateZone := dnssvcsv1.Dnszone{ ID: core.StringPtr("123"), Name: core.StringPtr("example.com"), State: core.StringPtr(zoneStatePendingNetwork), } secondPrivateZone := dnssvcsv1.Dnszone{ ID: core.StringPtr("456"), Name: core.StringPtr("example1.com"), State: core.StringPtr(zoneStateActive), } privateZones := []dnssvcsv1.Dnszone{firstPrivateZone, secondPrivateZone} listZonesResp := &dnssvcsv1.ListDnszones{ Dnszones: privateZones, } firstPrivateRecord := dnssvcsv1.ResourceRecord{ ID: core.StringPtr("123"), Name: core.StringPtr("test.example.com"), Type: core.StringPtr("A"), Rdata: map[string]interface{}{"ip": "1.2.3.4"}, TTL: core.Int64Ptr(int64(120)), } secondPrivateRecord := dnssvcsv1.ResourceRecord{ ID: core.StringPtr("456"), Name: core.StringPtr("testCNAME.example.com"), Type: core.StringPtr("CNAME"), Rdata: map[string]interface{}{"cname": "test.example.com"}, TTL: core.Int64Ptr(int64(120)), } thirdPrivateRecord := dnssvcsv1.ResourceRecord{ ID: core.StringPtr("789"), Name: core.StringPtr("test.example.com"), Type: core.StringPtr("TXT"), Rdata: map[string]interface{}{"text": "\"heritage=external-dns,external-dns/owner=tower-pdns\""}, TTL: core.Int64Ptr(int64(120)), } privateRecords := []dnssvcsv1.ResourceRecord{firstPrivateRecord, secondPrivateRecord, thirdPrivateRecord} privateRecordsResop := &dnssvcsv1.ListResourceRecords{ ResourceRecords: privateRecords, Offset: core.Int64Ptr(int64(0)), TotalCount: core.Int64Ptr(int64(1)), } // Setup record rData inputARecord := &dnssvcsv1.ResourceRecordInputRdataRdataARecord{ Ip: core.StringPtr("1.2.3.4"), } inputCnameRecord := &dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord{ Cname: core.StringPtr("test.example.com"), } inputTxtRecord := &dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord{ Text: core.StringPtr("test"), } updateARecord := &dnssvcsv1.ResourceRecordUpdateInputRdataRdataARecord{ Ip: core.StringPtr("1.2.3.4"), } updateCnameRecord := &dnssvcsv1.ResourceRecordUpdateInputRdataRdataCnameRecord{ Cname: core.StringPtr("test.example.com"), } updateTxtRecord := &dnssvcsv1.ResourceRecordUpdateInputRdataRdataTxtRecord{ Text: core.StringPtr("test"), } // Setup mock services mockDNSClient := &mockIbmcloudClientInterface{} mockDNSClient.On("CreateDNSRecordWithContext", mock.Anything, mock.Anything).Return(nil, nil, nil) mockDNSClient.On("UpdateDNSRecordWithContext", mock.Anything, mock.Anything).Return(nil, nil, nil) mockDNSClient.On("DeleteDNSRecordWithContext", mock.Anything, mock.Anything).Return(nil, nil, nil) mockDNSClient.On("ListAllDDNSRecordsWithContext", mock.Anything, mock.Anything).Return(publicRecordsResp, nil, nil) mockDNSClient.On("ListDnszonesWithContext", mock.Anything, mock.Anything).Return(listZonesResp, nil, nil) mockDNSClient.On("GetDnszoneWithContext", mock.Anything, mock.Anything).Return(&firstPrivateZone, nil, nil) mockDNSClient.On("ListResourceRecordsWithContext", mock.Anything, mock.Anything).Return(privateRecordsResop, nil, nil) mockDNSClient.On("CreatePermittedNetworkWithContext", mock.Anything, mock.Anything).Return(nil, nil, nil) mockDNSClient.On("CreateResourceRecordWithContext", mock.Anything, mock.Anything).Return(nil, nil, nil) mockDNSClient.On("DeleteResourceRecordWithContext", mock.Anything, mock.Anything).Return(nil, nil, nil) mockDNSClient.On("UpdateResourceRecordWithContext", mock.Anything, mock.Anything).Return(nil, nil, nil) mockDNSClient.On("NewResourceRecordInputRdataRdataARecord", mock.Anything).Return(inputARecord, nil) mockDNSClient.On("NewResourceRecordInputRdataRdataCnameRecord", mock.Anything).Return(inputCnameRecord, nil) mockDNSClient.On("NewResourceRecordInputRdataRdataTxtRecord", mock.Anything).Return(inputTxtRecord, nil) mockDNSClient.On("NewResourceRecordUpdateInputRdataRdataARecord", mock.Anything).Return(updateARecord, nil) mockDNSClient.On("NewResourceRecordUpdateInputRdataRdataCnameRecord", mock.Anything).Return(updateCnameRecord, nil) mockDNSClient.On("NewResourceRecordUpdateInputRdataRdataTxtRecord", mock.Anything).Return(updateTxtRecord, nil) return mockDNSClient } func newTestIBMCloudProvider(private bool) *IBMCloudProvider { mockSource := &mockSource{} endpoints := []*endpoint.Endpoint{ { DNSName: "new.example.com", Targets: endpoint.Targets{"4.3.2.1"}, ProviderSpecific: endpoint.ProviderSpecific{ { Name: "ibmcloud-vpc", Value: "crn:v1:staging:public:is:us-south:a/0821fa9f9ebcc7b7c9a0d6e9bf9442a4::vpc:be33cdad-9a03-4bfa-82ca-eadb9f1de688", }, }, }, } mockSource.On("Endpoints", mock.Anything).Return(endpoints, nil, nil) domainFilterTest := endpoint.NewDomainFilter([]string{"example.com"}) return &IBMCloudProvider{ Client: NewMockIBMCloudDNSAPI(), source: mockSource, domainFilter: domainFilterTest, DryRun: false, instanceID: "test123", privateZone: private, } } func TestPublic_Records(t *testing.T) { p := newTestIBMCloudProvider(false) endpoints, err := p.Records(context.Background()) if err != nil { t.Errorf("Failed to get records: %v", err) } else { if len(endpoints) != 2 { t.Errorf("Incorrect number of records: %d", len(endpoints)) } for _, endpoint := range endpoints { t.Logf("Endpoint for %++v", *endpoint) } } } func TestPrivate_Records(t *testing.T) { p := newTestIBMCloudProvider(true) endpoints, err := p.Records(context.Background()) if err != nil { t.Errorf("Failed to get records: %v", err) } else { if len(endpoints) != 3 { t.Errorf("Incorrect number of records: %d", len(endpoints)) } for _, endpoint := range endpoints { t.Logf("Endpoint for %++v", *endpoint) } } } func TestPublic_ApplyChanges(t *testing.T) { p := newTestIBMCloudProvider(false) changes := plan.Changes{ Create: []*endpoint.Endpoint{ { DNSName: "newA.example.com", RecordType: "A", RecordTTL: 300, Targets: endpoint.NewTargets("4.3.2.1"), ProviderSpecific: endpoint.ProviderSpecific{ { Name: "ibmcloud-proxied", Value: "false", }, }, }, }, UpdateOld: []*endpoint.Endpoint{ { DNSName: "test.example.com", RecordType: "A", RecordTTL: 180, Targets: endpoint.NewTargets("1.2.3.4"), ProviderSpecific: endpoint.ProviderSpecific{ { Name: "ibmcloud-proxied", Value: "false", }, }, }, }, UpdateNew: []*endpoint.Endpoint{ { DNSName: "test.example.com", RecordType: "A", RecordTTL: 180, Targets: endpoint.NewTargets("1.2.3.4", "5.6.7.8"), ProviderSpecific: endpoint.ProviderSpecific{ { Name: "ibmcloud-proxied", Value: "true", }, }, }, }, Delete: []*endpoint.Endpoint{ { DNSName: "test.example.com", RecordType: "TXT", RecordTTL: 300, Targets: endpoint.NewTargets("\"heritage=external-dns,external-dns/owner=tower-pdns\""), }, }, } ctx := context.Background() err := p.ApplyChanges(ctx, &changes) if err != nil { t.Errorf("should not fail, %s", err) } } func TestPrivate_ApplyChanges(t *testing.T) { p := newTestIBMCloudProvider(true) endpointsCreate, err := p.AdjustEndpoints([]*endpoint.Endpoint{ { DNSName: "newA.example.com", RecordType: "A", RecordTTL: 120, Targets: endpoint.NewTargets("4.3.2.1"), ProviderSpecific: endpoint.ProviderSpecific{ { Name: "ibmcloud-vpc", Value: "crn:v1:staging:public:is:us-south:a/0821fa9f9ebcc7b7c9a0d6e9bf9442a4::vpc:be33cdad-9a03-4bfa-82ca-eadb9f1de688", }, }, }, { DNSName: "newCNAME.example.com", RecordType: "CNAME", RecordTTL: 180, Targets: endpoint.NewTargets("newA.example.com"), }, { DNSName: "newTXT.example.com", RecordType: "TXT", RecordTTL: 240, Targets: endpoint.NewTargets("\"heritage=external-dns,external-dns/owner=tower-pdns\""), }, }) assert.NoError(t, err) endpointsUpdate, err := p.AdjustEndpoints([]*endpoint.Endpoint{ { DNSName: "test.example.com", RecordType: "A", RecordTTL: 180, Targets: endpoint.NewTargets("1.2.3.4", "5.6.7.8"), }, }) assert.NoError(t, err) changes := plan.Changes{ Create: endpointsCreate, UpdateOld: []*endpoint.Endpoint{ { DNSName: "test.example.com", RecordType: "A", RecordTTL: 180, Targets: endpoint.NewTargets("1.2.3.4"), }, }, UpdateNew: endpointsUpdate, Delete: []*endpoint.Endpoint{ { DNSName: "test.example.com", RecordType: "TXT", RecordTTL: 300, Targets: endpoint.NewTargets("\"heritage=external-dns,external-dns/owner=tower-pdns\""), }, }, } ctx := context.Background() err = p.ApplyChanges(ctx, &changes) if err != nil { t.Errorf("should not fail, %s", err) } } func TestAdjustEndpoints(t *testing.T) { p := newTestIBMCloudProvider(false) endpoints := []*endpoint.Endpoint{ { DNSName: "test.example.com", Targets: endpoint.Targets{"1.2.3.4"}, RecordType: endpoint.RecordTypeA, RecordTTL: 300, Labels: endpoint.Labels{}, ProviderSpecific: endpoint.ProviderSpecific{ { Name: "ibmcloud-proxied", Value: "1", }, }, }, } ep, err := p.AdjustEndpoints(endpoints) assert.NoError(t, err) assert.Equal(t, endpoint.TTL(0), ep[0].RecordTTL) assert.Equal(t, "test.example.com", ep[0].DNSName) proxied, _ := ep[0].GetProviderSpecificProperty("ibmcloud-proxied") assert.Equal(t, "true", proxied) } func TestPrivateZone_withFilterID(t *testing.T) { p := newTestIBMCloudProvider(true) p.zoneIDFilter = provider.NewZoneIDFilter([]string{"123", "456"}) zones, err := p.privateZones(context.Background()) if err != nil { t.Errorf("should not fail, %s", err) } else { if len(zones) != 2 { t.Errorf("Incorrect number of zones: %d", len(zones)) } for _, zone := range zones { t.Logf("zone %s", *zone.ID) } } } func TestPublicConfig_Validate(t *testing.T) { // mock http server testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { defer GinkgoRecover() time.Sleep(0) // Set mock response res.Header().Set("Content-type", "application/json") res.WriteHeader(200) fmt.Fprintf(res, "%s", `{"success": true, "errors": [["Errors"]], "messages": [["Messages"]], "result": [{"id": "123", "created_on": "2014-01-01T05:20:00.12345Z", "modified_on": "2014-01-01T05:20:00.12345Z", "name": "example.com", "original_registrar": "GoDaddy", "original_dnshost": "NameCheap", "status": "active", "paused": false, "original_name_servers": ["ns1.originaldnshost.com"], "name_servers": ["ns001.name.cloud.ibm.com"]}], "result_info": {"page": 1, "per_page": 20, "count": 1, "total_count": 2000}}`) })) zoneIDFilterTest := provider.NewZoneIDFilter([]string{"123"}) domainFilterTest := endpoint.NewDomainFilter([]string{"example.com"}) cfg := &ibmcloudConfig{ Endpoint: testServer.URL, CRN: "crn:v1:bluemix:public:internet-svcs:global:a/bcf1865e99742d38d2d5fc3fb80a5496:a6338168-9510-4951-9d67-425612de96f0::", } crn := cfg.CRN authenticator := &core.NoAuthAuthenticator{} service, isPrivate, err := cfg.Validate(authenticator, domainFilterTest, provider.NewZoneIDFilter([]string{""})) assert.NoError(t, err) assert.Equal(t, false, isPrivate) assert.Equal(t, crn, *service.publicRecordsService.Crn) assert.Equal(t, "123", *service.publicRecordsService.ZoneIdentifier) service, isPrivate, err = cfg.Validate(authenticator, endpoint.NewDomainFilter([]string{""}), zoneIDFilterTest) assert.NoError(t, err) assert.Equal(t, false, isPrivate) assert.Equal(t, crn, *service.publicRecordsService.Crn) assert.Equal(t, "123", *service.publicRecordsService.ZoneIdentifier) testServer.Close() } func TestPrivateConfig_Validate(t *testing.T) { zoneIDFilterTest := provider.NewZoneIDFilter([]string{"123"}) domainFilterTest := endpoint.NewDomainFilter([]string{"example.com"}) authenticator := &core.NoAuthAuthenticator{} cfg := &ibmcloudConfig{ Endpoint: "XXX", CRN: "crn:v1:bluemix:public:dns-svcs:global:a/bcf1865e99742d38d2d5fc3fb80a5496:a6338168-9510-4951-9d67-425612de96f0::", } _, isPrivate, err := cfg.Validate(authenticator, domainFilterTest, zoneIDFilterTest) assert.NoError(t, err) assert.Equal(t, true, isPrivate) } // mockIbmcloudClientInterface is an autogenerated mock type for the ibmcloudClient type type mockIbmcloudClientInterface struct { mock.Mock } // CreateDNSRecordWithContext provides a mock function with given fields: ctx, createDnsRecordOptions func (_m *mockIbmcloudClientInterface) CreateDNSRecordWithContext(ctx context.Context, createDnsRecordOptions *dnsrecordsv1.CreateDnsRecordOptions) (*dnsrecordsv1.DnsrecordResp, *core.DetailedResponse, error) { ret := _m.Called(ctx, createDnsRecordOptions) var r0 *dnsrecordsv1.DnsrecordResp if rf, ok := ret.Get(0).(func(context.Context, *dnsrecordsv1.CreateDnsRecordOptions) *dnsrecordsv1.DnsrecordResp); ok { r0 = rf(ctx, createDnsRecordOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnsrecordsv1.DnsrecordResp) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnsrecordsv1.CreateDnsRecordOptions) *core.DetailedResponse); ok { r1 = rf(ctx, createDnsRecordOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnsrecordsv1.CreateDnsRecordOptions) error); ok { r2 = rf(ctx, createDnsRecordOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // CreatePermittedNetworkWithContext provides a mock function with given fields: ctx, createPermittedNetworkOptions func (_m *mockIbmcloudClientInterface) CreatePermittedNetworkWithContext(ctx context.Context, createPermittedNetworkOptions *dnssvcsv1.CreatePermittedNetworkOptions) (*dnssvcsv1.PermittedNetwork, *core.DetailedResponse, error) { ret := _m.Called(ctx, createPermittedNetworkOptions) var r0 *dnssvcsv1.PermittedNetwork if rf, ok := ret.Get(0).(func(context.Context, *dnssvcsv1.CreatePermittedNetworkOptions) *dnssvcsv1.PermittedNetwork); ok { r0 = rf(ctx, createPermittedNetworkOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.PermittedNetwork) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnssvcsv1.CreatePermittedNetworkOptions) *core.DetailedResponse); ok { r1 = rf(ctx, createPermittedNetworkOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnssvcsv1.CreatePermittedNetworkOptions) error); ok { r2 = rf(ctx, createPermittedNetworkOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // CreateResourceRecordWithContext provides a mock function with given fields: ctx, createResourceRecordOptions func (_m *mockIbmcloudClientInterface) CreateResourceRecordWithContext(ctx context.Context, createResourceRecordOptions *dnssvcsv1.CreateResourceRecordOptions) (*dnssvcsv1.ResourceRecord, *core.DetailedResponse, error) { ret := _m.Called(ctx, createResourceRecordOptions) var r0 *dnssvcsv1.ResourceRecord if rf, ok := ret.Get(0).(func(context.Context, *dnssvcsv1.CreateResourceRecordOptions) *dnssvcsv1.ResourceRecord); ok { r0 = rf(ctx, createResourceRecordOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ResourceRecord) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnssvcsv1.CreateResourceRecordOptions) *core.DetailedResponse); ok { r1 = rf(ctx, createResourceRecordOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnssvcsv1.CreateResourceRecordOptions) error); ok { r2 = rf(ctx, createResourceRecordOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // DeleteDNSRecordWithContext provides a mock function with given fields: ctx, deleteDnsRecordOptions func (_m *mockIbmcloudClientInterface) DeleteDNSRecordWithContext(ctx context.Context, deleteDnsRecordOptions *dnsrecordsv1.DeleteDnsRecordOptions) (*dnsrecordsv1.DeleteDnsrecordResp, *core.DetailedResponse, error) { ret := _m.Called(ctx, deleteDnsRecordOptions) var r0 *dnsrecordsv1.DeleteDnsrecordResp if rf, ok := ret.Get(0).(func(context.Context, *dnsrecordsv1.DeleteDnsRecordOptions) *dnsrecordsv1.DeleteDnsrecordResp); ok { r0 = rf(ctx, deleteDnsRecordOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnsrecordsv1.DeleteDnsrecordResp) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnsrecordsv1.DeleteDnsRecordOptions) *core.DetailedResponse); ok { r1 = rf(ctx, deleteDnsRecordOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnsrecordsv1.DeleteDnsRecordOptions) error); ok { r2 = rf(ctx, deleteDnsRecordOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // DeleteResourceRecordWithContext provides a mock function with given fields: ctx, deleteResourceRecordOptions func (_m *mockIbmcloudClientInterface) DeleteResourceRecordWithContext(ctx context.Context, deleteResourceRecordOptions *dnssvcsv1.DeleteResourceRecordOptions) (*core.DetailedResponse, error) { ret := _m.Called(ctx, deleteResourceRecordOptions) var r0 *core.DetailedResponse if rf, ok := ret.Get(0).(func(context.Context, *dnssvcsv1.DeleteResourceRecordOptions) *core.DetailedResponse); ok { r0 = rf(ctx, deleteResourceRecordOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*core.DetailedResponse) } } var r1 error if rf, ok := ret.Get(1).(func(context.Context, *dnssvcsv1.DeleteResourceRecordOptions) error); ok { r1 = rf(ctx, deleteResourceRecordOptions) } else { r1 = ret.Error(1) } return r0, r1 } // GetDnszoneWithContext provides a mock function with given fields: ctx, getDnszoneOptions func (_m *mockIbmcloudClientInterface) GetDnszoneWithContext(ctx context.Context, getDnszoneOptions *dnssvcsv1.GetDnszoneOptions) (*dnssvcsv1.Dnszone, *core.DetailedResponse, error) { ret := _m.Called(ctx, getDnszoneOptions) var r0 *dnssvcsv1.Dnszone if rf, ok := ret.Get(0).(func(context.Context, *dnssvcsv1.GetDnszoneOptions) *dnssvcsv1.Dnszone); ok { r0 = rf(ctx, getDnszoneOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.Dnszone) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnssvcsv1.GetDnszoneOptions) *core.DetailedResponse); ok { r1 = rf(ctx, getDnszoneOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnssvcsv1.GetDnszoneOptions) error); ok { r2 = rf(ctx, getDnszoneOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // ListAllDDNSRecordsWithContext provides a mock function with given fields: ctx, listAllDnsRecordsOptions func (_m *mockIbmcloudClientInterface) ListAllDDNSRecordsWithContext(ctx context.Context, listAllDnsRecordsOptions *dnsrecordsv1.ListAllDnsRecordsOptions) (*dnsrecordsv1.ListDnsrecordsResp, *core.DetailedResponse, error) { ret := _m.Called(ctx, listAllDnsRecordsOptions) var r0 *dnsrecordsv1.ListDnsrecordsResp if rf, ok := ret.Get(0).(func(context.Context, *dnsrecordsv1.ListAllDnsRecordsOptions) *dnsrecordsv1.ListDnsrecordsResp); ok { r0 = rf(ctx, listAllDnsRecordsOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnsrecordsv1.ListDnsrecordsResp) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnsrecordsv1.ListAllDnsRecordsOptions) *core.DetailedResponse); ok { r1 = rf(ctx, listAllDnsRecordsOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnsrecordsv1.ListAllDnsRecordsOptions) error); ok { r2 = rf(ctx, listAllDnsRecordsOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // ListDnszonesWithContext provides a mock function with given fields: ctx, listDnszonesOptions func (_m *mockIbmcloudClientInterface) ListDnszonesWithContext(ctx context.Context, listDnszonesOptions *dnssvcsv1.ListDnszonesOptions) (*dnssvcsv1.ListDnszones, *core.DetailedResponse, error) { ret := _m.Called(ctx, listDnszonesOptions) var r0 *dnssvcsv1.ListDnszones if rf, ok := ret.Get(0).(func(context.Context, *dnssvcsv1.ListDnszonesOptions) *dnssvcsv1.ListDnszones); ok { r0 = rf(ctx, listDnszonesOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ListDnszones) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnssvcsv1.ListDnszonesOptions) *core.DetailedResponse); ok { r1 = rf(ctx, listDnszonesOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnssvcsv1.ListDnszonesOptions) error); ok { r2 = rf(ctx, listDnszonesOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // ListResourceRecordsWithContext provides a mock function with given fields: ctx, listResourceRecordsOptions func (_m *mockIbmcloudClientInterface) ListResourceRecordsWithContext(ctx context.Context, listResourceRecordsOptions *dnssvcsv1.ListResourceRecordsOptions) (*dnssvcsv1.ListResourceRecords, *core.DetailedResponse, error) { ret := _m.Called(ctx, listResourceRecordsOptions) var r0 *dnssvcsv1.ListResourceRecords if rf, ok := ret.Get(0).(func(context.Context, *dnssvcsv1.ListResourceRecordsOptions) *dnssvcsv1.ListResourceRecords); ok { r0 = rf(ctx, listResourceRecordsOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ListResourceRecords) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnssvcsv1.ListResourceRecordsOptions) *core.DetailedResponse); ok { r1 = rf(ctx, listResourceRecordsOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnssvcsv1.ListResourceRecordsOptions) error); ok { r2 = rf(ctx, listResourceRecordsOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // NewResourceRecordInputRdataRdataARecord provides a mock function with given fields: ip func (_m *mockIbmcloudClientInterface) NewResourceRecordInputRdataRdataARecord(ip string) (*dnssvcsv1.ResourceRecordInputRdataRdataARecord, error) { ret := _m.Called(ip) var r0 *dnssvcsv1.ResourceRecordInputRdataRdataARecord if rf, ok := ret.Get(0).(func(string) *dnssvcsv1.ResourceRecordInputRdataRdataARecord); ok { r0 = rf(ip) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ResourceRecordInputRdataRdataARecord) } } var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(ip) } else { r1 = ret.Error(1) } return r0, r1 } // NewResourceRecordInputRdataRdataCnameRecord provides a mock function with given fields: cname func (_m *mockIbmcloudClientInterface) NewResourceRecordInputRdataRdataCnameRecord(cname string) (*dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord, error) { ret := _m.Called(cname) var r0 *dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord if rf, ok := ret.Get(0).(func(string) *dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord); ok { r0 = rf(cname) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ResourceRecordInputRdataRdataCnameRecord) } } var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(cname) } else { r1 = ret.Error(1) } return r0, r1 } // NewResourceRecordInputRdataRdataTxtRecord provides a mock function with given fields: text func (_m *mockIbmcloudClientInterface) NewResourceRecordInputRdataRdataTxtRecord(text string) (*dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord, error) { ret := _m.Called(text) var r0 *dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord if rf, ok := ret.Get(0).(func(string) *dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord); ok { r0 = rf(text) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ResourceRecordInputRdataRdataTxtRecord) } } var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(text) } else { r1 = ret.Error(1) } return r0, r1 } // NewResourceRecordUpdateInputRdataRdataARecord provides a mock function with given fields: ip func (_m *mockIbmcloudClientInterface) NewResourceRecordUpdateInputRdataRdataARecord(ip string) (*dnssvcsv1.ResourceRecordUpdateInputRdataRdataARecord, error) { ret := _m.Called(ip) var r0 *dnssvcsv1.ResourceRecordUpdateInputRdataRdataARecord if rf, ok := ret.Get(0).(func(string) *dnssvcsv1.ResourceRecordUpdateInputRdataRdataARecord); ok { r0 = rf(ip) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ResourceRecordUpdateInputRdataRdataARecord) } } var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(ip) } else { r1 = ret.Error(1) } return r0, r1 } // NewResourceRecordUpdateInputRdataRdataCnameRecord provides a mock function with given fields: cname func (_m *mockIbmcloudClientInterface) NewResourceRecordUpdateInputRdataRdataCnameRecord(cname string) (*dnssvcsv1.ResourceRecordUpdateInputRdataRdataCnameRecord, error) { ret := _m.Called(cname) var r0 *dnssvcsv1.ResourceRecordUpdateInputRdataRdataCnameRecord if rf, ok := ret.Get(0).(func(string) *dnssvcsv1.ResourceRecordUpdateInputRdataRdataCnameRecord); ok { r0 = rf(cname) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ResourceRecordUpdateInputRdataRdataCnameRecord) } } var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(cname) } else { r1 = ret.Error(1) } return r0, r1 } // NewResourceRecordUpdateInputRdataRdataTxtRecord provides a mock function with given fields: text func (_m *mockIbmcloudClientInterface) NewResourceRecordUpdateInputRdataRdataTxtRecord(text string) (*dnssvcsv1.ResourceRecordUpdateInputRdataRdataTxtRecord, error) { ret := _m.Called(text) var r0 *dnssvcsv1.ResourceRecordUpdateInputRdataRdataTxtRecord if rf, ok := ret.Get(0).(func(string) *dnssvcsv1.ResourceRecordUpdateInputRdataRdataTxtRecord); ok { r0 = rf(text) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ResourceRecordUpdateInputRdataRdataTxtRecord) } } var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(text) } else { r1 = ret.Error(1) } return r0, r1 } // UpdateDNSRecordWithContext provides a mock function with given fields: ctx, updateDnsRecordOptions func (_m *mockIbmcloudClientInterface) UpdateDNSRecordWithContext(ctx context.Context, updateDnsRecordOptions *dnsrecordsv1.UpdateDnsRecordOptions) (*dnsrecordsv1.DnsrecordResp, *core.DetailedResponse, error) { ret := _m.Called(ctx, updateDnsRecordOptions) var r0 *dnsrecordsv1.DnsrecordResp if rf, ok := ret.Get(0).(func(context.Context, *dnsrecordsv1.UpdateDnsRecordOptions) *dnsrecordsv1.DnsrecordResp); ok { r0 = rf(ctx, updateDnsRecordOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnsrecordsv1.DnsrecordResp) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnsrecordsv1.UpdateDnsRecordOptions) *core.DetailedResponse); ok { r1 = rf(ctx, updateDnsRecordOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnsrecordsv1.UpdateDnsRecordOptions) error); ok { r2 = rf(ctx, updateDnsRecordOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } // UpdateResourceRecordWithContext provides a mock function with given fields: ctx, updateResourceRecordOptions func (_m *mockIbmcloudClientInterface) UpdateResourceRecordWithContext(ctx context.Context, updateResourceRecordOptions *dnssvcsv1.UpdateResourceRecordOptions) (*dnssvcsv1.ResourceRecord, *core.DetailedResponse, error) { ret := _m.Called(ctx, updateResourceRecordOptions) var r0 *dnssvcsv1.ResourceRecord if rf, ok := ret.Get(0).(func(context.Context, *dnssvcsv1.UpdateResourceRecordOptions) *dnssvcsv1.ResourceRecord); ok { r0 = rf(ctx, updateResourceRecordOptions) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*dnssvcsv1.ResourceRecord) } } var r1 *core.DetailedResponse if rf, ok := ret.Get(1).(func(context.Context, *dnssvcsv1.UpdateResourceRecordOptions) *core.DetailedResponse); ok { r1 = rf(ctx, updateResourceRecordOptions) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*core.DetailedResponse) } } var r2 error if rf, ok := ret.Get(2).(func(context.Context, *dnssvcsv1.UpdateResourceRecordOptions) error); ok { r2 = rf(ctx, updateResourceRecordOptions) } else { r2 = ret.Error(2) } return r0, r1, r2 } type mockSource struct { mock.Mock } // Endpoints provides a mock function with given fields: ctx func (_m *mockSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) { ret := _m.Called(ctx) var r0 []*endpoint.Endpoint if rf, ok := ret.Get(0).(func(context.Context) []*endpoint.Endpoint); ok { r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*endpoint.Endpoint) } } var r1 error if rf, ok := ret.Get(1).(func(context.Context) error); ok { r1 = rf(ctx) } else { r1 = ret.Error(1) } return r0, r1 } // AddEventHandler provides a mock function with given fields: _a0, _a1 func (_m *mockSource) AddEventHandler(_a0 context.Context, _a1 func()) { _m.Called(_a0, _a1) }