diff --git a/.changelog/16024.txt b/.changelog/16024.txt new file mode 100644 index 0000000000..d3d4575ba3 --- /dev/null +++ b/.changelog/16024.txt @@ -0,0 +1,4 @@ +```release-note:improvement +partitiion: **(Consul Enterprise only)** when loading service from on-disk config file or sending API request to agent endpoint, +if the partition is unspecified, consul will default the partition in the request to agent's partition +``` diff --git a/agent/agent.go b/agent/agent.go index 3832bd93e3..06b1cef60f 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -2206,7 +2206,9 @@ func (a *Agent) readPersistedServiceConfigs() (map[structs.ServiceID]*structs.Se } } - if !acl.EqualPartitions(a.AgentEnterpriseMeta().PartitionOrDefault(), p.PartitionOrDefault()) { + if acl.EqualPartitions("", p.PartitionOrEmpty()) { + p.OverridePartition(a.AgentEnterpriseMeta().PartitionOrDefault()) + } else if !acl.EqualPartitions(a.AgentEnterpriseMeta().PartitionOrDefault(), p.PartitionOrDefault()) { a.logger.Info("Purging service config file in wrong partition", "file", file, "partition", p.PartitionOrDefault(), @@ -3552,6 +3554,11 @@ func (a *Agent) loadServices(conf *config.RuntimeConfig, snap map[structs.CheckI // Register the services from config for _, service := range conf.Services { + // Default service partition to the same as agent + if service.EnterpriseMeta.PartitionOrEmpty() == "" { + service.EnterpriseMeta.OverridePartition(a.AgentEnterpriseMeta().PartitionOrDefault()) + } + ns := service.NodeService() chkTypes, err := service.CheckTypes() if err != nil { @@ -3661,7 +3668,11 @@ func (a *Agent) loadServices(conf *config.RuntimeConfig, snap map[structs.CheckI } } - if !acl.EqualPartitions(a.AgentEnterpriseMeta().PartitionOrDefault(), p.Service.PartitionOrDefault()) { + if acl.EqualPartitions("", p.Service.PartitionOrEmpty()) { + // NOTE: in case loading a service with empty partition (e.g., OSS -> ENT), + // we always default the service partition to the agent's partition. + p.Service.OverridePartition(a.AgentEnterpriseMeta().PartitionOrDefault()) + } else if !acl.EqualPartitions(a.AgentEnterpriseMeta().PartitionOrDefault(), p.Service.PartitionOrDefault()) { a.logger.Info("Purging service file in wrong partition", "file", file, "partition", p.Service.EnterpriseMeta.PartitionOrDefault(), diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go index 4f5546392f..fbef537c18 100644 --- a/agent/agent_endpoint.go +++ b/agent/agent_endpoint.go @@ -341,6 +341,7 @@ func (s *HTTPHandlers) AgentServices(resp http.ResponseWriter, req *http.Request var filterExpression string s.parseFilter(req, &filterExpression) + s.defaultMetaPartitionToAgent(&entMeta) authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, nil) if err != nil { return nil, err @@ -425,6 +426,7 @@ func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request) } // need to resolve to default the meta + s.defaultMetaPartitionToAgent(&entMeta) _, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, nil) if err != nil { return nil, err @@ -498,6 +500,7 @@ func (s *HTTPHandlers) AgentChecks(resp http.ResponseWriter, req *http.Request) return nil, err } + s.defaultMetaPartitionToAgent(&entMeta) authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, nil) if err != nil { return nil, err @@ -760,6 +763,7 @@ func (s *HTTPHandlers) AgentRegisterCheck(resp http.ResponseWriter, req *http.Re return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Bad check status"} } + s.defaultMetaPartitionToAgent(&args.EnterpriseMeta) authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &args.EnterpriseMeta, nil) if err != nil { return nil, err @@ -808,7 +812,9 @@ func (s *HTTPHandlers) AgentRegisterCheck(resp http.ResponseWriter, req *http.Re func (s *HTTPHandlers) AgentDeregisterCheck(resp http.ResponseWriter, req *http.Request) (interface{}, error) { id := strings.TrimPrefix(req.URL.Path, "/v1/agent/check/deregister/") - checkID := structs.NewCheckID(types.CheckID(id), nil) + + entMeta := acl.NewEnterpriseMetaWithPartition(s.agent.config.PartitionOrDefault(), "") + checkID := structs.NewCheckID(types.CheckID(id), &entMeta) // Get the provided token, if any, and vet against any ACL policies. var token string @@ -900,7 +906,8 @@ func (s *HTTPHandlers) AgentCheckUpdate(resp http.ResponseWriter, req *http.Requ } func (s *HTTPHandlers) agentCheckUpdate(resp http.ResponseWriter, req *http.Request, checkID types.CheckID, status string, output string) (interface{}, error) { - cid := structs.NewCheckID(checkID, nil) + entMeta := acl.NewEnterpriseMetaWithPartition(s.agent.config.PartitionOrDefault(), "") + cid := structs.NewCheckID(checkID, &entMeta) // Get the provided token, if any, and vet against any ACL policies. var token string @@ -990,6 +997,7 @@ func (s *HTTPHandlers) AgentHealthServiceByID(resp http.ResponseWriter, req *htt s.parseToken(req, &token) // need to resolve to default the meta + s.defaultMetaPartitionToAgent(&entMeta) var authzContext acl.AuthorizerContext authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, &authzContext) if err != nil { @@ -1047,6 +1055,7 @@ func (s *HTTPHandlers) AgentHealthServiceByName(resp http.ResponseWriter, req *h var token string s.parseToken(req, &token) + s.defaultMetaPartitionToAgent(&entMeta) // need to resolve to default the meta var authzContext acl.AuthorizerContext authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, &authzContext) @@ -1124,6 +1133,7 @@ func (s *HTTPHandlers) AgentRegisterService(resp http.ResponseWriter, req *http. var token string s.parseToken(req, &token) + s.defaultMetaPartitionToAgent(&args.EnterpriseMeta) authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &args.EnterpriseMeta, nil) if err != nil { return nil, err @@ -1240,7 +1250,8 @@ func (s *HTTPHandlers) AgentRegisterService(resp http.ResponseWriter, req *http. func (s *HTTPHandlers) AgentDeregisterService(resp http.ResponseWriter, req *http.Request) (interface{}, error) { serviceID := strings.TrimPrefix(req.URL.Path, "/v1/agent/service/deregister/") - sid := structs.NewServiceID(serviceID, nil) + entMeta := acl.NewEnterpriseMetaWithPartition(s.agent.config.PartitionOrDefault(), "") + sid := structs.NewServiceID(serviceID, &entMeta) // Get the provided token, if any, and vet against any ACL policies. var token string @@ -1276,7 +1287,8 @@ func (s *HTTPHandlers) AgentDeregisterService(resp http.ResponseWriter, req *htt func (s *HTTPHandlers) AgentServiceMaintenance(resp http.ResponseWriter, req *http.Request) (interface{}, error) { // Ensure we have a service ID serviceID := strings.TrimPrefix(req.URL.Path, "/v1/agent/service/maintenance/") - sid := structs.NewServiceID(serviceID, nil) + entMeta := acl.NewEnterpriseMetaWithPartition(s.agent.config.PartitionOrDefault(), "") + sid := structs.NewServiceID(serviceID, &entMeta) if sid.ID == "" { return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing service ID"} diff --git a/agent/agent_endpoint_oss.go b/agent/agent_endpoint_oss.go index b775b5e79f..b54b9df99f 100644 --- a/agent/agent_endpoint_oss.go +++ b/agent/agent_endpoint_oss.go @@ -12,3 +12,6 @@ import ( func (s *HTTPHandlers) validateRequestPartition(_ http.ResponseWriter, _ *acl.EnterpriseMeta) bool { return true } + +func (s *HTTPHandlers) defaultMetaPartitionToAgent(entMeta *acl.EnterpriseMeta) { +}