command: when generating envoy bootstrap configs use the datacenter returned from the agent services endpoint (#9229)

Fixes #9215
This commit is contained in:
R.B. Boyer 2020-11-19 15:27:31 -06:00 committed by GitHub
parent 8368f65006
commit 7c7a3e5165
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 44 additions and 22 deletions

3
.changelog/9229.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
command: when generating envoy bootstrap configs use the datacenter returned from the agent services endpoint
```

View File

@ -170,7 +170,7 @@ func (s *HTTPHandlers) AgentReload(resp http.ResponseWriter, req *http.Request)
return nil, s.agent.ReloadConfig()
}
func buildAgentService(s *structs.NodeService) api.AgentService {
func buildAgentService(s *structs.NodeService, dc string) api.AgentService {
weights := api.AgentWeights{Passing: 1, Warning: 1}
if s.Weights != nil {
if s.Weights.Passing > 0 {
@ -200,6 +200,7 @@ func buildAgentService(s *structs.NodeService) api.AgentService {
CreateIndex: s.CreateIndex,
ModifyIndex: s.ModifyIndex,
Weights: weights,
Datacenter: dc,
}
if as.Tags == nil {
@ -253,9 +254,11 @@ func (s *HTTPHandlers) AgentServices(resp http.ResponseWriter, req *http.Request
// anyway.
agentSvcs := make(map[string]*api.AgentService)
dc := s.agent.config.Datacenter
// Use empty list instead of nil
for id, s := range services {
agentService := buildAgentService(s)
agentService := buildAgentService(s, dc)
agentSvcs[id.ID] = &agentService
}
@ -303,6 +306,8 @@ func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request)
sid := structs.NewServiceID(id, &entMeta)
dc := s.agent.config.Datacenter
resultHash, service, err := s.agent.LocalBlockingQuery(false, hash, queryOpts.MaxQueryTime,
func(ws memdb.WatchSet) (string, interface{}, error) {
@ -330,7 +335,7 @@ func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request)
}
// Calculate the content hash over the response, minus the hash field
aSvc := buildAgentService(svc)
aSvc := buildAgentService(svc, dc)
reply := &aSvc
rawHash, err := hashstructure.Hash(reply, nil)
@ -768,6 +773,8 @@ func (s *HTTPHandlers) AgentHealthServiceByID(resp http.ResponseWriter, req *htt
sid := structs.NewServiceID(serviceID, &entMeta)
dc := s.agent.config.Datacenter
if service := s.agent.State.Service(sid); service != nil {
if authz != nil && authz.ServiceRead(service.Service, &authzContext) != acl.Allow {
return nil, acl.ErrPermissionDenied
@ -776,7 +783,7 @@ func (s *HTTPHandlers) AgentHealthServiceByID(resp http.ResponseWriter, req *htt
if returnTextPlain(req) {
return status, CodeWithPayloadError{StatusCode: code, Reason: status, ContentType: "text/plain"}
}
serviceInfo := buildAgentService(service)
serviceInfo := buildAgentService(service, dc)
result := &api.AgentServiceChecksInfo{
AggregatedStatus: status,
Checks: healthChecks,
@ -822,6 +829,8 @@ func (s *HTTPHandlers) AgentHealthServiceByName(resp http.ResponseWriter, req *h
return nil, acl.ErrPermissionDenied
}
dc := s.agent.config.Datacenter
code := http.StatusNotFound
status := fmt.Sprintf("ServiceName %s Not Found", serviceName)
services := s.agent.State.Services(&entMeta)
@ -831,7 +840,7 @@ func (s *HTTPHandlers) AgentHealthServiceByName(resp http.ResponseWriter, req *h
sid := structs.NewServiceID(service.ID, &entMeta)
scode, sstatus, healthChecks := agentHealthService(sid, s)
serviceInfo := buildAgentService(service)
serviceInfo := buildAgentService(service, dc)
res := api.AgentServiceChecksInfo{
AggregatedStatus: sstatus,
Checks: healthChecks,

View File

@ -365,8 +365,9 @@ func TestAgent_Service(t *testing.T) {
Passing: 1,
Warning: 1,
},
Meta: map[string]string{},
Tags: []string{},
Meta: map[string]string{},
Tags: []string{},
Datacenter: "dc1",
}
fillAgentServiceEnterpriseMeta(expectedResponse, structs.DefaultEnterpriseMeta())
@ -391,8 +392,9 @@ func TestAgent_Service(t *testing.T) {
Port: 1818,
},
},
Meta: map[string]string{},
Tags: []string{},
Meta: map[string]string{},
Tags: []string{},
Datacenter: "dc1",
}
fillAgentServiceEnterpriseMeta(expectWebResponse, structs.DefaultEnterpriseMeta())

View File

@ -93,6 +93,8 @@ type AgentService struct {
// to include the Namespace in the hash. When we do, then we are in for lots of fun with tests.
// For now though, ignoring it works well enough.
Namespace string `json:",omitempty" bexpr:"-" hash:"ignore"`
// Datacenter is only ever returned and is ignored if presented.
Datacenter string `json:",omitempty" bexpr:"-" hash:"ignore"`
}
// AgentServiceChecksInfo returns information about a Service and its checks

View File

@ -726,8 +726,9 @@ func TestAPI_AgentService(t *testing.T) {
Passing: 1,
Warning: 1,
},
Meta: map[string]string{},
Namespace: defaultNamespace,
Meta: map[string]string{},
Namespace: defaultNamespace,
Datacenter: "dc1",
}
require.Equal(expect, got)
require.Equal(expect.ContentHash, qm.LastContentHash)

View File

@ -478,6 +478,7 @@ func (c *cmd) templateArgs() (*BootstrapTplArgs, error) {
LocalAgentClusterName: xds.LocalAgentClusterName,
Namespace: httpCfg.Namespace,
EnvoyVersion: c.envoyVersion,
Datacenter: httpCfg.Datacenter,
}, nil
}
@ -529,15 +530,11 @@ func (c *cmd) generateConfig() ([]byte, error) {
// cluster is using namespaces regardless.
args.Namespace = svc.Namespace
}
agent, err := c.client.Agent().Self()
if err != nil {
return nil, fmt.Errorf("failed to fetch agent config: %v", err)
if svc.Datacenter != "" {
// The agent will definitely have the definitive answer here.
args.Datacenter = svc.Datacenter
}
dc, ok := agent["Config"]["Datacenter"].(string)
if !ok {
return nil, fmt.Errorf("failed to fetch datacenter from agent. DC is: %T", agent["Config"]["Datacenter"])
}
args.Datacenter = dc
if !c.disableCentralConfig {
// Parse the bootstrap config

View File

@ -991,9 +991,10 @@ func testMockAgentGatewayConfig(namespacesEnabled bool) http.HandlerFunc {
svc := map[string]*api.AgentService{
string(kind): {
Kind: kind,
ID: string(kind),
Service: string(kind),
Kind: kind,
ID: string(kind),
Service: string(kind),
Datacenter: "dc1",
},
}
@ -1036,6 +1037,7 @@ func testMockAgentProxyConfig(cfg map[string]interface{}, namespacesEnabled bool
DestinationServiceID: serviceID,
Config: cfg,
},
Datacenter: "dc1",
}
if namespacesEnabled {

View File

@ -74,6 +74,7 @@ $ curl \
"Port": 8000,
"Address": "",
"EnableTagOverride": false,
"Datacenter": "dc1",
"Weights": {
"Passing": 10,
"Warning": 1
@ -185,6 +186,7 @@ $ curl \
"Warning": 1
},
"EnableTagOverride": false,
"Datacenter": "dc1",
"ContentHash": "4ecd29c7bc647ca8",
"Proxy": {
"DestinationServiceName": "web",
@ -304,6 +306,7 @@ curl localhost:8500/v1/agent/health/service/name/web
"Meta": null,
"Port": 80,
"EnableTagOverride": false,
"Datacenter": "dc1",
"Connect": {
"Native": false,
"Proxy": null
@ -331,6 +334,7 @@ curl localhost:8500/v1/agent/health/service/name/web
"Meta": null,
"Port": 80,
"EnableTagOverride": false,
"Datacenter": "dc1",
"Connect": {
"Native": false,
"Proxy": null
@ -380,6 +384,7 @@ curl localhost:8500/v1/agent/health/service/id/web2
"Meta": null,
"Port": 80,
"EnableTagOverride": false,
"Datacenter": "dc1",
"Connect": {
"Native": false,
"Proxy": null
@ -425,6 +430,7 @@ curl localhost:8500/v1/agent/health/service/id/web1
"Meta": null,
"Port": 80,
"EnableTagOverride": false,
"Datacenter": "dc1",
"Connect": {
"Native": false,
"Proxy": null