-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
xds controller: setup watches for and compute leaf cert references in…
… ProxyStateTemplate, and wire up leaf cert manager dependency (#18756) * Refactors the leafcert package to not have a dependency on agent/consul and agent/cache to avoid import cycles. This way the xds controller can just import the leafcert package to use the leafcert manager. The leaf cert logic in the controller: * Sets up watches for leaf certs that are referenced in the ProxyStateTemplate (which generates the leaf certs too). * Gets the leaf cert from the leaf cert cache * Stores the leaf cert in the ProxyState that's pushed to xds * For the cert watches, this PR also uses a bimapper + a thin wrapper to map leaf cert events to related ProxyStateTemplates Since bimapper uses a resource.Reference or resource.ID to map between two resource types, I've created an internal type for a leaf certificate to use for the resource.Reference, since it's not a v2 resource. The wrapper allows mapping events to resources (as opposed to mapping resources to resources) The controller tests: Unit: Ensure that we resolve leaf cert references Lifecycle: Ensure that when the CA is updated, the leaf cert is as well Also adds a new spiffe id type, and adds workload identity and workload identity URI to leaf certs. This is so certs are generated with the new workload identity based SPIFFE id. * Pulls out some leaf cert test helpers into a helpers file so it can be used in the xds controller tests. * Wires up leaf cert manager dependency * Support getting token from proxytracker * Add workload identity spiffe id type to the authorize and sign functions --------- Co-authored-by: John Murret <john.murret@hashicorp.com>
- Loading branch information
1 parent
89e6725
commit 78b170a
Showing
42 changed files
with
1,302 additions
and
399 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package cacheshim | ||
|
||
import ( | ||
"context" | ||
"time" | ||
) | ||
|
||
// cacheshim defines any shared cache types for any packages that don't want to have a dependency on the agent cache. | ||
// This was created as part of a refactor to remove agent/leafcert package's dependency on agent/cache. | ||
|
||
type ResultMeta struct { | ||
// Hit indicates whether or not the request was a cache hit | ||
Hit bool | ||
|
||
// Age identifies how "stale" the result is. It's semantics differ based on | ||
// whether or not the cache type performs background refresh or not as defined | ||
// in https://www.consul.io/api/index.html#agent-caching. | ||
// | ||
// For background refresh types, Age is 0 unless the background blocking query | ||
// is currently in a failed state and so not keeping up with the server's | ||
// values. If it is non-zero it represents the time since the first failure to | ||
// connect during background refresh, and is reset after a background request | ||
// does manage to reconnect and either return successfully, or block for at | ||
// least the yamux keepalive timeout of 30 seconds (which indicates the | ||
// connection is OK but blocked as expected). | ||
// | ||
// For simple cache types, Age is the time since the result being returned was | ||
// fetched from the servers. | ||
Age time.Duration | ||
|
||
// Index is the internal ModifyIndex for the cache entry. Not all types | ||
// support blocking and all that do will likely have this in their result type | ||
// already but this allows generic code to reason about whether cache values | ||
// have changed. | ||
Index uint64 | ||
} | ||
|
||
type Request interface { | ||
// CacheInfo returns information used for caching this request. | ||
CacheInfo() RequestInfo | ||
} | ||
|
||
type RequestInfo struct { | ||
// Key is a unique cache key for this request. This key should | ||
// be globally unique to identify this request, since any conflicting | ||
// cache keys could result in invalid data being returned from the cache. | ||
// The Key does not need to include ACL or DC information, since the | ||
// cache already partitions by these values prior to using this key. | ||
Key string | ||
|
||
// Token is the ACL token associated with this request. | ||
// | ||
// Datacenter is the datacenter that the request is targeting. | ||
// | ||
// PeerName is the peer that the request is targeting. | ||
// | ||
// All of these values are used to partition the cache. The cache framework | ||
// today partitions data on these values to simplify behavior: by | ||
// partitioning ACL tokens, the cache doesn't need to be smart about | ||
// filtering results. By filtering datacenter/peer results, the cache can | ||
// service the multi-DC/multi-peer nature of Consul. This comes at the expense of | ||
// working set size, but in general the effect is minimal. | ||
Token string | ||
Datacenter string | ||
PeerName string | ||
|
||
// MinIndex is the minimum index being queried. This is used to | ||
// determine if we already have data satisfying the query or if we need | ||
// to block until new data is available. If no index is available, the | ||
// default value (zero) is acceptable. | ||
MinIndex uint64 | ||
|
||
// Timeout is the timeout for waiting on a blocking query. When the | ||
// timeout is reached, the last known value is returned (or maybe nil | ||
// if there was no prior value). This "last known value" behavior matches | ||
// normal Consul blocking queries. | ||
Timeout time.Duration | ||
|
||
// MaxAge if set limits how stale a cache entry can be. If it is non-zero and | ||
// there is an entry in cache that is older than specified, it is treated as a | ||
// cache miss and re-fetched. It is ignored for cachetypes with Refresh = | ||
// true. | ||
MaxAge time.Duration | ||
|
||
// MustRevalidate forces a new lookup of the cache even if there is an | ||
// existing one that has not expired. It is implied by HTTP requests with | ||
// `Cache-Control: max-age=0` but we can't distinguish that case from the | ||
// unset case for MaxAge. Later we may support revalidating the index without | ||
// a full re-fetch but for now the only option is to refetch. It is ignored | ||
// for cachetypes with Refresh = true. | ||
MustRevalidate bool | ||
} | ||
|
||
type UpdateEvent struct { | ||
// CorrelationID is used by the Notify API to allow correlation of updates | ||
// with specific requests. We could return the full request object and | ||
// cachetype for consumers to match against the calls they made but in | ||
// practice it's cleaner for them to choose the minimal necessary unique | ||
// identifier given the set of things they are watching. They might even | ||
// choose to assign random IDs for example. | ||
CorrelationID string | ||
Result interface{} | ||
Meta ResultMeta | ||
Err error | ||
} | ||
|
||
type Callback func(ctx context.Context, event UpdateEvent) | ||
|
||
type Cache interface { | ||
Get(ctx context.Context, t string, r Request) (interface{}, ResultMeta, error) | ||
NotifyCallback(ctx context.Context, t string, r Request, correlationID string, cb Callback) error | ||
Notify(ctx context.Context, t string, r Request, correlationID string, ch chan<- UpdateEvent) error | ||
} | ||
|
||
const ConnectCARootName = "connect-ca-root" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.