Skip to content

Commit 054b926

Browse files
committed
Add the support for creating service with DNS namespaces. Update the namespaceCache to support namespace struct.
1 parent bfd82eb commit 054b926

File tree

5 files changed

+183
-94
lines changed

5 files changed

+183
-94
lines changed

pkg/cloudmap/api.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
// internal data structures. It manages all interactions with the AWS SDK.
1818
type ServiceDiscoveryApi interface {
1919
// ListNamespaces returns a list of all namespaces.
20-
ListNamespaces(ctx context.Context) (namespaces []*model.Resource, err error)
20+
ListNamespaces(ctx context.Context) (namespaces []*model.Namespace, err error)
2121

2222
// ListServices returns a list of services for a given namespace.
2323
ListServices(ctx context.Context, namespaceId string) (services []*model.Resource, err error)
@@ -35,7 +35,7 @@ type ServiceDiscoveryApi interface {
3535
CreateHttpNamespace(ctx context.Context, namespaceName string) (operationId string, err error)
3636

3737
// CreateService creates a named service in AWS Cloud Map under the given namespace.
38-
CreateService(ctx context.Context, namespaceId string, serviceName string) (serviceId string, err error)
38+
CreateService(ctx context.Context, namespace model.Namespace, serviceName string) (serviceId string, err error)
3939

4040
// RegisterInstance registers a service instance in AWS Cloud Map.
4141
RegisterInstance(ctx context.Context, serviceId string, instanceId string, instanceAttrs map[string]string) (operationId string, err error)
@@ -60,8 +60,8 @@ func NewServiceDiscoveryApiFromConfig(cfg *aws.Config) ServiceDiscoveryApi {
6060
}
6161
}
6262

63-
func (sdApi *serviceDiscoveryApi) ListNamespaces(ctx context.Context) ([]*model.Resource, error) {
64-
namespaces := make([]*model.Resource, 0)
63+
func (sdApi *serviceDiscoveryApi) ListNamespaces(ctx context.Context) ([]*model.Namespace, error) {
64+
namespaces := make([]*model.Namespace, 0)
6565
pages := sd.NewListNamespacesPaginator(sdApi.awsFacade, &sd.ListNamespacesInput{})
6666

6767
for pages.HasMorePages() {
@@ -71,9 +71,10 @@ func (sdApi *serviceDiscoveryApi) ListNamespaces(ctx context.Context) ([]*model.
7171
}
7272

7373
for _, ns := range output.Namespaces {
74-
namespaces = append(namespaces, &model.Resource{
74+
namespaces = append(namespaces, &model.Namespace{
7575
Id: aws.ToString(ns.Id),
7676
Name: aws.ToString(ns.Name),
77+
Type: string(ns.Type),
7778
})
7879
}
7980
}
@@ -178,10 +179,19 @@ func (sdApi *serviceDiscoveryApi) CreateHttpNamespace(ctx context.Context, nsNam
178179
return aws.ToString(output.OperationId), nil
179180
}
180181

181-
func (sdApi *serviceDiscoveryApi) CreateService(ctx context.Context, nsId string, svcName string) (svcId string, err error) {
182-
output, err := sdApi.awsFacade.CreateService(ctx, &sd.CreateServiceInput{
183-
NamespaceId: &nsId,
184-
Name: &svcName})
182+
func (sdApi *serviceDiscoveryApi) CreateService(ctx context.Context, namespace model.Namespace, svcName string) (svcId string, err error) {
183+
var output *sd.CreateServiceOutput
184+
if namespace.Type == "DNS_PRIVATE" {
185+
dnsConfig := sdApi.getDnsConfig()
186+
output, err = sdApi.awsFacade.CreateService(ctx, &sd.CreateServiceInput{
187+
NamespaceId: &namespace.Id,
188+
DnsConfig: &dnsConfig,
189+
Name: &svcName})
190+
} else {
191+
output, err = sdApi.awsFacade.CreateService(ctx, &sd.CreateServiceInput{
192+
NamespaceId: &namespace.Id,
193+
Name: &svcName})
194+
}
185195

186196
if err != nil {
187197
return "", err
@@ -192,6 +202,19 @@ func (sdApi *serviceDiscoveryApi) CreateService(ctx context.Context, nsId string
192202
return svcId, nil
193203
}
194204

205+
func (sdApi *serviceDiscoveryApi) getDnsConfig() types.DnsConfig {
206+
ttl := int64(defaultServiceIdCacheTTL.Seconds())
207+
dnsConfig := types.DnsConfig{
208+
DnsRecords: []types.DnsRecord{
209+
{
210+
TTL: &ttl,
211+
Type: "SRV",
212+
},
213+
},
214+
}
215+
return dnsConfig
216+
}
217+
195218
func (sdApi *serviceDiscoveryApi) RegisterInstance(ctx context.Context, svcId string, instId string, instAttrs map[string]string) (opId string, err error) {
196219
regResp, err := sdApi.awsFacade.RegisterInstance(ctx, &sd.RegisterInstanceInput{
197220
Attributes: instAttrs,

pkg/cloudmap/client.go

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ import (
1212
)
1313

1414
const (
15-
defaultNamespaceIdCacheTTL = 2 * time.Minute
16-
defaultNamespaceIdCacheSize = 100
17-
defaultServiceIdCacheTTL = 2 * time.Minute
18-
defaultServiceIdCacheSize = 1024
19-
defaultEndpointsCacheTTL = 5 * time.Second
20-
defaultEndpointsCacheSize = 1024
15+
defaultNamespaceCacheTTL = 2 * time.Minute
16+
defaultNamespaceCacheSize = 100
17+
defaultServiceIdCacheTTL = 2 * time.Minute
18+
defaultServiceIdCacheSize = 1024
19+
defaultEndpointsCacheTTL = 5 * time.Second
20+
defaultEndpointsCacheSize = 1024
2121
)
2222

2323
// ServiceDiscoveryClient provides the service endpoint management functionality required by the AWS Cloud Map
@@ -40,21 +40,21 @@ type ServiceDiscoveryClient interface {
4040
}
4141

4242
type serviceDiscoveryClient struct {
43-
log logr.Logger
44-
sdApi ServiceDiscoveryApi
45-
namespaceIdCache *cache.LRUExpireCache
46-
serviceIdCache *cache.LRUExpireCache
47-
endpointCache *cache.LRUExpireCache
43+
log logr.Logger
44+
sdApi ServiceDiscoveryApi
45+
namespaceCache *cache.LRUExpireCache
46+
serviceIdCache *cache.LRUExpireCache
47+
endpointCache *cache.LRUExpireCache
4848
}
4949

5050
// NewServiceDiscoveryClient creates a new service discovery client for AWS Cloud Map from a given AWS client config.
5151
func NewServiceDiscoveryClient(cfg *aws.Config) ServiceDiscoveryClient {
5252
return &serviceDiscoveryClient{
53-
log: ctrl.Log.WithName("cloudmap"),
54-
sdApi: NewServiceDiscoveryApiFromConfig(cfg),
55-
namespaceIdCache: cache.NewLRUExpireCache(defaultNamespaceIdCacheSize),
56-
serviceIdCache: cache.NewLRUExpireCache(defaultServiceIdCacheSize),
57-
endpointCache: cache.NewLRUExpireCache(defaultEndpointsCacheSize),
53+
log: ctrl.Log.WithName("cloudmap"),
54+
sdApi: NewServiceDiscoveryApiFromConfig(cfg),
55+
namespaceCache: cache.NewLRUExpireCache(defaultNamespaceCacheSize),
56+
serviceIdCache: cache.NewLRUExpireCache(defaultServiceIdCacheSize),
57+
endpointCache: cache.NewLRUExpireCache(defaultEndpointsCacheSize),
5858
}
5959
}
6060

@@ -92,21 +92,20 @@ func (sdc *serviceDiscoveryClient) ListServices(ctx context.Context, nsName stri
9292
func (sdc *serviceDiscoveryClient) CreateService(ctx context.Context, nsName string, svcName string) (err error) {
9393
sdc.log.Info("creating a new service", "namespace", nsName, "name", svcName)
9494

95-
nsId, err := sdc.getNamespaceId(ctx, nsName)
95+
namespace, err := sdc.getNamespace(ctx, nsName)
9696
if err != nil {
9797
return err
9898
}
9999

100-
if nsId == "" {
101-
nsId, err = sdc.createNamespace(ctx, nsName)
102-
}
103-
if err != nil {
104-
return err
100+
if namespace == nil {
101+
// Create HttpNamespace if the namespace is not present in the CloudMap
102+
namespace, err = sdc.createNamespace(ctx, nsName)
103+
if err != nil {
104+
return err
105+
}
105106
}
106107

107-
//TODO: Handle non-http namespaces
108-
svcId, err := sdc.sdApi.CreateService(ctx, nsId, svcName)
109-
108+
svcId, err := sdc.sdApi.CreateService(ctx, *namespace, svcName)
110109
if err != nil {
111110
return err
112111
}
@@ -117,7 +116,7 @@ func (sdc *serviceDiscoveryClient) CreateService(ctx context.Context, nsName str
117116
}
118117

119118
func (sdc *serviceDiscoveryClient) GetService(ctx context.Context, nsName string, svcName string) (svc *model.Service, err error) {
120-
sdc.log.Info("fetching a service", "nsName", nsName, "svcName", svcName)
119+
sdc.log.Info("fetching a service", "namespace", nsName, "name", svcName)
121120

122121
svcId, err := sdc.getServiceId(ctx, nsName, svcName)
123122

@@ -237,27 +236,44 @@ func (sdc *serviceDiscoveryClient) listEndpoints(ctx context.Context, serviceId
237236
}
238237

239238
func (sdc *serviceDiscoveryClient) getNamespaceId(ctx context.Context, nsName string) (nsId string, err error) {
239+
namespace, err := sdc.getNamespace(ctx, nsName)
240+
if err != nil || namespace == nil {
241+
return "", err
242+
}
243+
return namespace.Id, nil
244+
}
245+
246+
func (sdc *serviceDiscoveryClient) getNamespace(ctx context.Context, nsName string) (namespace *model.Namespace, err error) {
240247
// We are assuming a unique namespace name per account
241-
if cachedValue, exists := sdc.namespaceIdCache.Get(nsName); exists {
242-
return cachedValue.(string), nil
248+
if cachedValue, exists := sdc.namespaceCache.Get(nsName); exists {
249+
ns, ok := cachedValue.(*model.Namespace)
250+
if !ok {
251+
return nil, nil
252+
}
253+
return ns, nil
243254
}
244255

245256
namespaces, err := sdc.sdApi.ListNamespaces(ctx)
246-
247257
if err != nil {
248-
return "", err
258+
return nil, err
249259
}
250260

251261
for _, ns := range namespaces {
252-
sdc.cacheNamespaceId(ns.Name, ns.Id)
262+
sdc.cacheNamespace(*ns)
263+
// Set the return namespace
253264
if nsName == ns.Name {
254-
nsId = ns.Id
265+
namespace = ns
255266
}
256267
}
257268

258-
// This will cache empty namespace IDs for namespaces not in Cloud Map
259-
sdc.cacheNamespaceId(nsName, nsId)
260-
return nsId, nil
269+
if namespace == nil {
270+
// This will cache empty namespace IDs for namespaces not in Cloud Map
271+
sdc.cacheNamespace(model.Namespace{
272+
Name: nsName,
273+
})
274+
}
275+
276+
return namespace, nil
261277
}
262278

263279
func (sdc *serviceDiscoveryClient) getServiceId(ctx context.Context, nsName string, svcName string) (svcId string, err error) {
@@ -293,27 +309,31 @@ func (sdc *serviceDiscoveryClient) getServiceId(ctx context.Context, nsName stri
293309
return svcId, nil
294310
}
295311

296-
func (sdc *serviceDiscoveryClient) createNamespace(ctx context.Context, nsName string) (nsId string, err error) {
312+
func (sdc *serviceDiscoveryClient) createNamespace(ctx context.Context, nsName string) (namespace *model.Namespace, err error) {
297313
sdc.log.Info("creating a new namespace", "namespace", nsName)
298314
opId, err := sdc.sdApi.CreateHttpNamespace(ctx, nsName)
299-
300315
if err != nil {
301-
return "", err
316+
return nil, err
302317
}
303318

304-
nsId, err = sdc.sdApi.PollCreateNamespace(ctx, opId)
305-
319+
nsId, err := sdc.sdApi.PollCreateNamespace(ctx, opId)
306320
if err != nil {
307-
return "", err
321+
return nil, err
308322
}
309323

310-
sdc.cacheNamespaceId(nsName, nsId)
324+
// Cache the Namespace, by default we always create namespace of type HTTP
325+
namespace = &model.Namespace{
326+
Id: nsId,
327+
Name: nsName,
328+
Type: "HTTP",
329+
}
330+
sdc.cacheNamespace(*namespace)
311331

312-
return nsId, nil
332+
return namespace, nil
313333
}
314334

315-
func (sdc *serviceDiscoveryClient) cacheNamespaceId(nsName string, nsId string) {
316-
sdc.namespaceIdCache.Add(nsName, nsId, defaultNamespaceIdCacheTTL)
335+
func (sdc *serviceDiscoveryClient) cacheNamespace(namespace model.Namespace) {
336+
sdc.namespaceCache.Add(namespace.Name, namespace, defaultNamespaceCacheTTL)
317337
}
318338

319339
func (sdc *serviceDiscoveryClient) cacheServiceId(nsName string, svcName string, svcId string) {

0 commit comments

Comments
 (0)