Catalog + Namespace OSS changes. (#7219)
* Various Prepared Query + Namespace things * Last round of OSS changes for a namespaced catalog
This commit is contained in:
parent
6b8ca85f6c
commit
966d085066
|
@ -110,7 +110,6 @@ func (s *HTTPServer) ACLRulesTranslate(resp http.ResponseWriter, req *http.Reque
|
|||
}
|
||||
// Should this require lesser permissions? Really the only reason to require authorization at all is
|
||||
// to prevent external entities from DoS Consul with repeated rule translation requests
|
||||
// TODO (namespaces) - pass through a real ent authz ctx
|
||||
if rule != nil && rule.ACLRead(nil) != acl.Allow {
|
||||
return nil, acl.ErrPermissionDenied
|
||||
}
|
||||
|
|
|
@ -1107,7 +1107,6 @@ func (s *HTTPServer) AgentNodeMaintenance(resp http.ResponseWriter, req *http.Re
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO (namespaces) - pass through a real ent authz ctx?
|
||||
if rule != nil && rule.NodeWrite(s.agent.config.NodeName, nil) != acl.Allow {
|
||||
return nil, acl.ErrPermissionDenied
|
||||
}
|
||||
|
@ -1325,12 +1324,15 @@ func (s *HTTPServer) AgentConnectCALeafCert(resp http.ResponseWriter, req *http.
|
|||
// not the ID of the service instance.
|
||||
serviceName := strings.TrimPrefix(req.URL.Path, "/v1/agent/connect/ca/leaf/")
|
||||
|
||||
// TODO (namespaces) add namespacing to connect leaf cert generation request
|
||||
args := cachetype.ConnectCALeafRequest{
|
||||
Service: serviceName, // Need name not ID
|
||||
}
|
||||
var qOpts structs.QueryOptions
|
||||
|
||||
if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Store DC in the ConnectCALeafRequest but query opts separately
|
||||
if done := s.parse(resp, req, &args.Datacenter, &qOpts); done {
|
||||
return nil, nil
|
||||
|
|
|
@ -226,7 +226,7 @@ func (s *HTTPServer) catalogServiceNodes(resp http.ResponseWriter, req *http.Req
|
|||
|
||||
// Set default DC
|
||||
args := structs.ServiceSpecificRequest{Connect: connect}
|
||||
if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
|
||||
if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -487,9 +487,12 @@ func (s *ConnectCA) Sign(
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var authzContext acl.AuthorizerContext
|
||||
var entMeta structs.EnterpriseMeta
|
||||
if isService {
|
||||
// TODO (namespaces) use actual ent authz context
|
||||
if rule != nil && rule.ServiceWrite(serviceID.Service, nil) != acl.Allow {
|
||||
entMeta.Merge(serviceID.GetEnterpriseMeta())
|
||||
entMeta.FillAuthzContext(&authzContext)
|
||||
if rule != nil && rule.ServiceWrite(serviceID.Service, &authzContext) != acl.Allow {
|
||||
return acl.ErrPermissionDenied
|
||||
}
|
||||
|
||||
|
@ -500,8 +503,8 @@ func (s *ConnectCA) Sign(
|
|||
"we are %s", serviceID.Datacenter, s.srv.config.Datacenter)
|
||||
}
|
||||
} else if isAgent {
|
||||
// TODO (namespaces) use actual ent authz context
|
||||
if rule != nil && rule.NodeWrite(agentID.Agent, nil) != acl.Allow {
|
||||
structs.DefaultEnterpriseMeta().FillAuthzContext(&authzContext)
|
||||
if rule != nil && rule.NodeWrite(agentID.Agent, &authzContext) != acl.Allow {
|
||||
return acl.ErrPermissionDenied
|
||||
}
|
||||
}
|
||||
|
@ -588,10 +591,11 @@ func (s *ConnectCA) Sign(
|
|||
|
||||
// Set the response
|
||||
*reply = structs.IssuedCert{
|
||||
SerialNumber: connect.EncodeSerialNumber(cert.SerialNumber),
|
||||
CertPEM: pem,
|
||||
ValidAfter: cert.NotBefore,
|
||||
ValidBefore: cert.NotAfter,
|
||||
SerialNumber: connect.EncodeSerialNumber(cert.SerialNumber),
|
||||
CertPEM: pem,
|
||||
ValidAfter: cert.NotBefore,
|
||||
ValidBefore: cert.NotAfter,
|
||||
EnterpriseMeta: entMeta,
|
||||
RaftIndex: structs.RaftIndex{
|
||||
ModifyIndex: modIdx,
|
||||
CreateIndex: modIdx,
|
||||
|
|
|
@ -139,13 +139,14 @@ func (c *Coordinate) Update(args *structs.CoordinateUpdateRequest, reply *struct
|
|||
}
|
||||
|
||||
// Fetch the ACL token, if any, and enforce the node policy if enabled.
|
||||
rule, err := c.srv.ResolveToken(args.Token)
|
||||
authz, err := c.srv.ResolveToken(args.Token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rule != nil && c.srv.config.ACLEnforceVersion8 {
|
||||
// TODO (namespaces) use actual ent authz context
|
||||
if rule.NodeWrite(args.Node, nil) != acl.Allow {
|
||||
if authz != nil && c.srv.config.ACLEnforceVersion8 {
|
||||
var authzContext acl.AuthorizerContext
|
||||
structs.DefaultEnterpriseMeta().FillAuthzContext(&authzContext)
|
||||
if authz.NodeWrite(args.Node, &authzContext) != acl.Allow {
|
||||
return acl.ErrPermissionDenied
|
||||
}
|
||||
}
|
||||
|
@ -211,13 +212,15 @@ func (c *Coordinate) Node(args *structs.NodeSpecificRequest, reply *structs.Inde
|
|||
}
|
||||
|
||||
// Fetch the ACL token, if any, and enforce the node policy if enabled.
|
||||
rule, err := c.srv.ResolveToken(args.Token)
|
||||
|
||||
authz, err := c.srv.ResolveToken(args.Token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rule != nil && c.srv.config.ACLEnforceVersion8 {
|
||||
// TODO (namespaces) use actual ent authz context
|
||||
if rule.NodeRead(args.Node, nil) != acl.Allow {
|
||||
if authz != nil && c.srv.config.ACLEnforceVersion8 {
|
||||
var authzContext acl.AuthorizerContext
|
||||
structs.WildcardEnterpriseMeta().FillAuthzContext(&authzContext)
|
||||
if authz.NodeRead(args.Node, &authzContext) != acl.Allow {
|
||||
return acl.ErrPermissionDenied
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@ func (m *Internal) NodeInfo(args *structs.NodeSpecificRequest,
|
|||
return err
|
||||
}
|
||||
|
||||
_, err := m.srv.ResolveTokenAndDefaultMeta(args.Token, &args.EnterpriseMeta, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.srv.blockingQuery(
|
||||
&args.QueryOptions,
|
||||
&reply.QueryMeta,
|
||||
|
@ -49,6 +54,11 @@ func (m *Internal) NodeDump(args *structs.DCSpecificRequest,
|
|||
return err
|
||||
}
|
||||
|
||||
_, err := m.srv.ResolveTokenAndDefaultMeta(args.Token, &args.EnterpriseMeta, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filter, err := bexpr.CreateFilter(args.Filter, nil, reply.Dump)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -83,6 +93,11 @@ func (m *Internal) ServiceDump(args *structs.ServiceDumpRequest, reply *structs.
|
|||
return err
|
||||
}
|
||||
|
||||
_, err := m.srv.ResolveTokenAndDefaultMeta(args.Token, &args.EnterpriseMeta, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filter, err := bexpr.CreateFilter(args.Filter, nil, reply.Nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -548,6 +548,7 @@ func (p *PreparedQuery) execute(query *structs.PreparedQuery,
|
|||
|
||||
// Capture the nodes and pass the DNS information through to the reply.
|
||||
reply.Service = query.Service.Service
|
||||
reply.EnterpriseMeta = query.Service.EnterpriseMeta
|
||||
reply.Nodes = nodes
|
||||
reply.DNS = query.DNS
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ func testServerACLConfig(cb func(*Config)) func(*Config) {
|
|||
c.ACLsEnabled = true
|
||||
c.ACLMasterToken = TestDefaultMasterToken
|
||||
c.ACLDefaultPolicy = "deny"
|
||||
c.ACLEnforceVersion8 = true
|
||||
|
||||
if cb != nil {
|
||||
cb(c)
|
||||
|
|
|
@ -1206,7 +1206,7 @@ func (s *Store) getPolicyWithTxn(tx *memdb.Txn, ws memdb.WatchSet, value string,
|
|||
}
|
||||
ws.Add(watchCh)
|
||||
|
||||
if err != nil || policy == nil {
|
||||
if policy == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -528,7 +528,6 @@ func (s *Store) deleteNodeCASTxn(tx *memdb.Txn, idx, cidx uint64, nodeName strin
|
|||
|
||||
// deleteNodeTxn is the inner method used for removing a node from
|
||||
// the store within a given transaction.
|
||||
// TODO (namespaces) (catalog) access to catalog tables needs to become namespace aware for services/checks
|
||||
func (s *Store) deleteNodeTxn(tx *memdb.Txn, idx uint64, nodeName string) error {
|
||||
// Look up the node.
|
||||
node, err := tx.First("nodes", "id", nodeName)
|
||||
|
|
|
@ -256,8 +256,6 @@ func TestDiscoveryChainRead(t *testing.T) {
|
|||
})
|
||||
}))
|
||||
|
||||
// TODO(namespaces): add a test
|
||||
|
||||
expectTarget_DC2 := newTarget("web", "", "default", "dc2")
|
||||
expectTarget_DC2.MeshGateway = structs.MeshGatewayConfig{
|
||||
Mode: structs.MeshGatewayModeLocal,
|
||||
|
|
|
@ -108,7 +108,7 @@ RETRY_ONCE:
|
|||
func (s *HTTPServer) HealthServiceChecks(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
// Set default DC
|
||||
args := structs.ServiceSpecificRequest{}
|
||||
if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
|
||||
if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.parseSource(req, &args.Source)
|
||||
|
@ -164,7 +164,7 @@ func (s *HTTPServer) HealthServiceNodes(resp http.ResponseWriter, req *http.Requ
|
|||
func (s *HTTPServer) healthServiceNodes(resp http.ResponseWriter, req *http.Request, connect bool) (interface{}, error) {
|
||||
// Set default DC
|
||||
args := structs.ServiceSpecificRequest{Connect: connect}
|
||||
if err := s.parseEntMeta(req, &args.EnterpriseMeta); err != nil {
|
||||
if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.parseSource(req, &args.Source)
|
||||
|
|
|
@ -305,6 +305,9 @@ type PreparedQueryExecuteResponse struct {
|
|||
// Service is the service that was queried.
|
||||
Service string
|
||||
|
||||
// EnterpriseMeta of the service that was queried.
|
||||
EnterpriseMeta
|
||||
|
||||
// Nodes has the nodes that were output by the query.
|
||||
Nodes CheckServiceNodes
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ func (d *DiscoveryChain) Get(name string, opts *DiscoveryChainOptions, q *QueryO
|
|||
if opts.EvaluateInDatacenter != "" {
|
||||
r.params.Set("compile-dc", opts.EvaluateInDatacenter)
|
||||
}
|
||||
// TODO(namespaces): handle possible EvaluateInNamespace here
|
||||
}
|
||||
|
||||
if method == "POST" {
|
||||
|
|
|
@ -25,6 +25,9 @@ type ServiceQuery struct {
|
|||
// Service is the service to query.
|
||||
Service string
|
||||
|
||||
// Namespace of the service to query
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
// Near allows baking in the name of a node to automatically distance-
|
||||
// sort from. The magic "_agent" value is supported, which sorts near
|
||||
// the agent which initiated the request by default.
|
||||
|
@ -119,6 +122,9 @@ type PreparedQueryExecuteResponse struct {
|
|||
// Service is the service that was queried.
|
||||
Service string
|
||||
|
||||
// Namespace of the service that was queried
|
||||
Namespace string `json:",omitempty"`
|
||||
|
||||
// Nodes has the nodes that were output by the query.
|
||||
Nodes []ServiceEntry
|
||||
|
||||
|
|
Loading…
Reference in New Issue