Skip to content

Commit 4eb7e75

Browse files
voro015johngmyers
andauthored
AWSSD: Utilize DiscoverInstances instead of ListInstances (#2506)
* AWSSD: Utilize DiscoverInstances instead of ListInstances * Fixed stylecheck Renamed instanceToHttpInstanceSummary to instanceToHTTPInstanceSummary * awssd use DiscoverInstancesWithContext from client directly * updated awssd tests fix DiscoverInstancesWithContext to implement AWSSDClient interface drop old test, no need to cover direct calls to aws clent methods moved instanceToHTTPInstanceSummary to _test file * awssd log error on failed DeleteService * updated awssd tests * fix missing import * awssd tests handle not found NS with DiscoverInstancesWithContext * Update provider/awssd/aws_sd_test.go Co-authored-by: John Gardiner Myers <[email protected]> * Update provider/awssd/aws_sd_test.go Co-authored-by: John Gardiner Myers <[email protected]> --------- Co-authored-by: John Gardiner Myers <[email protected]>
1 parent 17e9637 commit 4eb7e75

File tree

2 files changed

+52
-118
lines changed

2 files changed

+52
-118
lines changed

provider/awssd/aws_sd.go

+13-44
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"strings"
2626

2727
"github.com/aws/aws-sdk-go/aws"
28+
"github.com/aws/aws-sdk-go/aws/request"
2829
sd "github.com/aws/aws-sdk-go/service/servicediscovery"
2930
log "github.com/sirupsen/logrus"
3031

@@ -57,7 +58,7 @@ var (
5758
type AWSSDClient interface {
5859
CreateService(input *sd.CreateServiceInput) (*sd.CreateServiceOutput, error)
5960
DeregisterInstance(input *sd.DeregisterInstanceInput) (*sd.DeregisterInstanceOutput, error)
60-
ListInstancesPages(input *sd.ListInstancesInput, fn func(*sd.ListInstancesOutput, bool) bool) error
61+
DiscoverInstancesWithContext(ctx aws.Context, input *sd.DiscoverInstancesInput, opts ...request.Option) (*sd.DiscoverInstancesOutput, error)
6162
ListNamespacesPages(input *sd.ListNamespacesInput, fn func(*sd.ListNamespacesOutput, bool) bool) error
6263
ListServicesPages(input *sd.ListServicesInput, fn func(*sd.ListServicesOutput, bool) bool) error
6364
RegisterInstance(input *sd.RegisterInstanceInput) (*sd.RegisterInstanceOutput, error)
@@ -126,28 +127,29 @@ func (p *AWSSDProvider) Records(ctx context.Context) (endpoints []*endpoint.Endp
126127
}
127128

128129
for _, srv := range services {
129-
instances, err := p.ListInstancesByServiceID(srv.Id)
130+
resp, err := p.client.DiscoverInstancesWithContext(ctx, &sd.DiscoverInstancesInput{
131+
NamespaceName: ns.Name,
132+
ServiceName: srv.Name,
133+
})
130134
if err != nil {
131135
return nil, err
132136
}
133137

134-
if len(instances) > 0 {
135-
ep := p.instancesToEndpoint(ns, srv, instances)
136-
endpoints = append(endpoints, ep)
137-
}
138-
if len(instances) == 0 {
139-
err = p.DeleteService(srv)
140-
if err != nil {
141-
log.Warnf("Failed to delete service \"%s\", error: %s", aws.StringValue(srv.Name), err)
138+
if len(resp.Instances) == 0 {
139+
if err := p.DeleteService(srv); err != nil {
140+
log.Errorf("Failed to delete service %q, error: %s", aws.StringValue(srv.Name), err)
142141
}
142+
continue
143143
}
144+
145+
endpoints = append(endpoints, p.instancesToEndpoint(ns, srv, resp.Instances))
144146
}
145147
}
146148

147149
return endpoints, nil
148150
}
149151

150-
func (p *AWSSDProvider) instancesToEndpoint(ns *sd.NamespaceSummary, srv *sd.Service, instances []*sd.InstanceSummary) *endpoint.Endpoint {
152+
func (p *AWSSDProvider) instancesToEndpoint(ns *sd.NamespaceSummary, srv *sd.Service, instances []*sd.HttpInstanceSummary) *endpoint.Endpoint {
151153
// DNS name of the record is a concatenation of service and namespace
152154
recordName := *srv.Name + "." + *ns.Name
153155

@@ -376,26 +378,6 @@ func (p *AWSSDProvider) ListServicesByNamespaceID(namespaceID *string) (map[stri
376378
return servicesMap, nil
377379
}
378380

379-
// ListInstancesByServiceID returns list of instances registered in given service.
380-
func (p *AWSSDProvider) ListInstancesByServiceID(serviceID *string) ([]*sd.InstanceSummary, error) {
381-
instances := make([]*sd.InstanceSummary, 0)
382-
383-
f := func(resp *sd.ListInstancesOutput, lastPage bool) bool {
384-
instances = append(instances, resp.Instances...)
385-
386-
return true
387-
}
388-
389-
err := p.client.ListInstancesPages(&sd.ListInstancesInput{
390-
ServiceId: serviceID,
391-
}, f)
392-
if err != nil {
393-
return nil, err
394-
}
395-
396-
return instances, nil
397-
}
398-
399381
// CreateService creates a new service in AWS API. Returns the created service.
400382
func (p *AWSSDProvider) CreateService(namespaceID *string, srvName *string, ep *endpoint.Endpoint) (*sd.Service, error) {
401383
log.Infof("Creating a new service \"%s\" in \"%s\" namespace", *srvName, *namespaceID)
@@ -585,19 +567,6 @@ func serviceToServiceSummary(service *sd.Service) *sd.ServiceSummary {
585567
}
586568
}
587569

588-
// nolint: deadcode
589-
// used from unit test
590-
func instanceToInstanceSummary(instance *sd.Instance) *sd.InstanceSummary {
591-
if instance == nil {
592-
return nil
593-
}
594-
595-
return &sd.InstanceSummary{
596-
Id: instance.Id,
597-
Attributes: instance.Attributes,
598-
}
599-
}
600-
601570
func (p *AWSSDProvider) changesByNamespaceID(namespaces []*sd.NamespaceSummary, changes []*endpoint.Endpoint) map[string][]*endpoint.Endpoint {
602571
changesByNsID := make(map[string][]*endpoint.Endpoint)
603572

provider/awssd/aws_sd_test.go

+39-74
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"time"
2727

2828
"github.com/aws/aws-sdk-go/aws"
29+
"github.com/aws/aws-sdk-go/aws/request"
2930
sd "github.com/aws/aws-sdk-go/service/servicediscovery"
3031
"github.com/stretchr/testify/assert"
3132
"github.com/stretchr/testify/require"
@@ -38,6 +39,10 @@ import (
3839
// Compile time check for interface conformance
3940
var _ AWSSDClient = &AWSSDClientStub{}
4041

42+
var (
43+
ErrNamespaceNotFound = errors.New("Namespace not found")
44+
)
45+
4146
type AWSSDClientStub struct {
4247
// map[namespace_id]namespace
4348
namespaces map[string]*sd.Namespace
@@ -91,18 +96,31 @@ func (s *AWSSDClientStub) GetService(input *sd.GetServiceInput) (*sd.GetServiceO
9196
return nil, errors.New("service not found")
9297
}
9398

94-
func (s *AWSSDClientStub) ListInstancesPages(input *sd.ListInstancesInput, fn func(*sd.ListInstancesOutput, bool) bool) error {
95-
instances := make([]*sd.InstanceSummary, 0)
99+
func (s *AWSSDClientStub) DiscoverInstancesWithContext(ctx context.Context, input *sd.DiscoverInstancesInput, opts ...request.Option) (*sd.DiscoverInstancesOutput, error) {
100+
instances := make([]*sd.HttpInstanceSummary, 0)
96101

97-
for _, inst := range s.instances[*input.ServiceId] {
98-
instances = append(instances, instanceToInstanceSummary(inst))
102+
var foundNs bool
103+
for _, ns := range s.namespaces {
104+
if aws.StringValue(ns.Name) == aws.StringValue(input.NamespaceName) {
105+
foundNs = true
106+
107+
for _, srv := range s.services[*ns.Id] {
108+
if aws.StringValue(srv.Name) == aws.StringValue(input.ServiceName) {
109+
for _, inst := range s.instances[*srv.Id] {
110+
instances = append(instances, instanceToHTTPInstanceSummary(inst))
111+
}
112+
}
113+
}
114+
}
99115
}
100116

101-
fn(&sd.ListInstancesOutput{
102-
Instances: instances,
103-
}, true)
117+
if !foundNs {
118+
return nil, ErrNamespaceNotFound
119+
}
104120

105-
return nil
121+
return &sd.DiscoverInstancesOutput{
122+
Instances: instances,
123+
}, nil
106124
}
107125

108126
func (s *AWSSDClientStub) ListNamespacesPages(input *sd.ListNamespacesInput, fn func(*sd.ListNamespacesOutput, bool) bool) error {
@@ -203,6 +221,19 @@ func newTestAWSSDProvider(api AWSSDClient, domainFilter endpoint.DomainFilter, n
203221
}
204222
}
205223

224+
// nolint: deadcode
225+
// used for unit test
226+
func instanceToHTTPInstanceSummary(instance *sd.Instance) *sd.HttpInstanceSummary {
227+
if instance == nil {
228+
return nil
229+
}
230+
231+
return &sd.HttpInstanceSummary{
232+
InstanceId: instance.Id,
233+
Attributes: instance.Attributes,
234+
}
235+
}
236+
206237
func TestAWSSDProvider_Records(t *testing.T) {
207238
namespaces := map[string]*sd.Namespace{
208239
"private": {
@@ -463,72 +494,6 @@ func TestAWSSDProvider_ListServicesByNamespace(t *testing.T) {
463494
}
464495
}
465496

466-
func TestAWSSDProvider_ListInstancesByService(t *testing.T) {
467-
namespaces := map[string]*sd.Namespace{
468-
"private": {
469-
Id: aws.String("private"),
470-
Name: aws.String("private.com"),
471-
Type: aws.String(sd.NamespaceTypeDnsPrivate),
472-
},
473-
}
474-
475-
services := map[string]map[string]*sd.Service{
476-
"private": {
477-
"srv1": {
478-
Id: aws.String("srv1"),
479-
Name: aws.String("service1"),
480-
},
481-
"srv2": {
482-
Id: aws.String("srv2"),
483-
Name: aws.String("service2"),
484-
},
485-
},
486-
}
487-
488-
instances := map[string]map[string]*sd.Instance{
489-
"srv1": {
490-
"inst1": {
491-
Id: aws.String("inst1"),
492-
Attributes: map[string]*string{
493-
sdInstanceAttrIPV4: aws.String("1.2.3.4"),
494-
},
495-
},
496-
"inst2": {
497-
Id: aws.String("inst2"),
498-
Attributes: map[string]*string{
499-
sdInstanceAttrIPV4: aws.String("1.2.3.5"),
500-
},
501-
},
502-
},
503-
}
504-
505-
api := &AWSSDClientStub{
506-
namespaces: namespaces,
507-
services: services,
508-
instances: instances,
509-
}
510-
511-
provider := newTestAWSSDProvider(api, endpoint.NewDomainFilter([]string{}), "", "")
512-
513-
result, err := provider.ListInstancesByServiceID(services["private"]["srv1"].Id)
514-
require.NoError(t, err)
515-
516-
expectedInstances := []*sd.InstanceSummary{instanceToInstanceSummary(instances["srv1"]["inst1"]), instanceToInstanceSummary(instances["srv1"]["inst2"])}
517-
518-
expectedMap := make(map[string]*sd.InstanceSummary)
519-
resultMap := make(map[string]*sd.InstanceSummary)
520-
for _, inst := range expectedInstances {
521-
expectedMap[*inst.Id] = inst
522-
}
523-
for _, inst := range result {
524-
resultMap[*inst.Id] = inst
525-
}
526-
527-
if !reflect.DeepEqual(resultMap, expectedMap) {
528-
t.Errorf("AWSSDProvider.ListInstancesByServiceID() error = %v, wantErr %v", result, expectedInstances)
529-
}
530-
}
531-
532497
func TestAWSSDProvider_CreateService(t *testing.T) {
533498
namespaces := map[string]*sd.Namespace{
534499
"private": {

0 commit comments

Comments
 (0)