66 lines
1.8 KiB
Go
66 lines
1.8 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package consul
|
|
|
|
import (
|
|
"github.com/hashicorp/consul/acl"
|
|
"github.com/hashicorp/consul/agent/consul/state"
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
"github.com/hashicorp/go-memdb"
|
|
)
|
|
|
|
// Usage returns counts for service usage within catalog.
|
|
func (op *Operator) Usage(args *structs.OperatorUsageRequest, reply *structs.Usage) error {
|
|
reply.Usage = make(map[string]structs.ServiceUsage)
|
|
|
|
if args.Global {
|
|
remoteDCs := op.srv.router.GetDatacenters()
|
|
for _, dc := range remoteDCs {
|
|
remoteArgs := &structs.OperatorUsageRequest{
|
|
DCSpecificRequest: structs.DCSpecificRequest{
|
|
Datacenter: dc,
|
|
QueryOptions: structs.QueryOptions{
|
|
Token: args.Token,
|
|
},
|
|
},
|
|
}
|
|
var resp structs.Usage
|
|
if _, err := op.srv.ForwardRPC("Operator.Usage", remoteArgs, &resp); err != nil {
|
|
op.logger.Warn("error forwarding usage request to remote datacenter", "datacenter", dc, "error", err)
|
|
}
|
|
if usage, ok := resp.Usage[dc]; ok {
|
|
reply.Usage[dc] = usage
|
|
}
|
|
}
|
|
}
|
|
|
|
var authzContext acl.AuthorizerContext
|
|
authz, err := op.srv.ResolveTokenAndDefaultMeta(args.Token, structs.DefaultEnterpriseMetaInDefaultPartition(), &authzContext)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = authz.ToAllowAuthorizer().OperatorReadAllowed(&authzContext)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err = op.srv.validateEnterpriseRequest(&args.EnterpriseMeta, false); err != nil {
|
|
return err
|
|
}
|
|
|
|
return op.srv.blockingQuery(
|
|
&args.QueryOptions,
|
|
&reply.QueryMeta,
|
|
func(ws memdb.WatchSet, state *state.Store) error {
|
|
// Get service usage.
|
|
index, serviceUsage, err := state.ServiceUsage(ws)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
reply.QueryMeta.Index, reply.Usage[op.srv.config.Datacenter] = index, serviceUsage
|
|
return nil
|
|
})
|
|
}
|