2023-08-11 13:12:13 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
|
2023-06-13 15:54:45 +00:00
|
|
|
package leafcert
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/mitchellh/hashstructure"
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/acl"
|
2023-09-12 19:56:43 +00:00
|
|
|
"github.com/hashicorp/consul/agent/cacheshim"
|
2023-06-13 15:54:45 +00:00
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ConnectCALeafRequest is the cache.Request implementation for the
|
|
|
|
// ConnectCALeaf cache type. This is implemented here and not in structs
|
|
|
|
// since this is only used for cache-related requests and not forwarded
|
|
|
|
// directly to any Consul servers.
|
|
|
|
type ConnectCALeafRequest struct {
|
|
|
|
Token string
|
|
|
|
Datacenter string
|
|
|
|
DNSSAN []string
|
|
|
|
IPSAN []net.IP
|
|
|
|
MinQueryIndex uint64
|
|
|
|
MaxQueryTime time.Duration
|
|
|
|
acl.EnterpriseMeta
|
|
|
|
MustRevalidate bool
|
|
|
|
|
|
|
|
// The following flags indicate the entity we are requesting a cert for.
|
|
|
|
// Only one of these must be specified.
|
2024-09-05 14:50:46 +00:00
|
|
|
Service string // Given a Service name, not ID, the request is for a SpiffeIDService.
|
|
|
|
Agent string // Given an Agent name, not ID, the request is for a SpiffeIDAgent.
|
|
|
|
Kind structs.ServiceKind // Given "mesh-gateway", the request is for a SpiffeIDMeshGateway. No other kinds supported.
|
|
|
|
Server bool // If true, the request is for a SpiffeIDServer.
|
2023-06-13 15:54:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ConnectCALeafRequest) Key() string {
|
|
|
|
r.EnterpriseMeta.Normalize()
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case r.Agent != "":
|
|
|
|
v, err := hashstructure.Hash([]any{
|
|
|
|
r.Agent,
|
|
|
|
r.PartitionOrDefault(),
|
|
|
|
}, nil)
|
|
|
|
if err == nil {
|
|
|
|
return fmt.Sprintf("agent:%d", v)
|
|
|
|
}
|
|
|
|
case r.Kind == structs.ServiceKindMeshGateway:
|
|
|
|
v, err := hashstructure.Hash([]any{
|
|
|
|
r.PartitionOrDefault(),
|
|
|
|
r.DNSSAN,
|
|
|
|
r.IPSAN,
|
|
|
|
}, nil)
|
|
|
|
if err == nil {
|
|
|
|
return fmt.Sprintf("kind:%d", v)
|
|
|
|
}
|
|
|
|
case r.Kind != "":
|
|
|
|
// this is not valid
|
|
|
|
case r.Server:
|
|
|
|
v, err := hashstructure.Hash([]any{
|
|
|
|
"server",
|
|
|
|
r.Datacenter,
|
|
|
|
}, nil)
|
|
|
|
if err == nil {
|
|
|
|
return fmt.Sprintf("server:%d", v)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
v, err := hashstructure.Hash([]any{
|
|
|
|
r.Service,
|
|
|
|
r.EnterpriseMeta,
|
|
|
|
r.DNSSAN,
|
|
|
|
r.IPSAN,
|
|
|
|
}, nil)
|
|
|
|
if err == nil {
|
|
|
|
return fmt.Sprintf("service:%d", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If there is an error, we don't set the key. A blank key forces
|
|
|
|
// no cache for this request so the request is forwarded directly
|
|
|
|
// to the server.
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
func (req *ConnectCALeafRequest) TargetNamespace() string {
|
|
|
|
return req.NamespaceOrDefault()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (req *ConnectCALeafRequest) TargetPartition() string {
|
|
|
|
return req.PartitionOrDefault()
|
|
|
|
}
|
|
|
|
|
2023-09-12 19:56:43 +00:00
|
|
|
func (r *ConnectCALeafRequest) CacheInfo() cacheshim.RequestInfo {
|
|
|
|
return cacheshim.RequestInfo{
|
2023-06-13 15:54:45 +00:00
|
|
|
Token: r.Token,
|
|
|
|
Key: r.Key(),
|
|
|
|
Datacenter: r.Datacenter,
|
|
|
|
MinIndex: r.MinQueryIndex,
|
|
|
|
Timeout: r.MaxQueryTime,
|
|
|
|
MustRevalidate: r.MustRevalidate,
|
|
|
|
}
|
|
|
|
}
|