mirror of https://github.com/status-im/consul.git
[NET-8091] Add file-system-certificate config entry for API gateway (#20873)
* Define file-system-certificate config entry * Collect file-system-certificate(s) referenced by api-gateway onto snapshot * Add file-system-certificate to config entry kind allow lists * Remove inapplicable validation This validation makes sense for inline certificates since Consul server is holding the certificate; however, for file system certificates, Consul server never actually sees the certificate. * Support file-system-certificate as source for listener TLS certificate * Add more required mappings for the new config entry type * Construct proper TLS context based on certificate kind * Add support or SDS in xdscommon * Remove unused param * Adds back verification of certs for inline-certificates * Undo tangential changes to TLS config consumption * Remove stray curly braces * Undo some more tangential changes * Improve function name for generating API gateway secrets * Add changelog entry * Update .changelog/20873.txt Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com> * Add some nil-checking, remove outdated TODO * Update test assertions to include file-system-certificate * Add documentation for file-system-certificate config entry Add new doc to nav * Fix grammar mistake * Rename watchmaps, remove outdated TODO --------- Co-authored-by: Melisa Griffin <melisa.griffin@hashicorp.com> Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com>
This commit is contained in:
parent
e52b1702e9
commit
5e9f02d4be
|
@ -0,0 +1,3 @@
|
|||
```release-note:feature
|
||||
gateways: api-gateway can leverage listener TLS certificates available on the gateway's local filesystem by specifying the public certificate and private key path in the new file-system-certificate configuration entry
|
||||
```
|
|
@ -619,6 +619,8 @@ func MakeShadowConfigEntry(kind, name string) (structs.ConfigEntry, error) {
|
|||
return &ShadowAPIGatewayConfigEntry{APIGatewayConfigEntry: &structs.APIGatewayConfigEntry{Name: name}}, nil
|
||||
case structs.BoundAPIGateway:
|
||||
return &ShadowBoundAPIGatewayConfigEntry{BoundAPIGatewayConfigEntry: &structs.BoundAPIGatewayConfigEntry{Name: name}}, nil
|
||||
case structs.FileSystemCertificate:
|
||||
return &ShadowFileSystemCertificateConfigEntry{FileSystemCertificateConfigEntry: &structs.FileSystemCertificateConfigEntry{Name: name}}, nil
|
||||
case structs.InlineCertificate:
|
||||
return &ShadowInlineCertificateConfigEntry{InlineCertificateConfigEntry: &structs.InlineCertificateConfigEntry{Name: name}}, nil
|
||||
case structs.HTTPRoute:
|
||||
|
@ -931,6 +933,15 @@ func (s ShadowBoundAPIGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEnt
|
|||
return s.BoundAPIGatewayConfigEntry
|
||||
}
|
||||
|
||||
type ShadowFileSystemCertificateConfigEntry struct {
|
||||
ShadowBase
|
||||
*structs.FileSystemCertificateConfigEntry
|
||||
}
|
||||
|
||||
func (s ShadowFileSystemCertificateConfigEntry) GetRealConfigEntry() structs.ConfigEntry {
|
||||
return s.FileSystemCertificateConfigEntry
|
||||
}
|
||||
|
||||
type ShadowInlineCertificateConfigEntry struct {
|
||||
ShadowBase
|
||||
*structs.InlineCertificateConfigEntry
|
||||
|
|
|
@ -403,6 +403,11 @@ func (c *FSM) registerStreamSnapshotHandlers() {
|
|||
}, true)
|
||||
panicIfErr(err)
|
||||
|
||||
err = c.deps.Publisher.RegisterHandler(state.EventTopicFileSystemCertificate, func(req stream.SubscribeRequest, buf stream.SnapshotAppender) (uint64, error) {
|
||||
return c.State().FileSystemCertificateSnapshot(req, buf)
|
||||
}, true)
|
||||
panicIfErr(err)
|
||||
|
||||
err = c.deps.Publisher.RegisterHandler(state.EventTopicInlineCertificate, func(req stream.SubscribeRequest, buf stream.SnapshotAppender) (uint64, error) {
|
||||
return c.State().InlineCertificateSnapshot(req, buf)
|
||||
}, true)
|
||||
|
|
|
@ -61,7 +61,7 @@ func (r *apiGatewayReconciler) Reconcile(ctx context.Context, req controller.Req
|
|||
return reconcileEntry(r.fsm.State(), r.logger, ctx, req, r.reconcileHTTPRoute, r.cleanupRoute)
|
||||
case structs.TCPRoute:
|
||||
return reconcileEntry(r.fsm.State(), r.logger, ctx, req, r.reconcileTCPRoute, r.cleanupRoute)
|
||||
case structs.InlineCertificate:
|
||||
case structs.InlineCertificate, structs.FileSystemCertificate:
|
||||
return r.enqueueCertificateReferencedGateways(r.fsm.State(), ctx, req)
|
||||
case structs.JWTProvider:
|
||||
return r.enqueueJWTProviderReferencedGatewaysAndHTTPRoutes(r.fsm.State(), ctx, req)
|
||||
|
|
|
@ -646,6 +646,7 @@ func validateProposedConfigEntryInGraph(
|
|||
case structs.ExportedServices:
|
||||
case structs.APIGateway: // TODO Consider checkGatewayClash
|
||||
case structs.BoundAPIGateway:
|
||||
case structs.FileSystemCertificate:
|
||||
case structs.InlineCertificate:
|
||||
case structs.HTTPRoute:
|
||||
case structs.TCPRoute:
|
||||
|
|
|
@ -15,20 +15,21 @@ import (
|
|||
|
||||
// Adding events for a new config entry kind? Remember to update ConfigEntryFromStructs and ConfigEntryToStructs.
|
||||
var configEntryKindToTopic = map[string]stream.Topic{
|
||||
structs.MeshConfig: EventTopicMeshConfig,
|
||||
structs.ServiceResolver: EventTopicServiceResolver,
|
||||
structs.IngressGateway: EventTopicIngressGateway,
|
||||
structs.ServiceIntentions: EventTopicServiceIntentions,
|
||||
structs.ServiceDefaults: EventTopicServiceDefaults,
|
||||
structs.APIGateway: EventTopicAPIGateway,
|
||||
structs.TCPRoute: EventTopicTCPRoute,
|
||||
structs.HTTPRoute: EventTopicHTTPRoute,
|
||||
structs.InlineCertificate: EventTopicInlineCertificate,
|
||||
structs.BoundAPIGateway: EventTopicBoundAPIGateway,
|
||||
structs.RateLimitIPConfig: EventTopicIPRateLimit,
|
||||
structs.SamenessGroup: EventTopicSamenessGroup,
|
||||
structs.JWTProvider: EventTopicJWTProvider,
|
||||
structs.ExportedServices: EventTopicExportedServices,
|
||||
structs.MeshConfig: EventTopicMeshConfig,
|
||||
structs.ServiceResolver: EventTopicServiceResolver,
|
||||
structs.IngressGateway: EventTopicIngressGateway,
|
||||
structs.ServiceIntentions: EventTopicServiceIntentions,
|
||||
structs.ServiceDefaults: EventTopicServiceDefaults,
|
||||
structs.APIGateway: EventTopicAPIGateway,
|
||||
structs.TCPRoute: EventTopicTCPRoute,
|
||||
structs.HTTPRoute: EventTopicHTTPRoute,
|
||||
structs.FileSystemCertificate: EventTopicFileSystemCertificate,
|
||||
structs.InlineCertificate: EventTopicInlineCertificate,
|
||||
structs.BoundAPIGateway: EventTopicBoundAPIGateway,
|
||||
structs.RateLimitIPConfig: EventTopicIPRateLimit,
|
||||
structs.SamenessGroup: EventTopicSamenessGroup,
|
||||
structs.JWTProvider: EventTopicJWTProvider,
|
||||
structs.ExportedServices: EventTopicExportedServices,
|
||||
}
|
||||
|
||||
// EventSubjectConfigEntry is a stream.Subject used to route and receive events
|
||||
|
@ -147,6 +148,12 @@ func (s *Store) HTTPRouteSnapshot(req stream.SubscribeRequest, buf stream.Snapsh
|
|||
return s.configEntrySnapshot(structs.HTTPRoute, req, buf)
|
||||
}
|
||||
|
||||
// FileSystemCertificateSnapshot is a stream.SnapshotFunc that returns a snapshot of
|
||||
// inline-certificate config entries.
|
||||
func (s *Store) FileSystemCertificateSnapshot(req stream.SubscribeRequest, buf stream.SnapshotAppender) (uint64, error) {
|
||||
return s.configEntrySnapshot(structs.FileSystemCertificate, req, buf)
|
||||
}
|
||||
|
||||
// InlineCertificateSnapshot is a stream.SnapshotFunc that returns a snapshot of
|
||||
// inline-certificate config entries.
|
||||
func (s *Store) InlineCertificateSnapshot(req stream.SubscribeRequest, buf stream.SnapshotAppender) (uint64, error) {
|
||||
|
|
|
@ -46,7 +46,8 @@ func PBToStreamSubscribeRequest(req *pbsubscribe.SubscribeRequest, entMeta acl.E
|
|||
case EventTopicMeshConfig, EventTopicServiceResolver, EventTopicIngressGateway,
|
||||
EventTopicServiceIntentions, EventTopicServiceDefaults, EventTopicAPIGateway,
|
||||
EventTopicTCPRoute, EventTopicHTTPRoute, EventTopicJWTProvider, EventTopicInlineCertificate,
|
||||
EventTopicBoundAPIGateway, EventTopicSamenessGroup, EventTopicExportedServices:
|
||||
EventTopicBoundAPIGateway, EventTopicSamenessGroup, EventTopicExportedServices,
|
||||
EventTopicFileSystemCertificate:
|
||||
subject = EventSubjectConfigEntry{
|
||||
Name: named.Key,
|
||||
EnterpriseMeta: &entMeta,
|
||||
|
|
|
@ -196,23 +196,24 @@ func (db *readDB) ReadTxn() AbortTxn {
|
|||
}
|
||||
|
||||
var (
|
||||
EventTopicServiceHealth = pbsubscribe.Topic_ServiceHealth
|
||||
EventTopicServiceHealthConnect = pbsubscribe.Topic_ServiceHealthConnect
|
||||
EventTopicMeshConfig = pbsubscribe.Topic_MeshConfig
|
||||
EventTopicServiceResolver = pbsubscribe.Topic_ServiceResolver
|
||||
EventTopicIngressGateway = pbsubscribe.Topic_IngressGateway
|
||||
EventTopicServiceIntentions = pbsubscribe.Topic_ServiceIntentions
|
||||
EventTopicServiceDefaults = pbsubscribe.Topic_ServiceDefaults
|
||||
EventTopicServiceList = pbsubscribe.Topic_ServiceList
|
||||
EventTopicAPIGateway = pbsubscribe.Topic_APIGateway
|
||||
EventTopicTCPRoute = pbsubscribe.Topic_TCPRoute
|
||||
EventTopicHTTPRoute = pbsubscribe.Topic_HTTPRoute
|
||||
EventTopicInlineCertificate = pbsubscribe.Topic_InlineCertificate
|
||||
EventTopicBoundAPIGateway = pbsubscribe.Topic_BoundAPIGateway
|
||||
EventTopicIPRateLimit = pbsubscribe.Topic_IPRateLimit
|
||||
EventTopicSamenessGroup = pbsubscribe.Topic_SamenessGroup
|
||||
EventTopicJWTProvider = pbsubscribe.Topic_JWTProvider
|
||||
EventTopicExportedServices = pbsubscribe.Topic_ExportedServices
|
||||
EventTopicServiceHealth = pbsubscribe.Topic_ServiceHealth
|
||||
EventTopicServiceHealthConnect = pbsubscribe.Topic_ServiceHealthConnect
|
||||
EventTopicMeshConfig = pbsubscribe.Topic_MeshConfig
|
||||
EventTopicServiceResolver = pbsubscribe.Topic_ServiceResolver
|
||||
EventTopicIngressGateway = pbsubscribe.Topic_IngressGateway
|
||||
EventTopicServiceIntentions = pbsubscribe.Topic_ServiceIntentions
|
||||
EventTopicServiceDefaults = pbsubscribe.Topic_ServiceDefaults
|
||||
EventTopicServiceList = pbsubscribe.Topic_ServiceList
|
||||
EventTopicAPIGateway = pbsubscribe.Topic_APIGateway
|
||||
EventTopicTCPRoute = pbsubscribe.Topic_TCPRoute
|
||||
EventTopicHTTPRoute = pbsubscribe.Topic_HTTPRoute
|
||||
EventTopicFileSystemCertificate = pbsubscribe.Topic_FileSystemCertificate
|
||||
EventTopicInlineCertificate = pbsubscribe.Topic_InlineCertificate
|
||||
EventTopicBoundAPIGateway = pbsubscribe.Topic_BoundAPIGateway
|
||||
EventTopicIPRateLimit = pbsubscribe.Topic_IPRateLimit
|
||||
EventTopicSamenessGroup = pbsubscribe.Topic_SamenessGroup
|
||||
EventTopicJWTProvider = pbsubscribe.Topic_JWTProvider
|
||||
EventTopicExportedServices = pbsubscribe.Topic_ExportedServices
|
||||
)
|
||||
|
||||
func processDBChanges(tx ReadTxn, changes Changes) ([]stream.Event, error) {
|
||||
|
|
|
@ -334,6 +334,14 @@ var baseCases = map[string]testCase{
|
|||
{Name: "kind", Value: "bound-api-gateway"},
|
||||
},
|
||||
},
|
||||
"consul.usage.test.state.config_entries;datacenter=dc1;kind=file-system-certificate": {
|
||||
Name: "consul.usage.test.state.config_entries",
|
||||
Value: 0,
|
||||
Labels: []metrics.Label{
|
||||
{Name: "datacenter", Value: "dc1"},
|
||||
{Name: "kind", Value: "file-system-certificate"},
|
||||
},
|
||||
},
|
||||
"consul.usage.test.state.config_entries;datacenter=dc1;kind=inline-certificate": {
|
||||
Name: "consul.usage.test.state.config_entries",
|
||||
Value: 0,
|
||||
|
@ -607,6 +615,14 @@ var baseCases = map[string]testCase{
|
|||
{Name: "kind", Value: "bound-api-gateway"},
|
||||
},
|
||||
},
|
||||
"consul.usage.test.state.config_entries;datacenter=dc1;kind=file-system-certificate": {
|
||||
Name: "consul.usage.test.state.config_entries",
|
||||
Value: 0,
|
||||
Labels: []metrics.Label{
|
||||
{Name: "datacenter", Value: "dc1"},
|
||||
{Name: "kind", Value: "file-system-certificate"},
|
||||
},
|
||||
},
|
||||
"consul.usage.test.state.config_entries;datacenter=dc1;kind=inline-certificate": {
|
||||
Name: "consul.usage.test.state.config_entries",
|
||||
Value: 0,
|
||||
|
|
|
@ -69,6 +69,8 @@ func newConfigEntryRequest(req *structs.ConfigEntryQuery, deps ServerDataSourceD
|
|||
topic = pbsubscribe.Topic_HTTPRoute
|
||||
case structs.TCPRoute:
|
||||
topic = pbsubscribe.Topic_TCPRoute
|
||||
case structs.FileSystemCertificate:
|
||||
topic = pbsubscribe.Topic_FileSystemCertificate
|
||||
case structs.InlineCertificate:
|
||||
topic = pbsubscribe.Topic_InlineCertificate
|
||||
case structs.BoundAPIGateway:
|
||||
|
|
|
@ -63,7 +63,8 @@ func (h *handlerAPIGateway) initialize(ctx context.Context) (ConfigSnapshot, err
|
|||
snap.APIGateway.BoundListeners = make(map[string]structs.BoundAPIGatewayListener)
|
||||
snap.APIGateway.HTTPRoutes = watch.NewMap[structs.ResourceReference, *structs.HTTPRouteConfigEntry]()
|
||||
snap.APIGateway.TCPRoutes = watch.NewMap[structs.ResourceReference, *structs.TCPRouteConfigEntry]()
|
||||
snap.APIGateway.Certificates = watch.NewMap[structs.ResourceReference, *structs.InlineCertificateConfigEntry]()
|
||||
snap.APIGateway.InlineCertificates = watch.NewMap[structs.ResourceReference, *structs.InlineCertificateConfigEntry]()
|
||||
snap.APIGateway.FileSystemCertificates = watch.NewMap[structs.ResourceReference, *structs.FileSystemCertificateConfigEntry]()
|
||||
|
||||
snap.APIGateway.Upstreams = make(listenerRouteUpstreams)
|
||||
snap.APIGateway.UpstreamsSet = make(routeUpstreamSet)
|
||||
|
@ -96,7 +97,8 @@ func (h *handlerAPIGateway) subscribeToConfigEntry(ctx context.Context, kind, na
|
|||
// handleUpdate responds to changes in the api-gateway. In general, we want
|
||||
// to crawl the various resources related to or attached to the gateway and
|
||||
// collect the list of things need to generate xDS. This list of resources
|
||||
// includes the bound-api-gateway, http-routes, tcp-routes, and inline-certificates.
|
||||
// includes the bound-api-gateway, http-routes, tcp-routes,
|
||||
// file-system-certificates and inline-certificates.
|
||||
func (h *handlerAPIGateway) handleUpdate(ctx context.Context, u UpdateEvent, snap *ConfigSnapshot) error {
|
||||
if u.Err != nil {
|
||||
return fmt.Errorf("error filling agent cache: %v", u.Err)
|
||||
|
@ -113,6 +115,11 @@ func (h *handlerAPIGateway) handleUpdate(ctx context.Context, u UpdateEvent, sna
|
|||
if err := h.handleGatewayConfigUpdate(ctx, u, snap, u.CorrelationID); err != nil {
|
||||
return err
|
||||
}
|
||||
case fileSystemCertificateConfigWatchID:
|
||||
// Handle change in an attached file-system-certificate config entry
|
||||
if err := h.handleFileSystemCertConfigUpdate(ctx, u, snap); err != nil {
|
||||
return err
|
||||
}
|
||||
case inlineCertificateConfigWatchID:
|
||||
// Handle change in an attached inline-certificate config entry
|
||||
if err := h.handleInlineCertConfigUpdate(ctx, u, snap); err != nil {
|
||||
|
@ -205,12 +212,21 @@ func (h *handlerAPIGateway) handleGatewayConfigUpdate(ctx context.Context, u Upd
|
|||
for _, ref := range listener.Certificates {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
seenRefs[ref] = struct{}{}
|
||||
snap.APIGateway.Certificates.InitWatch(ref, cancel)
|
||||
|
||||
err := h.subscribeToConfigEntry(ctx, ref.Kind, ref.Name, ref.EnterpriseMeta, inlineCertificateConfigWatchID)
|
||||
if err != nil {
|
||||
// TODO May want to continue
|
||||
return err
|
||||
if ref.Kind == structs.FileSystemCertificate {
|
||||
snap.APIGateway.FileSystemCertificates.InitWatch(ref, cancel)
|
||||
|
||||
err := h.subscribeToConfigEntry(ctx, ref.Kind, ref.Name, ref.EnterpriseMeta, fileSystemCertificateConfigWatchID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
snap.APIGateway.InlineCertificates.InitWatch(ref, cancel)
|
||||
|
||||
err := h.subscribeToConfigEntry(ctx, ref.Kind, ref.Name, ref.EnterpriseMeta, inlineCertificateConfigWatchID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,9 +250,16 @@ func (h *handlerAPIGateway) handleGatewayConfigUpdate(ctx context.Context, u Upd
|
|||
return true
|
||||
})
|
||||
|
||||
snap.APIGateway.Certificates.ForEachKey(func(ref structs.ResourceReference) bool {
|
||||
snap.APIGateway.InlineCertificates.ForEachKey(func(ref structs.ResourceReference) bool {
|
||||
if _, ok := seenRefs[ref]; !ok {
|
||||
snap.APIGateway.Certificates.CancelWatch(ref)
|
||||
snap.APIGateway.InlineCertificates.CancelWatch(ref)
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
snap.APIGateway.FileSystemCertificates.ForEachKey(func(ref structs.ResourceReference) bool {
|
||||
if _, ok := seenRefs[ref]; !ok {
|
||||
snap.APIGateway.FileSystemCertificates.CancelWatch(ref)
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
@ -265,6 +288,30 @@ func (h *handlerAPIGateway) handleGatewayConfigUpdate(ctx context.Context, u Upd
|
|||
return h.watchIngressLeafCert(ctx, snap)
|
||||
}
|
||||
|
||||
func (h *handlerAPIGateway) handleFileSystemCertConfigUpdate(_ context.Context, u UpdateEvent, snap *ConfigSnapshot) error {
|
||||
resp, ok := u.Result.(*structs.ConfigEntryResponse)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid type for response: %T", u.Result)
|
||||
} else if resp == nil || resp.Entry == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, ok := resp.Entry.(*structs.FileSystemCertificateConfigEntry)
|
||||
if !ok || cfg == nil {
|
||||
return fmt.Errorf("invalid type for config entry: %T", resp.Entry)
|
||||
}
|
||||
|
||||
ref := structs.ResourceReference{
|
||||
Kind: cfg.GetKind(),
|
||||
Name: cfg.GetName(),
|
||||
EnterpriseMeta: *cfg.GetEnterpriseMeta(),
|
||||
}
|
||||
|
||||
snap.APIGateway.FileSystemCertificates.Set(ref, cfg)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleInlineCertConfigUpdate stores the certificate for the gateway
|
||||
func (h *handlerAPIGateway) handleInlineCertConfigUpdate(_ context.Context, u UpdateEvent, snap *ConfigSnapshot) error {
|
||||
resp, ok := u.Result.(*structs.ConfigEntryResponse)
|
||||
|
@ -285,7 +332,7 @@ func (h *handlerAPIGateway) handleInlineCertConfigUpdate(_ context.Context, u Up
|
|||
EnterpriseMeta: *cfg.GetEnterpriseMeta(),
|
||||
}
|
||||
|
||||
snap.APIGateway.Certificates.Set(ref, cfg)
|
||||
snap.APIGateway.InlineCertificates.Set(ref, cfg)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -421,7 +421,8 @@ func (o *configSnapshotAPIGateway) DeepCopy() *configSnapshotAPIGateway {
|
|||
}
|
||||
cp.HTTPRoutes = o.HTTPRoutes.DeepCopy()
|
||||
cp.TCPRoutes = o.TCPRoutes.DeepCopy()
|
||||
cp.Certificates = o.Certificates.DeepCopy()
|
||||
cp.InlineCertificates = o.InlineCertificates.DeepCopy()
|
||||
cp.FileSystemCertificates = o.FileSystemCertificates.DeepCopy()
|
||||
if o.Listeners != nil {
|
||||
cp.Listeners = make(map[string]structs.APIGatewayListener, len(o.Listeners))
|
||||
for k2, v2 := range o.Listeners {
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/connect"
|
||||
"github.com/hashicorp/consul/agent/consul/discoverychain"
|
||||
|
@ -17,7 +19,6 @@ import (
|
|||
"github.com/hashicorp/consul/agent/xds/config"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
"github.com/hashicorp/consul/proto/private/pbpeering"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
)
|
||||
|
||||
// TODO(ingress): Can we think of a better for this bag of data?
|
||||
|
@ -735,9 +736,11 @@ type configSnapshotAPIGateway struct {
|
|||
// UpstreamsSet is the unique set of UpstreamID the gateway routes to.
|
||||
UpstreamsSet routeUpstreamSet
|
||||
|
||||
HTTPRoutes watch.Map[structs.ResourceReference, *structs.HTTPRouteConfigEntry]
|
||||
TCPRoutes watch.Map[structs.ResourceReference, *structs.TCPRouteConfigEntry]
|
||||
Certificates watch.Map[structs.ResourceReference, *structs.InlineCertificateConfigEntry]
|
||||
HTTPRoutes watch.Map[structs.ResourceReference, *structs.HTTPRouteConfigEntry]
|
||||
TCPRoutes watch.Map[structs.ResourceReference, *structs.TCPRouteConfigEntry]
|
||||
|
||||
InlineCertificates watch.Map[structs.ResourceReference, *structs.InlineCertificateConfigEntry]
|
||||
FileSystemCertificates watch.Map[structs.ResourceReference, *structs.FileSystemCertificateConfigEntry]
|
||||
|
||||
// LeafCertWatchCancel is a CancelFunc to use when refreshing this gateway's
|
||||
// leaf cert watch with different parameters.
|
||||
|
|
|
@ -38,6 +38,7 @@ const (
|
|||
gatewayConfigWatchID = "gateway-config"
|
||||
apiGatewayConfigWatchID = "api-gateway-config"
|
||||
boundGatewayConfigWatchID = "bound-gateway-config"
|
||||
fileSystemCertificateConfigWatchID = "file-system-certificate-config"
|
||||
inlineCertificateConfigWatchID = "inline-certificate-config"
|
||||
routeConfigWatchID = "route-config"
|
||||
externalServiceIDPrefix = "external-service:"
|
||||
|
|
|
@ -27,22 +27,23 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
ServiceDefaults string = "service-defaults"
|
||||
ProxyDefaults string = "proxy-defaults"
|
||||
ServiceRouter string = "service-router"
|
||||
ServiceSplitter string = "service-splitter"
|
||||
ServiceResolver string = "service-resolver"
|
||||
IngressGateway string = "ingress-gateway"
|
||||
TerminatingGateway string = "terminating-gateway"
|
||||
ServiceIntentions string = "service-intentions"
|
||||
MeshConfig string = "mesh"
|
||||
ExportedServices string = "exported-services"
|
||||
SamenessGroup string = "sameness-group"
|
||||
APIGateway string = "api-gateway"
|
||||
BoundAPIGateway string = "bound-api-gateway"
|
||||
InlineCertificate string = "inline-certificate"
|
||||
HTTPRoute string = "http-route"
|
||||
TCPRoute string = "tcp-route"
|
||||
ServiceDefaults string = "service-defaults"
|
||||
ProxyDefaults string = "proxy-defaults"
|
||||
ServiceRouter string = "service-router"
|
||||
ServiceSplitter string = "service-splitter"
|
||||
ServiceResolver string = "service-resolver"
|
||||
IngressGateway string = "ingress-gateway"
|
||||
TerminatingGateway string = "terminating-gateway"
|
||||
ServiceIntentions string = "service-intentions"
|
||||
MeshConfig string = "mesh"
|
||||
ExportedServices string = "exported-services"
|
||||
SamenessGroup string = "sameness-group"
|
||||
APIGateway string = "api-gateway"
|
||||
BoundAPIGateway string = "bound-api-gateway"
|
||||
FileSystemCertificate string = "file-system-certificate"
|
||||
InlineCertificate string = "inline-certificate"
|
||||
HTTPRoute string = "http-route"
|
||||
TCPRoute string = "tcp-route"
|
||||
// TODO: decide if we want to highlight 'ip' keyword in the name of RateLimitIPConfig
|
||||
RateLimitIPConfig string = "control-plane-request-limit"
|
||||
JWTProvider string = "jwt-provider"
|
||||
|
@ -71,6 +72,7 @@ var AllConfigEntryKinds = []string{
|
|||
BoundAPIGateway,
|
||||
HTTPRoute,
|
||||
TCPRoute,
|
||||
FileSystemCertificate,
|
||||
InlineCertificate,
|
||||
RateLimitIPConfig,
|
||||
JWTProvider,
|
||||
|
@ -832,6 +834,8 @@ func MakeConfigEntry(kind, name string) (ConfigEntry, error) {
|
|||
return &APIGatewayConfigEntry{Name: name}, nil
|
||||
case BoundAPIGateway:
|
||||
return &BoundAPIGatewayConfigEntry{Name: name}, nil
|
||||
case FileSystemCertificate:
|
||||
return &FileSystemCertificateConfigEntry{Name: name}, nil
|
||||
case InlineCertificate:
|
||||
return &InlineCertificateConfigEntry{Name: name}, nil
|
||||
case HTTPRoute:
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package structs
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/consul/acl"
|
||||
)
|
||||
|
||||
// FileSystemCertificateConfigEntry manages the configuration for a certificate
|
||||
// and private key located in the local file system.
|
||||
type FileSystemCertificateConfigEntry struct {
|
||||
// Kind of config entry. This will be set to structs.FileSystemCertificate.
|
||||
Kind string
|
||||
|
||||
// Name is used to match the config entry with its associated file system certificate.
|
||||
Name string
|
||||
|
||||
// Certificate is the optional path to a client certificate to use for TLS connections.
|
||||
Certificate string
|
||||
|
||||
// PrivateKey is the optional path to a private key to use for TLS connections.
|
||||
PrivateKey string
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
Hash uint64 `json:",omitempty" hash:"ignore"`
|
||||
acl.EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
|
||||
RaftIndex `hash:"ignore"`
|
||||
}
|
||||
|
||||
func (e *FileSystemCertificateConfigEntry) SetHash(h uint64) {
|
||||
e.Hash = h
|
||||
}
|
||||
|
||||
func (e *FileSystemCertificateConfigEntry) GetHash() uint64 {
|
||||
return e.Hash
|
||||
}
|
||||
|
||||
func (e *FileSystemCertificateConfigEntry) GetKind() string { return FileSystemCertificate }
|
||||
func (e *FileSystemCertificateConfigEntry) GetName() string { return e.Name }
|
||||
func (e *FileSystemCertificateConfigEntry) Normalize() error {
|
||||
h, err := HashConfigEntry(e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.Hash = h
|
||||
return nil
|
||||
}
|
||||
func (e *FileSystemCertificateConfigEntry) GetMeta() map[string]string { return e.Meta }
|
||||
func (e *FileSystemCertificateConfigEntry) GetEnterpriseMeta() *acl.EnterpriseMeta {
|
||||
return &e.EnterpriseMeta
|
||||
}
|
||||
func (e *FileSystemCertificateConfigEntry) GetRaftIndex() *RaftIndex { return &e.RaftIndex }
|
||||
|
||||
func (e *FileSystemCertificateConfigEntry) Validate() error {
|
||||
return validateConfigEntryMeta(e.Meta)
|
||||
}
|
||||
|
||||
func (e *FileSystemCertificateConfigEntry) Hosts() ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func (e *FileSystemCertificateConfigEntry) CanRead(authz acl.Authorizer) error {
|
||||
var authzContext acl.AuthorizerContext
|
||||
e.FillAuthzContext(&authzContext)
|
||||
return authz.ToAllowAuthorizer().MeshReadAllowed(&authzContext)
|
||||
}
|
||||
|
||||
func (e *FileSystemCertificateConfigEntry) CanWrite(authz acl.Authorizer) error {
|
||||
var authzContext acl.AuthorizerContext
|
||||
e.FillAuthzContext(&authzContext)
|
||||
return authz.ToAllowAuthorizer().MeshWriteAllowed(&authzContext)
|
||||
}
|
|
@ -870,7 +870,8 @@ func (e *APIGatewayConfigEntry) validateListeners() error {
|
|||
ListenerProtocolTCP: true,
|
||||
}
|
||||
allowedCertificateKinds := map[string]bool{
|
||||
InlineCertificate: true,
|
||||
FileSystemCertificate: true,
|
||||
InlineCertificate: true,
|
||||
}
|
||||
|
||||
for _, listener := range e.Listeners {
|
||||
|
@ -889,7 +890,7 @@ func (e *APIGatewayConfigEntry) validateListeners() error {
|
|||
}
|
||||
for _, certificate := range listener.TLS.Certificates {
|
||||
if !allowedCertificateKinds[certificate.Kind] {
|
||||
return fmt.Errorf("unsupported certificate kind: %q, must be 'inline-certificate'", certificate.Kind)
|
||||
return fmt.Errorf("unsupported certificate kind: %q, must be 'file-system-certificate' or 'inline-certificate'", certificate.Kind)
|
||||
}
|
||||
if certificate.Name == "" {
|
||||
return fmt.Errorf("certificate reference must have a name")
|
||||
|
@ -978,6 +979,16 @@ func (a *APIGatewayTLSConfiguration) IsEmpty() bool {
|
|||
return len(a.Certificates) == 0 && len(a.MaxVersion) == 0 && len(a.MinVersion) == 0 && len(a.CipherSuites) == 0
|
||||
}
|
||||
|
||||
func (a *APIGatewayTLSConfiguration) ToGatewayTLSConfig() GatewayTLSConfig {
|
||||
return GatewayTLSConfig{
|
||||
Enabled: true,
|
||||
SDS: nil,
|
||||
TLSMinVersion: a.MinVersion,
|
||||
TLSMaxVersion: a.MaxVersion,
|
||||
CipherSuites: a.CipherSuites,
|
||||
}
|
||||
}
|
||||
|
||||
// ServiceRouteReferences is a map with a key of ServiceName type for a routed to service from a
|
||||
// bound gateway listener with a value being a slice of resource references of the routes that reference the service
|
||||
type ServiceRouteReferences map[ServiceName][]ResourceReference
|
||||
|
|
|
@ -24,6 +24,7 @@ deep-copy \
|
|||
-type DiscoverySplit \
|
||||
-type ExposeConfig \
|
||||
-type ExportedServicesConfigEntry \
|
||||
-type FileSystemCertificateConfigEntry \
|
||||
-type GatewayService \
|
||||
-type GatewayServiceTLSConfig \
|
||||
-type HTTPHeaderModifiers \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// generated by deep-copy -pointer-receiver -o ./structs.deepcopy.go -type APIGatewayListener -type BoundAPIGatewayListener -type CARoot -type CheckServiceNode -type CheckType -type CompiledDiscoveryChain -type ConnectProxyConfig -type DiscoveryFailover -type DiscoveryGraphNode -type DiscoveryResolver -type DiscoveryRoute -type DiscoverySplit -type ExposeConfig -type ExportedServicesConfigEntry -type GatewayService -type GatewayServiceTLSConfig -type HTTPHeaderModifiers -type HTTPRouteConfigEntry -type HashPolicy -type HealthCheck -type IndexedCARoots -type IngressListener -type InlineCertificateConfigEntry -type Intention -type IntentionPermission -type LoadBalancer -type MeshConfigEntry -type MeshDirectionalTLSConfig -type MeshTLSConfig -type Node -type NodeService -type PeeringServiceMeta -type ServiceConfigEntry -type ServiceConfigResponse -type ServiceConnect -type ServiceDefinition -type ServiceResolverConfigEntry -type ServiceResolverFailover -type ServiceRoute -type ServiceRouteDestination -type ServiceRouteMatch -type TCPRouteConfigEntry -type Upstream -type UpstreamConfiguration -type Status -type BoundAPIGatewayConfigEntry ./; DO NOT EDIT.
|
||||
// generated by deep-copy -pointer-receiver -o ./structs.deepcopy.go -type APIGatewayListener -type BoundAPIGatewayListener -type CARoot -type CheckServiceNode -type CheckType -type CompiledDiscoveryChain -type ConnectProxyConfig -type DiscoveryFailover -type DiscoveryGraphNode -type DiscoveryResolver -type DiscoveryRoute -type DiscoverySplit -type ExposeConfig -type ExportedServicesConfigEntry -type FileSystemCertificateConfigEntry -type GatewayService -type GatewayServiceTLSConfig -type HTTPHeaderModifiers -type HTTPRouteConfigEntry -type HashPolicy -type HealthCheck -type IndexedCARoots -type IngressListener -type InlineCertificateConfigEntry -type Intention -type IntentionPermission -type LoadBalancer -type MeshConfigEntry -type MeshDirectionalTLSConfig -type MeshTLSConfig -type Node -type NodeService -type PeeringServiceMeta -type ServiceConfigEntry -type ServiceConfigResponse -type ServiceConnect -type ServiceDefinition -type ServiceResolverConfigEntry -type ServiceResolverFailover -type ServiceRoute -type ServiceRouteDestination -type ServiceRouteMatch -type TCPRouteConfigEntry -type Upstream -type UpstreamConfiguration -type Status -type BoundAPIGatewayConfigEntry ./; DO NOT EDIT.
|
||||
|
||||
package structs
|
||||
|
||||
|
@ -318,6 +318,18 @@ func (o *ExportedServicesConfigEntry) DeepCopy() *ExportedServicesConfigEntry {
|
|||
return &cp
|
||||
}
|
||||
|
||||
// DeepCopy generates a deep copy of *FileSystemCertificateConfigEntry
|
||||
func (o *FileSystemCertificateConfigEntry) DeepCopy() *FileSystemCertificateConfigEntry {
|
||||
var cp FileSystemCertificateConfigEntry = *o
|
||||
if o.Meta != nil {
|
||||
cp.Meta = make(map[string]string, len(o.Meta))
|
||||
for k2, v2 := range o.Meta {
|
||||
cp.Meta[k2] = v2
|
||||
}
|
||||
}
|
||||
return &cp
|
||||
}
|
||||
|
||||
// DeepCopy generates a deep copy of *GatewayService
|
||||
func (o *GatewayService) DeepCopy() *GatewayService {
|
||||
var cp GatewayService = *o
|
||||
|
|
|
@ -6,22 +6,19 @@ package xds
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
||||
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||
envoy_http_jwt_authn_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/jwt_authn/v3"
|
||||
envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
|
||||
envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
|
||||
|
||||
"github.com/hashicorp/consul/agent/consul/discoverychain"
|
||||
"github.com/hashicorp/consul/agent/xds/naming"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
|
||||
"github.com/hashicorp/consul/agent/consul/discoverychain"
|
||||
"github.com/hashicorp/consul/agent/proxycfg"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/agent/xds/naming"
|
||||
"github.com/hashicorp/consul/types"
|
||||
)
|
||||
|
||||
|
@ -35,13 +32,19 @@ func (s *ResourceGenerator) makeAPIGatewayListeners(address string, cfgSnap *pro
|
|||
listenerKey := readyListener.listenerKey
|
||||
boundListener := readyListener.boundListenerCfg
|
||||
|
||||
var certs []structs.InlineCertificateConfigEntry
|
||||
// Collect the referenced certificate config entries
|
||||
var certs []structs.ConfigEntry
|
||||
for _, certRef := range boundListener.Certificates {
|
||||
cert, ok := cfgSnap.APIGateway.Certificates.Get(certRef)
|
||||
if !ok {
|
||||
continue
|
||||
switch certRef.Kind {
|
||||
case structs.InlineCertificate:
|
||||
if cert, ok := cfgSnap.APIGateway.InlineCertificates.Get(certRef); ok {
|
||||
certs = append(certs, cert)
|
||||
}
|
||||
case structs.FileSystemCertificate:
|
||||
if cert, ok := cfgSnap.APIGateway.FileSystemCertificates.Get(certRef); ok {
|
||||
certs = append(certs, cert)
|
||||
}
|
||||
}
|
||||
certs = append(certs, *cert)
|
||||
}
|
||||
|
||||
isAPIGatewayWithTLS := len(boundListener.Certificates) > 0
|
||||
|
@ -111,7 +114,7 @@ func (s *ResourceGenerator) makeAPIGatewayListeners(address string, cfgSnap *pro
|
|||
|
||||
if isAPIGatewayWithTLS {
|
||||
// construct SNI filter chains
|
||||
l.FilterChains, err = makeInlineOverrideFilterChains(
|
||||
l.FilterChains, err = s.makeInlineOverrideFilterChains(
|
||||
cfgSnap,
|
||||
cfgSnap.APIGateway.TLSConfig,
|
||||
listenerKey.Protocol,
|
||||
|
@ -225,7 +228,7 @@ func (s *ResourceGenerator) makeAPIGatewayListeners(address string, cfgSnap *pro
|
|||
sniFilterChains := []*envoy_listener_v3.FilterChain{}
|
||||
|
||||
if isAPIGatewayWithTLS {
|
||||
sniFilterChains, err = makeInlineOverrideFilterChains(cfgSnap, cfgSnap.IngressGateway.TLSConfig, listenerKey.Protocol, filterOpts, certs)
|
||||
sniFilterChains, err = s.makeInlineOverrideFilterChains(cfgSnap, cfgSnap.IngressGateway.TLSConfig, listenerKey.Protocol, filterOpts, certs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -393,11 +396,11 @@ func resolveAPIListenerTLSConfig(listenerTLSCfg structs.APIGatewayTLSConfigurati
|
|||
|
||||
// when we have multiple certificates on a single listener, we need
|
||||
// to duplicate the filter chains with multiple TLS contexts
|
||||
func makeInlineOverrideFilterChains(cfgSnap *proxycfg.ConfigSnapshot,
|
||||
func (s *ResourceGenerator) makeInlineOverrideFilterChains(cfgSnap *proxycfg.ConfigSnapshot,
|
||||
tlsCfg structs.GatewayTLSConfig,
|
||||
protocol string,
|
||||
filterOpts listenerFilterOpts,
|
||||
certs []structs.InlineCertificateConfigEntry,
|
||||
certs []structs.ConfigEntry,
|
||||
) ([]*envoy_listener_v3.FilterChain, error) {
|
||||
var chains []*envoy_listener_v3.FilterChain
|
||||
|
||||
|
@ -438,50 +441,72 @@ func makeInlineOverrideFilterChains(cfgSnap *proxycfg.ConfigSnapshot,
|
|||
// we only need to prune out overlapping hosts if we have more than
|
||||
// one certificate
|
||||
for _, cert := range certs {
|
||||
hosts, err := cert.Hosts()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse hosts from x509 certificate: %v", hosts)
|
||||
}
|
||||
for _, host := range hosts {
|
||||
if _, ok := allCertHosts[host]; ok {
|
||||
overlappingHosts[host] = struct{}{}
|
||||
switch tce := cert.(type) {
|
||||
case *structs.InlineCertificateConfigEntry:
|
||||
hosts, err := tce.Hosts()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse hosts from x509 certificate: %v", hosts)
|
||||
}
|
||||
allCertHosts[host] = struct{}{}
|
||||
for _, host := range hosts {
|
||||
if _, ok := allCertHosts[host]; ok {
|
||||
overlappingHosts[host] = struct{}{}
|
||||
}
|
||||
allCertHosts[host] = struct{}{}
|
||||
}
|
||||
default:
|
||||
// do nothing for FileSystemCertificates because we don't actually have the certificate available
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructTLSContext := func(certConfig structs.ConfigEntry) (*envoy_tls_v3.CommonTlsContext, error) {
|
||||
switch tce := certConfig.(type) {
|
||||
case *structs.InlineCertificateConfigEntry:
|
||||
return makeInlineTLSContextFromGatewayTLSConfig(tlsCfg, tce), nil
|
||||
case *structs.FileSystemCertificateConfigEntry:
|
||||
return makeFileSystemTLSContextFromGatewayTLSConfig(tlsCfg, tce), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported config entry kind %s", tce.GetKind())
|
||||
}
|
||||
}
|
||||
|
||||
for _, cert := range certs {
|
||||
var hosts []string
|
||||
|
||||
// if we only have one cert, we just use it for all ingress
|
||||
if multipleCerts {
|
||||
// otherwise, we need an SNI per cert and to fallback to our ingress
|
||||
// gateway certificate signed by our Consul CA
|
||||
certHosts, err := cert.Hosts()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse hosts from x509 certificate: %v", hosts)
|
||||
}
|
||||
// filter out any overlapping hosts so we don't have collisions in our filter chains
|
||||
for _, host := range certHosts {
|
||||
if _, ok := overlappingHosts[host]; !ok {
|
||||
hosts = append(hosts, host)
|
||||
switch tce := cert.(type) {
|
||||
case *structs.InlineCertificateConfigEntry:
|
||||
certHosts, err := tce.Hosts()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse hosts from x509 certificate: %v", hosts)
|
||||
}
|
||||
// filter out any overlapping hosts so we don't have collisions in our filter chains
|
||||
for _, host := range certHosts {
|
||||
if _, ok := overlappingHosts[host]; !ok {
|
||||
hosts = append(hosts, host)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(hosts) == 0 {
|
||||
// all of our hosts are overlapping, so we just skip this filter and it'll be
|
||||
// handled by the default filter chain
|
||||
continue
|
||||
if len(hosts) == 0 {
|
||||
// all of our hosts are overlapping, so we just skip this filter and it'll be
|
||||
// handled by the default filter chain
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := constructChain(cert.Name, hosts, makeInlineTLSContextFromGatewayTLSConfig(tlsCfg, cert)); err != nil {
|
||||
tlsContext, err := constructTLSContext(cert)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := constructChain(cert.GetName(), hosts, tlsContext); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if multipleCerts {
|
||||
if len(certs) > 1 {
|
||||
// if we have more than one cert, add a default handler that uses the leaf cert from connect
|
||||
if err := constructChain("default", nil, makeCommonTLSContext(cfgSnap.Leaf(), cfgSnap.RootPEMs(), makeTLSParametersFromGatewayTLSConfig(tlsCfg))); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
||||
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||
envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
|
||||
"github.com/hashicorp/consul/agent/xds/naming"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
@ -17,6 +16,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/consul/agent/proxycfg"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/agent/xds/naming"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
"github.com/hashicorp/consul/types"
|
||||
)
|
||||
|
@ -391,7 +391,26 @@ func makeTLSParametersFromGatewayTLSConfig(tlsCfg structs.GatewayTLSConfig) *env
|
|||
return makeTLSParametersFromTLSConfig(tlsCfg.TLSMinVersion, tlsCfg.TLSMaxVersion, tlsCfg.CipherSuites)
|
||||
}
|
||||
|
||||
func makeInlineTLSContextFromGatewayTLSConfig(tlsCfg structs.GatewayTLSConfig, cert structs.InlineCertificateConfigEntry) *envoy_tls_v3.CommonTlsContext {
|
||||
func makeFileSystemTLSContextFromGatewayTLSConfig(tlsCfg structs.GatewayTLSConfig, cert *structs.FileSystemCertificateConfigEntry) *envoy_tls_v3.CommonTlsContext {
|
||||
return &envoy_tls_v3.CommonTlsContext{
|
||||
TlsParams: makeTLSParametersFromGatewayTLSConfig(tlsCfg),
|
||||
TlsCertificateSdsSecretConfigs: []*envoy_tls_v3.SdsSecretConfig{
|
||||
{
|
||||
// Delivering via SDS is required in order to get file system watches today.
|
||||
// https://github.com/envoyproxy/envoy/issues/10387
|
||||
Name: cert.Name, // Reference the secret returned in xds/secrets.go by name here
|
||||
SdsConfig: &envoy_core_v3.ConfigSource{
|
||||
ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_Ads{
|
||||
Ads: &envoy_core_v3.AggregatedConfigSource{},
|
||||
},
|
||||
ResourceApiVersion: envoy_core_v3.ApiVersion_V3,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func makeInlineTLSContextFromGatewayTLSConfig(tlsCfg structs.GatewayTLSConfig, cert *structs.InlineCertificateConfigEntry) *envoy_tls_v3.CommonTlsContext {
|
||||
return &envoy_tls_v3.CommonTlsContext{
|
||||
TlsParams: makeTLSParametersFromGatewayTLSConfig(tlsCfg),
|
||||
TlsCertificates: []*envoy_tls_v3.TlsCertificate{{
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
||||
envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/hashicorp/consul/agent/proxycfg"
|
||||
|
@ -21,13 +23,45 @@ func (s *ResourceGenerator) secretsFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot
|
|||
}
|
||||
|
||||
switch cfgSnap.Kind {
|
||||
case structs.ServiceKindAPIGateway:
|
||||
return s.secretsFromSnapshotAPIGateway(cfgSnap), nil // return any attached certs
|
||||
case structs.ServiceKindConnectProxy,
|
||||
structs.ServiceKindTerminatingGateway,
|
||||
structs.ServiceKindMeshGateway,
|
||||
structs.ServiceKindIngressGateway,
|
||||
structs.ServiceKindAPIGateway:
|
||||
structs.ServiceKindIngressGateway:
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind)
|
||||
}
|
||||
}
|
||||
|
||||
// secretsFromSnapshotAPIGateway returns the "secrets" for an api-gateway service
|
||||
func (s *ResourceGenerator) secretsFromSnapshotAPIGateway(cfgSnap *proxycfg.ConfigSnapshot) []proto.Message {
|
||||
var resources []proto.Message
|
||||
|
||||
cfgSnap.APIGateway.FileSystemCertificates.ForEachKey(func(ref structs.ResourceReference) bool {
|
||||
cert, ok := cfgSnap.APIGateway.FileSystemCertificates.Get(ref)
|
||||
if !ok || cert == nil {
|
||||
return true
|
||||
}
|
||||
resources = append(resources, &envoy_tls_v3.Secret{
|
||||
Name: ref.Name,
|
||||
Type: &envoy_tls_v3.Secret_TlsCertificate{
|
||||
TlsCertificate: &envoy_tls_v3.TlsCertificate{
|
||||
CertificateChain: &envoy_core_v3.DataSource{
|
||||
Specifier: &envoy_core_v3.DataSource_Filename{
|
||||
Filename: cert.Certificate,
|
||||
}},
|
||||
PrivateKey: &envoy_core_v3.DataSource{
|
||||
Specifier: &envoy_core_v3.DataSource_Filename{
|
||||
Filename: cert.PrivateKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
return true
|
||||
})
|
||||
|
||||
return resources
|
||||
}
|
||||
|
|
|
@ -29,13 +29,14 @@ const (
|
|||
SamenessGroup string = "sameness-group"
|
||||
RateLimitIPConfig string = "control-plane-request-limit"
|
||||
|
||||
ProxyConfigGlobal string = "global"
|
||||
MeshConfigMesh string = "mesh"
|
||||
APIGateway string = "api-gateway"
|
||||
TCPRoute string = "tcp-route"
|
||||
InlineCertificate string = "inline-certificate"
|
||||
HTTPRoute string = "http-route"
|
||||
JWTProvider string = "jwt-provider"
|
||||
ProxyConfigGlobal string = "global"
|
||||
MeshConfigMesh string = "mesh"
|
||||
APIGateway string = "api-gateway"
|
||||
TCPRoute string = "tcp-route"
|
||||
FileSystemCertificate string = "file-system-certificate"
|
||||
InlineCertificate string = "inline-certificate"
|
||||
HTTPRoute string = "http-route"
|
||||
JWTProvider string = "jwt-provider"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -447,6 +448,8 @@ func makeConfigEntry(kind, name string) (ConfigEntry, error) {
|
|||
return &APIGatewayConfigEntry{Kind: kind, Name: name}, nil
|
||||
case TCPRoute:
|
||||
return &TCPRouteConfigEntry{Kind: kind, Name: name}, nil
|
||||
case FileSystemCertificate:
|
||||
return &FileSystemCertificateConfigEntry{Kind: kind, Name: name}, nil
|
||||
case InlineCertificate:
|
||||
return &InlineCertificateConfigEntry{Kind: kind, Name: name}, nil
|
||||
case HTTPRoute:
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package api
|
||||
|
||||
type FileSystemCertificateConfigEntry struct {
|
||||
// Kind of the config entry. This should be set to api.FileSystemCertificate.
|
||||
Kind string
|
||||
|
||||
Name string
|
||||
|
||||
// Certificate is the path to a client certificate to use for TLS connections.
|
||||
Certificate string `json:",omitempty" alias:"certificate"`
|
||||
|
||||
// PrivateKey is the path to a private key to use for TLS connections.
|
||||
PrivateKey string `json:",omitempty" alias:"private_key"`
|
||||
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
|
||||
// CreateIndex is the Raft index this entry was created at. This is a
|
||||
// read-only field.
|
||||
CreateIndex uint64
|
||||
|
||||
// ModifyIndex is used for the Check-And-Set operations and can also be fed
|
||||
// back into the WaitIndex of the QueryOptions in order to perform blocking
|
||||
// queries.
|
||||
ModifyIndex uint64
|
||||
|
||||
// Partition is the partition the config entry is associated with.
|
||||
// Partitioning is a Consul Enterprise feature.
|
||||
Partition string `json:",omitempty"`
|
||||
|
||||
// Namespace is the namespace the config entry is associated with.
|
||||
// Namespacing is a Consul Enterprise feature.
|
||||
Namespace string `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (a *FileSystemCertificateConfigEntry) GetKind() string { return FileSystemCertificate }
|
||||
func (a *FileSystemCertificateConfigEntry) GetName() string { return a.Name }
|
||||
func (a *FileSystemCertificateConfigEntry) GetPartition() string { return a.Partition }
|
||||
func (a *FileSystemCertificateConfigEntry) GetNamespace() string { return a.Namespace }
|
||||
func (a *FileSystemCertificateConfigEntry) GetMeta() map[string]string { return a.Meta }
|
||||
func (a *FileSystemCertificateConfigEntry) GetCreateIndex() uint64 { return a.CreateIndex }
|
||||
func (a *FileSystemCertificateConfigEntry) GetModifyIndex() uint64 { return a.ModifyIndex }
|
|
@ -8,6 +8,7 @@ import (
|
|||
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
|
||||
envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||
envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
|
||||
envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
@ -111,7 +112,7 @@ func IndexResources(logger hclog.Logger, resources map[string][]proto.Message) *
|
|||
}
|
||||
|
||||
func GetResourceName(res proto.Message) string {
|
||||
// NOTE: this only covers types that we currently care about for LDS/RDS/CDS/EDS
|
||||
// NOTE: this only covers types that we currently care about for LDS/RDS/CDS/EDS/SDS
|
||||
switch x := res.(type) {
|
||||
case *envoy_listener_v3.Listener: // LDS
|
||||
return x.Name
|
||||
|
@ -121,6 +122,8 @@ func GetResourceName(res proto.Message) string {
|
|||
return x.Name
|
||||
case *envoy_endpoint_v3.ClusterLoadAssignment: // EDS
|
||||
return x.ClusterName
|
||||
case *envoy_tls_v3.Secret: // SDS
|
||||
return x.Name
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
@ -133,6 +136,7 @@ func EmptyIndexedResources() *IndexedResources {
|
|||
RouteType: make(map[string]proto.Message),
|
||||
ClusterType: make(map[string]proto.Message),
|
||||
EndpointType: make(map[string]proto.Message),
|
||||
SecretType: make(map[string]proto.Message),
|
||||
},
|
||||
ChildIndex: map[string]map[string][]string{
|
||||
ListenerType: make(map[string][]string),
|
||||
|
|
|
@ -408,6 +408,24 @@ func ExposePathFromStructs(t *structs.ExposePath, s *ExposePath) {
|
|||
s.Protocol = t.Protocol
|
||||
s.ParsedFromCheck = t.ParsedFromCheck
|
||||
}
|
||||
func FileSystemCertificateToStructs(s *FileSystemCertificate, t *structs.FileSystemCertificateConfigEntry) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
t.Certificate = s.Certificate
|
||||
t.PrivateKey = s.PrivateKey
|
||||
t.Meta = s.Meta
|
||||
t.Hash = s.Hash
|
||||
}
|
||||
func FileSystemCertificateFromStructs(t *structs.FileSystemCertificateConfigEntry, s *FileSystemCertificate) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
s.Certificate = t.Certificate
|
||||
s.PrivateKey = t.PrivateKey
|
||||
s.Meta = t.Meta
|
||||
s.Hash = t.Hash
|
||||
}
|
||||
func GatewayServiceTLSConfigToStructs(s *GatewayServiceTLSConfig, t *structs.GatewayServiceTLSConfig) {
|
||||
if s == nil {
|
||||
return
|
||||
|
|
|
@ -85,6 +85,14 @@ func ConfigEntryToStructs(s *ConfigEntry) structs.ConfigEntry {
|
|||
pbcommon.RaftIndexToStructs(s.RaftIndex, &target.RaftIndex)
|
||||
pbcommon.EnterpriseMetaToStructs(s.EnterpriseMeta, &target.EnterpriseMeta)
|
||||
return &target
|
||||
case Kind_KindFileSystemCertificate:
|
||||
var target structs.FileSystemCertificateConfigEntry
|
||||
target.Name = s.Name
|
||||
|
||||
FileSystemCertificateToStructs(s.GetFileSystemCertificate(), &target)
|
||||
pbcommon.RaftIndexToStructs(s.RaftIndex, &target.RaftIndex)
|
||||
pbcommon.EnterpriseMetaToStructs(s.EnterpriseMeta, &target.EnterpriseMeta)
|
||||
return &target
|
||||
case Kind_KindInlineCertificate:
|
||||
var target structs.InlineCertificateConfigEntry
|
||||
target.Name = s.Name
|
||||
|
@ -213,6 +221,14 @@ func ConfigEntryFromStructs(s structs.ConfigEntry) *ConfigEntry {
|
|||
configEntry.Entry = &ConfigEntry_HTTPRoute{
|
||||
HTTPRoute: &route,
|
||||
}
|
||||
case *structs.FileSystemCertificateConfigEntry:
|
||||
var cert FileSystemCertificate
|
||||
FileSystemCertificateFromStructs(v, &cert)
|
||||
|
||||
configEntry.Kind = Kind_KindFileSystemCertificate
|
||||
configEntry.Entry = &ConfigEntry_FileSystemCertificate{
|
||||
FileSystemCertificate: &cert,
|
||||
}
|
||||
case *structs.InlineCertificateConfigEntry:
|
||||
var cert InlineCertificate
|
||||
InlineCertificateFromStructs(v, &cert)
|
||||
|
|
|
@ -657,6 +657,16 @@ func (msg *BoundAPIGatewayListener) UnmarshalBinary(b []byte) error {
|
|||
return proto.Unmarshal(b, msg)
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler
|
||||
func (msg *FileSystemCertificate) MarshalBinary() ([]byte, error) {
|
||||
return proto.Marshal(msg)
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler
|
||||
func (msg *FileSystemCertificate) UnmarshalBinary(b []byte) error {
|
||||
return proto.Unmarshal(b, msg)
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler
|
||||
func (msg *InlineCertificate) MarshalBinary() ([]byte, error) {
|
||||
return proto.Marshal(msg)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -54,6 +54,7 @@ enum Kind {
|
|||
KindSamenessGroup = 11;
|
||||
KindJWTProvider = 12;
|
||||
KindExportedServices = 13;
|
||||
KindFileSystemCertificate = 14;
|
||||
}
|
||||
|
||||
message ConfigEntry {
|
||||
|
@ -77,6 +78,7 @@ message ConfigEntry {
|
|||
SamenessGroup SamenessGroup = 15;
|
||||
JWTProvider JWTProvider = 16;
|
||||
ExportedServices ExportedServices = 17;
|
||||
FileSystemCertificate FileSystemCertificate = 18;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -867,6 +869,19 @@ message BoundAPIGatewayListener {
|
|||
repeated ResourceReference Routes = 3;
|
||||
}
|
||||
|
||||
// mog annotation:
|
||||
//
|
||||
// target=github.com/hashicorp/consul/agent/structs.FileSystemCertificateConfigEntry
|
||||
// output=config_entry.gen.go
|
||||
// name=Structs
|
||||
// ignore-fields=Kind,Name,RaftIndex,EnterpriseMeta
|
||||
message FileSystemCertificate {
|
||||
map<string, string> Meta = 1;
|
||||
string Certificate = 2;
|
||||
string PrivateKey = 3;
|
||||
uint64 Hash = 4;
|
||||
}
|
||||
|
||||
// mog annotation:
|
||||
//
|
||||
// target=github.com/hashicorp/consul/agent/structs.InlineCertificateConfigEntry
|
||||
|
|
|
@ -80,6 +80,8 @@ const (
|
|||
Topic_JWTProvider Topic = 16
|
||||
// ExportedServices topic contains events for changes to exported-services.
|
||||
Topic_ExportedServices Topic = 17
|
||||
// FileSystemCertificate topic contains events for changes to file-system-certificates.
|
||||
Topic_FileSystemCertificate Topic = 18
|
||||
)
|
||||
|
||||
// Enum value maps for Topic.
|
||||
|
@ -103,26 +105,28 @@ var (
|
|||
15: "SamenessGroup",
|
||||
16: "JWTProvider",
|
||||
17: "ExportedServices",
|
||||
18: "FileSystemCertificate",
|
||||
}
|
||||
Topic_value = map[string]int32{
|
||||
"Unknown": 0,
|
||||
"ServiceHealth": 1,
|
||||
"ServiceHealthConnect": 2,
|
||||
"MeshConfig": 3,
|
||||
"ServiceResolver": 4,
|
||||
"IngressGateway": 5,
|
||||
"ServiceIntentions": 6,
|
||||
"ServiceList": 7,
|
||||
"ServiceDefaults": 8,
|
||||
"APIGateway": 9,
|
||||
"TCPRoute": 10,
|
||||
"HTTPRoute": 11,
|
||||
"InlineCertificate": 12,
|
||||
"BoundAPIGateway": 13,
|
||||
"IPRateLimit": 14,
|
||||
"SamenessGroup": 15,
|
||||
"JWTProvider": 16,
|
||||
"ExportedServices": 17,
|
||||
"Unknown": 0,
|
||||
"ServiceHealth": 1,
|
||||
"ServiceHealthConnect": 2,
|
||||
"MeshConfig": 3,
|
||||
"ServiceResolver": 4,
|
||||
"IngressGateway": 5,
|
||||
"ServiceIntentions": 6,
|
||||
"ServiceList": 7,
|
||||
"ServiceDefaults": 8,
|
||||
"APIGateway": 9,
|
||||
"TCPRoute": 10,
|
||||
"HTTPRoute": 11,
|
||||
"InlineCertificate": 12,
|
||||
"BoundAPIGateway": 13,
|
||||
"IPRateLimit": 14,
|
||||
"SamenessGroup": 15,
|
||||
"JWTProvider": 16,
|
||||
"ExportedServices": 17,
|
||||
"FileSystemCertificate": 18,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -1004,7 +1008,7 @@ var file_private_pbsubscribe_subscribe_proto_rawDesc = []byte{
|
|||
0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x2a, 0xdb, 0x02, 0x0a, 0x05, 0x54, 0x6f,
|
||||
0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x2a, 0xf6, 0x02, 0x0a, 0x05, 0x54, 0x6f,
|
||||
0x70, 0x69, 0x63, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00,
|
||||
0x12, 0x11, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74,
|
||||
0x68, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x65,
|
||||
|
@ -1026,26 +1030,28 @@ var file_private_pbsubscribe_subscribe_proto_rawDesc = []byte{
|
|||
0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x10, 0x0f,
|
||||
0x12, 0x0f, 0x0a, 0x0b, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x10,
|
||||
0x10, 0x12, 0x14, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x10, 0x11, 0x2a, 0x29, 0x0a, 0x09, 0x43, 0x61, 0x74, 0x61, 0x6c,
|
||||
0x6f, 0x67, 0x4f, 0x70, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
|
||||
0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
|
||||
0x10, 0x01, 0x32, 0x61, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67,
|
||||
0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a,
|
||||
0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x75, 0x62,
|
||||
0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72,
|
||||
0x69, 0x62, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x08, 0xe2, 0x86, 0x04, 0x04, 0x08,
|
||||
0x02, 0x10, 0x09, 0x30, 0x01, 0x42, 0x9a, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x75,
|
||||
0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x42, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
|
||||
0x62, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x69,
|
||||
0x76, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x62, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
|
||||
0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
|
||||
0x62, 0x65, 0xca, 0x02, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0xe2, 0x02,
|
||||
0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
|
||||
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
|
||||
0x62, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x76, 0x69, 0x63, 0x65, 0x73, 0x10, 0x11, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x69, 0x6c, 0x65, 0x53,
|
||||
0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
|
||||
0x10, 0x12, 0x2a, 0x29, 0x0a, 0x09, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x4f, 0x70, 0x12,
|
||||
0x0c, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x10, 0x00, 0x12, 0x0e, 0x0a,
|
||||
0x0a, 0x44, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x10, 0x01, 0x32, 0x61, 0x0a,
|
||||
0x17, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x73,
|
||||
0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73,
|
||||
0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x1b, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62,
|
||||
0x65, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x10, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2e, 0x45,
|
||||
0x76, 0x65, 0x6e, 0x74, 0x22, 0x08, 0xe2, 0x86, 0x04, 0x04, 0x08, 0x02, 0x10, 0x09, 0x30, 0x01,
|
||||
0x42, 0x9a, 0x01, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
|
||||
0x62, 0x65, 0x42, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f,
|
||||
0x70, 0x62, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0xa2, 0x02, 0x03, 0x53, 0x58,
|
||||
0x58, 0xaa, 0x02, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0xca, 0x02, 0x09,
|
||||
0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0xe2, 0x02, 0x15, 0x53, 0x75, 0x62, 0x73,
|
||||
0x63, 0x72, 0x69, 0x62, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0xea, 0x02, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -109,6 +109,9 @@ enum Topic {
|
|||
|
||||
// ExportedServices topic contains events for changes to exported-services.
|
||||
ExportedServices = 17;
|
||||
|
||||
// FileSystemCertificate topic contains events for changes to file-system-certificates.
|
||||
FileSystemCertificate = 18;
|
||||
}
|
||||
|
||||
message NamedSubject {
|
||||
|
|
|
@ -39,23 +39,24 @@ The corresponding CLI command is [`consul config write`](/consul/commands/config
|
|||
|
||||
The ACL required depends on the config entry being written:
|
||||
|
||||
| Config Entry Kind | Required ACLs |
|
||||
| ------------------- | -------------------------------- |
|
||||
| api-gateway | `mesh:write` or `operator:write` |
|
||||
| bound-api-gateway | Not writable. |
|
||||
| exported-services | `mesh:write` or `operator:write` |
|
||||
| http-route | `mesh:write` or `operator:write` |
|
||||
| ingress-gateway | `mesh:write` or `operator:write` |
|
||||
| inline-certificate | `mesh:write` or `operator:write` |
|
||||
| mesh | `mesh:write` or `operator:write` |
|
||||
| proxy-defaults | `mesh:write` or `operator:write` |
|
||||
| service-defaults | `service:write` |
|
||||
| service-intentions | `intentions:write` |
|
||||
| service-resolver | `service:write` |
|
||||
| service-router | `service:write` |
|
||||
| service-splitter | `service:write` |
|
||||
| tcp-route | `mesh:write` or `operator:write` |
|
||||
| terminating-gateway | `mesh:write` or `operator:write` |
|
||||
| Config Entry Kind | Required ACLs |
|
||||
| ----------------------- | -------------------------------- |
|
||||
| api-gateway | `mesh:write` or `operator:write` |
|
||||
| bound-api-gateway | Not writable. |
|
||||
| exported-services | `mesh:write` or `operator:write` |
|
||||
| file-system-certificate | `mesh:write` or `operator:write` |
|
||||
| http-route | `mesh:write` or `operator:write` |
|
||||
| ingress-gateway | `mesh:write` or `operator:write` |
|
||||
| inline-certificate | `mesh:write` or `operator:write` |
|
||||
| mesh | `mesh:write` or `operator:write` |
|
||||
| proxy-defaults | `mesh:write` or `operator:write` |
|
||||
| service-defaults | `service:write` |
|
||||
| service-intentions | `intentions:write` |
|
||||
| service-resolver | `service:write` |
|
||||
| service-router | `service:write` |
|
||||
| service-splitter | `service:write` |
|
||||
| tcp-route | `mesh:write` or `operator:write` |
|
||||
| terminating-gateway | `mesh:write` or `operator:write` |
|
||||
|
||||
### Query Parameters
|
||||
|
||||
|
@ -114,23 +115,24 @@ The corresponding CLI command is [`consul config read`](/consul/commands/config/
|
|||
|
||||
The ACL required depends on the config entry kind being read:
|
||||
|
||||
| Config Entry Kind | Required ACLs |
|
||||
| ------------------- | -------------------------------- |
|
||||
| api-gateway | `service:read` |
|
||||
| bound-api-gateway | `service:read` |
|
||||
| exported-services | `mesh:read` or `operator:read` |
|
||||
| http-route | `mesh:read` or `operator:read` |
|
||||
| ingress-gateway | `service:read` |
|
||||
| inline-certificate | `mesh:read` or `operator:read` |
|
||||
| mesh | No ACL required |
|
||||
| proxy-defaults | No ACL required |
|
||||
| service-defaults | `service:read` |
|
||||
| service-intentions | `intentions:read` |
|
||||
| service-resolver | `service:read` |
|
||||
| service-router | `service:read` |
|
||||
| service-splitter | `service:read` |
|
||||
| tcp-route | `mesh:read` or `operator:read` |
|
||||
| terminating-gateway | `service:read` |
|
||||
| Config Entry Kind | Required ACLs |
|
||||
| ----------------------- | -------------------------------- |
|
||||
| api-gateway | `service:read` |
|
||||
| bound-api-gateway | `service:read` |
|
||||
| exported-services | `mesh:read` or `operator:read` |
|
||||
| file-system-certificate | `mesh:read` or `operator:read` |
|
||||
| http-route | `mesh:read` or `operator:read` |
|
||||
| ingress-gateway | `service:read` |
|
||||
| inline-certificate | `mesh:read` or `operator:read` |
|
||||
| mesh | No ACL required |
|
||||
| proxy-defaults | No ACL required |
|
||||
| service-defaults | `service:read` |
|
||||
| service-intentions | `intentions:read` |
|
||||
| service-resolver | `service:read` |
|
||||
| service-router | `service:read` |
|
||||
| service-splitter | `service:read` |
|
||||
| tcp-route | `mesh:read` or `operator:read` |
|
||||
| terminating-gateway | `service:read` |
|
||||
|
||||
### Path Parameters
|
||||
|
||||
|
@ -192,23 +194,24 @@ The table below shows this endpoint's support for
|
|||
|
||||
The ACL required depends on the config entry kind being read:
|
||||
|
||||
| Config Entry Kind | Required ACLs |
|
||||
| ------------------- | -------------------------------- |
|
||||
| api-gateway | `service:read` |
|
||||
| bound-api-gateway | `service:read` |
|
||||
| exported-services | `mesh:read` or `operator:read` |
|
||||
| http-route | `mesh:read` or `operator:read` |
|
||||
| ingress-gateway | `service:read` |
|
||||
| inline-certificate | `mesh:read` or `operator:read` |
|
||||
| mesh | No ACL required |
|
||||
| proxy-defaults | No ACL required |
|
||||
| service-defaults | `service:read` |
|
||||
| service-intentions | `intentions:read` |
|
||||
| service-resolver | `service:read` |
|
||||
| service-router | `service:read` |
|
||||
| service-splitter | `service:read` |
|
||||
| tcp-route | `mesh:read` or `operator:read` |
|
||||
| terminating-gateway | `service:read` |
|
||||
| Config Entry Kind | Required ACLs |
|
||||
| ----------------------- | -------------------------------- |
|
||||
| api-gateway | `service:read` |
|
||||
| bound-api-gateway | `service:read` |
|
||||
| exported-services | `mesh:read` or `operator:read` |
|
||||
| file-system-certificate | `mesh:read` or `operator:read` |
|
||||
| http-route | `mesh:read` or `operator:read` |
|
||||
| ingress-gateway | `service:read` |
|
||||
| inline-certificate | `mesh:read` or `operator:read` |
|
||||
| mesh | No ACL required |
|
||||
| proxy-defaults | No ACL required |
|
||||
| service-defaults | `service:read` |
|
||||
| service-intentions | `intentions:read` |
|
||||
| service-resolver | `service:read` |
|
||||
| service-router | `service:read` |
|
||||
| service-splitter | `service:read` |
|
||||
| tcp-route | `mesh:read` or `operator:read` |
|
||||
| terminating-gateway | `service:read` |
|
||||
|
||||
The corresponding CLI command is [`consul config list`](/consul/commands/config/list).
|
||||
|
||||
|
@ -276,23 +279,24 @@ The table below shows this endpoint's support for
|
|||
|
||||
The ACL required depends on the config entry kind being deleted:
|
||||
|
||||
| Config Entry Kind | Required ACLs |
|
||||
| ------------------- | -------------------------------- |
|
||||
| api-gateway | `mesh:write` or `operator:write` |
|
||||
| bound-api-gateway | Not writable. |
|
||||
| exported-services | `mesh:write` or `operator:write` |
|
||||
| http-route | `mesh:write` or `operator:write` |
|
||||
| ingress-gateway | `mesh:write` or `operator:write` |
|
||||
| inline-certificate | `mesh:write` or `operator:write` |
|
||||
| mesh | `mesh:write` or `operator:write` |
|
||||
| proxy-defaults | `mesh:write` or `operator:write` |
|
||||
| service-defaults | `service:write` |
|
||||
| service-intentions | `intentions:write` |
|
||||
| service-resolver | `service:write` |
|
||||
| service-router | `service:write` |
|
||||
| service-splitter | `service:write` |
|
||||
| tcp-route | `mesh:write` or `operator:write` |
|
||||
| terminating-gateway | `mesh:write` or `operator:write` |
|
||||
| Config Entry Kind | Required ACLs |
|
||||
| ----------------------- | -------------------------------- |
|
||||
| api-gateway | `mesh:write` or `operator:write` |
|
||||
| bound-api-gateway | Not writable. |
|
||||
| exported-services | `mesh:write` or `operator:write` |
|
||||
| file-system-certificate | `mesh:write` or `operator:write` |
|
||||
| http-route | `mesh:write` or `operator:write` |
|
||||
| ingress-gateway | `mesh:write` or `operator:write` |
|
||||
| inline-certificate | `mesh:write` or `operator:write` |
|
||||
| mesh | `mesh:write` or `operator:write` |
|
||||
| proxy-defaults | `mesh:write` or `operator:write` |
|
||||
| service-defaults | `service:write` |
|
||||
| service-intentions | `intentions:write` |
|
||||
| service-resolver | `service:write` |
|
||||
| service-router | `service:write` |
|
||||
| service-splitter | `service:write` |
|
||||
| tcp-route | `mesh:write` or `operator:write` |
|
||||
| terminating-gateway | `mesh:write` or `operator:write` |
|
||||
|
||||
The corresponding CLI command is [`consul config delete`](/consul/commands/config/delete).
|
||||
|
||||
|
|
|
@ -31,19 +31,19 @@ The following list outlines field hierarchy, language-specific data types, and r
|
|||
- [`MaxVersion`](#listeners-tls-maxversion): string | no default
|
||||
- [`CipherSuites`](#listeners-tls-ciphersuites): list of strings | Envoy default cipher suites
|
||||
- [`Certificates`](#listeners-tls-certificates): list of objects | no default
|
||||
- [`Kind`](#listeners-tls-certificates-kind): string | must be `"inline-certificate"`
|
||||
- [`Kind`](#listeners-tls-certificates-kind): string | no default
|
||||
- [`Name`](#listeners-tls-certificates-name): string | no default
|
||||
- [`Namespace`](#listeners-tls-certificates-namespace): string | no default <EnterpriseAlert inline />
|
||||
- [`Partition`](#listeners-tls-certificates-partition): string | no default <EnterpriseAlert inline />
|
||||
- [`default`](#listeners-default): map
|
||||
- [`JWT`](#listeners-default-jwt): map
|
||||
- [`JWT`](#listeners-default-jwt): map
|
||||
- [`Providers`](#listeners-default-jwt-providers): list
|
||||
- [`Name`](#listeners-default-jwt-providers): string
|
||||
- [`VerifyClaims`](#listeners-default-jwt-providers): map
|
||||
- [`Path`](#listeners-default-jwt-providers): list
|
||||
- [`Value`](#listeners-default-jwt-providers): string
|
||||
- [`override`](#listeners-override): map
|
||||
- [`JWT`](#listeners-override-jwt): map
|
||||
- [`JWT`](#listeners-override-jwt): map
|
||||
- [`Providers`](#listeners-override-jwt-providers): list
|
||||
- [`Name`](#listeners-override-jwt-providers): string
|
||||
- [`VerifyClaims`](#listeners-override-jwt-providers): map
|
||||
|
@ -81,8 +81,8 @@ Listeners = [
|
|||
]
|
||||
Certificates = [
|
||||
{
|
||||
Kind = "inline-certificate"
|
||||
Name = "<name of inline-certificate>"
|
||||
Kind = "file-system-certificate"
|
||||
Name = "<name of file-system-certificate>"
|
||||
Namespace = "<enterprise: namespace of the certificate>"
|
||||
Partition = "<enterprise: partition of the certificate>"
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ Listeners = [
|
|||
Value = "<value of claim>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
override = {
|
||||
JWT = {
|
||||
|
@ -108,7 +108,7 @@ Listeners = [
|
|||
Value = "<value of claim>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -136,8 +136,8 @@ Listeners = [
|
|||
],
|
||||
"Certificates": [
|
||||
{
|
||||
"Kind": "inline-certificate",
|
||||
"Name": "<name of inline-certificate>",
|
||||
"Kind": "file-system-certificate",
|
||||
"Name": "<name of file-system-certificate>",
|
||||
"Namespace": "<enterprise: namespace of the certificate>",
|
||||
"Partition": "<enterprise: partition of the certificate>"
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ Specifies a list of cipher suites that the listener supports when negotiating co
|
|||
|
||||
### `Listeners[].TLS.Certificates[]`
|
||||
|
||||
The list of references to inline certificates that the listener uses for TLS termination.
|
||||
The list of references to file system or inline certificates that the listener uses for TLS termination.
|
||||
|
||||
#### Values
|
||||
|
||||
|
@ -362,17 +362,17 @@ The list of references to inline certificates that the listener uses for TLS ter
|
|||
|
||||
### `Listeners[].TLS.Certificates[].Kind`
|
||||
|
||||
The list of references to inline-certificates that the listener uses for TLS termination.
|
||||
The list of references to certificates that the listener uses for TLS termination.
|
||||
|
||||
#### Values
|
||||
|
||||
- Default: None
|
||||
- This field is required and must be set to `"inline-certificate"`.
|
||||
- Data type: string
|
||||
- This field is required.
|
||||
- The data type is one of the following string values: `"file-system-certificate"` or `"inline-certificate"`.
|
||||
|
||||
### `Listeners[].TLS.Certificates[].Name`
|
||||
|
||||
The list of references to inline certificates that the listener uses for TLS termination.
|
||||
Specifies the name of the file system or inline certificate that the listener uses for TLS termination.
|
||||
|
||||
#### Values
|
||||
|
||||
|
@ -400,7 +400,7 @@ Specifies the Enterprise [admin partition](/consul/docs/enterprise/admin-partiti
|
|||
|
||||
### `Listeners[].default`
|
||||
|
||||
Specifies a block of default configurations to apply to the gateway listener. All routes attached to the listener inherit the default configurations. You can specify override configurations that have precedence over default configurations in the [`override` block](#listeners-override) as well as in the `JWT` block in the [HTTP route configuration entry](/consul/docs/connect/config-entries/http-route).
|
||||
Specifies a block of default configurations to apply to the gateway listener. All routes attached to the listener inherit the default configurations. You can specify override configurations that have precedence over default configurations in the [`override` block](#listeners-override) as well as in the `JWT` block in the [HTTP route configuration entry](/consul/docs/connect/config-entries/http-route).
|
||||
|
||||
#### Values
|
||||
|
||||
|
@ -409,7 +409,7 @@ Specifies a block of default configurations to apply to the gateway listener. Al
|
|||
|
||||
### `Listeners[].default{}.JWT`
|
||||
|
||||
Specifies a block of default JWT verification configurations to apply to the gateway listener. Specify configurations that have precedence over the defaults in either the [`override.JWT` block](#listeners-override) or in the [`JWT` block](/consul/docs/connect/config-entries/http-route#rules-filters-jwt) in the HTTP route configuration. Refer to [Use JWTs to verify requests to API gateways](/consul/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms) for order of precedence and other details about using JWT verification in API gateways.
|
||||
Specifies a block of default JWT verification configurations to apply to the gateway listener. Specify configurations that have precedence over the defaults in either the [`override.JWT` block](#listeners-override) or in the [`JWT` block](/consul/docs/connect/config-entries/http-route#rules-filters-jwt) in the HTTP route configuration. Refer to [Use JWTs to verify requests to API gateways](/consul/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms) for order of precedence and other details about using JWT verification in API gateways.
|
||||
|
||||
#### Values
|
||||
|
||||
|
@ -418,7 +418,7 @@ Specifies a block of default JWT verification configurations to apply to the gat
|
|||
|
||||
### `Listeners[].default{}.JWT{}.Providers`
|
||||
|
||||
Specifies a list of default JWT provider configurations to apply to the gateway listener. A provider configuration contains the name of the provider and claims. Specify configurations that have precedence over the defaults in either the [`override.JWT.Providers` block](#listeners-override-providers) or in the [`JWT` block](/consul/docs/connect/config-entries/http-route#rules-filters-jwt-providers) of the HTTP route configuration. Refer to [Use JWTs to verify requests to API gateways](/consul/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms) for order of precedence and other details about using JWT verification in API gateways.
|
||||
Specifies a list of default JWT provider configurations to apply to the gateway listener. A provider configuration contains the name of the provider and claims. Specify configurations that have precedence over the defaults in either the [`override.JWT.Providers` block](#listeners-override-providers) or in the [`JWT` block](/consul/docs/connect/config-entries/http-route#rules-filters-jwt-providers) of the HTTP route configuration. Refer to [Use JWTs to verify requests to API gateways](/consul/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms) for order of precedence and other details about using JWT verification in API gateways.
|
||||
|
||||
#### Values
|
||||
|
||||
|
@ -432,7 +432,7 @@ The following table describes the parameters you can specify in a member of the
|
|||
| `Name` | Specifies the name of the provider. | String | None |
|
||||
| `VerifyClaims` | Specifies a list of paths and a value that define the claim that Consul verifies when it receives a request. The `VerifyClaims` map specifies the following settings: <ul><li>`Path`: Specifies a list of one or more registered or custom claims.</li><li>`Value`: Specifies the expected value of the claim.</li></ul> | Map | None |
|
||||
|
||||
Refer to [Configure JWT verification settings](#configure-jwt-verification-settings) for an example configuration.
|
||||
Refer to [Configure JWT verification settings](#configure-jwt-verification-settings) for an example configuration.
|
||||
|
||||
### `Listeners[].override`
|
||||
|
||||
|
@ -454,7 +454,7 @@ Specifies a block of JWT verification configurations to apply to the gateway lis
|
|||
|
||||
### `Listeners[].override{}.JWT{}.Providers`
|
||||
|
||||
Specifies a list of JWT provider configurations to apply to the gateway listener. A provider configuration contains the name of the provider and claims. The override settings have precedence over `Listeners[].defaults{}.JWT{}.Providers` as well as any listener-specific configuration.
|
||||
Specifies a list of JWT provider configurations to apply to the gateway listener. A provider configuration contains the name of the provider and claims. The override settings have precedence over `Listeners[].defaults{}.JWT{}.Providers` as well as any listener-specific configuration.
|
||||
|
||||
#### Values
|
||||
|
||||
|
@ -468,7 +468,7 @@ The following table describes the parameters you can specify in a member of the
|
|||
| `Name` | Specifies the name of the provider. | String | None |
|
||||
| `VerifyClaims` | Specifies a list of paths and a value that define the claim that Consul verifies when it receives a request. The `VerifyClaims` map specifies the following settings: <ul><li>`Path`: Specifies a list of one or more registered or custom claims.</li><li>`Value`: Specifies the expected value of the claim.</li></ul> | Map | None |
|
||||
|
||||
Refer to [Configure JWT verification settings](#configure-jwt-verification-settings) for an example configuration.
|
||||
Refer to [Configure JWT verification settings](#configure-jwt-verification-settings) for an example configuration.
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -530,7 +530,7 @@ Listeners = [
|
|||
{
|
||||
"name": "listener-one",
|
||||
"port": 9001,
|
||||
"protocol": "http",
|
||||
"protocol": "http",
|
||||
"override": {
|
||||
"JWT": {
|
||||
"Providers": [{
|
||||
|
@ -559,4 +559,4 @@ Listeners = [
|
|||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Tabs>
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
---
|
||||
layout: docs
|
||||
page_title: File System Certificate Configuration Reference
|
||||
description: Learn how to configure a file system certificate bound to an API Gateway on VMs.
|
||||
---
|
||||
|
||||
# File system certificate configuration reference
|
||||
|
||||
This topic provides reference information for the gateway file system certificate
|
||||
configuration entry. For information about certificate configuration for Kubernetes environments, refer to [Gateway Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/gateway).
|
||||
|
||||
## Configuration model
|
||||
|
||||
The following list outlines field hierarchy, language-specific data types, and
|
||||
requirements in a `file-system-certificate` configuration entry. Click on a property name
|
||||
to view additional details, including default values.
|
||||
|
||||
- [`Kind`](#kind): string | must be `"file-system-certificate"`
|
||||
- [`Name`](#name): string | no default
|
||||
- [`Namespace`](#namespace): string | no default <EnterpriseAlert inline />
|
||||
- [`Partition`](#partition): string | no default <EnterpriseAlert inline />
|
||||
- [`Meta`](#meta): map | no default
|
||||
- [`Certificate`](#certificate): string | no default
|
||||
- [`PrivateKey`](#privatekey): string | no default
|
||||
|
||||
## Complete configuration
|
||||
|
||||
When every field is defined, a `file-system-certificate` configuration entry has the following form:
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
```HCL
|
||||
Kind = "file-system-certificate"
|
||||
Name = "<name of certificate>"
|
||||
|
||||
Meta = {
|
||||
"<any key>" = "<any value>"
|
||||
}
|
||||
|
||||
Certificate = "<filepath to public certificate>"
|
||||
PrivateKey = "<filepath to private key>"
|
||||
```
|
||||
|
||||
```JSON
|
||||
{
|
||||
"Kind": "file-system-certificate",
|
||||
"Name": "<name of certificate>",
|
||||
"Meta": {
|
||||
"any key": "any value"
|
||||
}
|
||||
"Certificate": "<filepath to public certificate>",
|
||||
"PrivateKey": "<filepath to private key>"
|
||||
}
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Specification
|
||||
|
||||
### `Kind`
|
||||
|
||||
Specifies the type of configuration entry to implement.
|
||||
|
||||
#### Values
|
||||
|
||||
- Default: none
|
||||
- This field is required.
|
||||
- Data type: string that must equal `"file-system-certificate"`
|
||||
|
||||
### `Name`
|
||||
|
||||
Specifies a name for the configuration entry. The name is metadata that you can
|
||||
use to reference the configuration entry when performing Consul operations, such
|
||||
as applying a configuration entry to a specific cluster.
|
||||
|
||||
#### Values
|
||||
|
||||
- Default: none
|
||||
- This field is required.
|
||||
- Data type: string
|
||||
|
||||
### `Namespace` <EnterpriseAlert inline />
|
||||
|
||||
Specifies the Enterprise [namespace](/consul/docs/enterprise/namespaces) to apply to the configuration entry.
|
||||
|
||||
#### Values
|
||||
|
||||
- Default: `"default"` in Enterprise
|
||||
- Data type: string
|
||||
|
||||
### `Partition` <EnterpriseAlert inline />
|
||||
|
||||
Specifies the Enterprise [admin partition](/consul/docs/enterprise/admin-partitions) to apply to the configuration entry.
|
||||
|
||||
#### Values
|
||||
|
||||
- Default: `"default"` in Enterprise
|
||||
- Data type: string
|
||||
|
||||
### `Meta`
|
||||
|
||||
Specifies an arbitrary set of key-value pairs to associate with the gateway.
|
||||
|
||||
#### Values
|
||||
|
||||
- Default: none
|
||||
- Data type: map containing one or more keys and string values.
|
||||
|
||||
### `Certificate`
|
||||
|
||||
Specifies the filepath to a public certificate to use for TLS. This filepath must be accessible to the API gateway proxy at runtime.
|
||||
|
||||
#### Values
|
||||
|
||||
- Default: none
|
||||
- This field is required.
|
||||
- Data type: string value of the filepath to a public certificate
|
||||
|
||||
### `PrivateKey`
|
||||
|
||||
Specifies the filepath to a private key to use for TLS. This filepath must be accessible to the API gateway proxy at runtime.
|
||||
|
||||
#### Values
|
||||
|
||||
- Default: none
|
||||
- This field is required.
|
||||
- Data type: string value of the filepath to a private key
|
|
@ -7,7 +7,7 @@ description: >-
|
|||
|
||||
# Consul API gateway configuration overview
|
||||
|
||||
This topic provides an overview of the configuration items you can use to create API gateways, configure listeners, define routes, and apply additional resources that may be necessary to operate Consul API gateways in your environment.
|
||||
This topic provides an overview of the configuration items you can use to create API gateways, configure listeners, define routes, and apply additional resources that may be necessary to operate Consul API gateways in your environment.
|
||||
|
||||
## Configurations for virtual machines
|
||||
|
||||
|
@ -18,9 +18,10 @@ Apply the following configuration items if your network runs on virtual machines
|
|||
| [`api-gateway`](/consul/docs/connect/config-entries/api-gateway) | Defines the main infrastructure resource for declaring an API gateway and listeners on the gateway. | [Deploy API gateway listeners on virtual machines](/consul/docs/connect/gateways/api-gateway/deploy/listeners-vms) |
|
||||
| [`http-route`](/consul/docs/connect/config-entries/http-route) | Enables HTTP traffic to reach services in the mesh from a listener on the gateway.| <nobr>[Define routes on virtual machines](/consul/docs/connect/gateways/api-gateway/define-routes/routes-vms)</nobr> |
|
||||
| [`tcp-route`](/consul/docs/connect/config-entries/tcp-route) | Enables TCP traffic to reach services in the mesh from a listener on the gateway.| [Define routes on virtual machines](/consul/docs/connect/gateways/api-gateway/define-routes/routes-vms) |
|
||||
| <nobr>[`inline-certificate`](/consul/docs/connect/config-entries/inline-certificate)</nobr> | Provides gateway artificats with a CA certificate so that requests between the user and the gateway endpoint are encrypted. | [Encrypt API gateway traffic on virtual machines](/consul/docs/connect/gateways/api-gateway/secure-traffic/encrypt-vms) |
|
||||
| <nobr>[`file-system-certificate`](/consul/docs/connect/config-entries/file-system-certificate)</nobr> | Provides gateway with a CA certificate so that requests between the user and the gateway endpoint are encrypted. | [Encrypt API gateway traffic on virtual machines](/consul/docs/connect/gateways/api-gateway/secure-traffic/encrypt-vms) |
|
||||
| <nobr>[`inline-certificate`](/consul/docs/connect/config-entries/inline-certificate)</nobr> | Provides gateway with a CA certificate so that requests between the user and the gateway endpoint are encrypted. | [Encrypt API gateway traffic on virtual machines](/consul/docs/connect/gateways/api-gateway/secure-traffic/encrypt-vms) |
|
||||
| [`service-intentions`](/consul/docs/connect/config-entries/service-intentions) | Specifies traffic communication rules between services in the mesh. Intentions also enforce rules for service-to-service traffic routed through a Consul API gateway. | General configuration for securing a service mesh |
|
||||
|
||||
|
||||
## Configurations for Kubernetes
|
||||
|
||||
Apply the following configuration items if your network runs on Kubernetes:
|
||||
|
@ -32,7 +33,7 @@ Apply the following configuration items if your network runs on Kubernetes:
|
|||
| [`GatewayClassConfig`](/consul/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig) | Describes additional gateway-related configuration parameters for the `GatewayClass` resource. | [Deploy listeners on Kubernetes](/consul/docs/connect/gateways/api-gateway/deploy/listeners-k8s) |
|
||||
| [`Routes`](/consul/docs/connect/gateways/api-gateway/configuration/routes) | Specifies paths from the gateway listener to backend services. | <nobr>[Define routes on Kubernetes](/consul/docs/connect/gateways/api-gateway/define-routes/routes-k8s)</nobr><p>[Reroute traffic in Kubernetes](/consul/docs/connect/gateways/api-gateway/define-routes/reroute-http-requests)</p><p>[Route traffic to peered services in Kubernetes](/consul/docs/connect/gateways/api-gateway/define-routes/route-to-peered-services)</p> |
|
||||
| [`MeshServices`](/consul/docs/connect/gateways/api-gateway/configuration/meshservices) | Enables routes to reference services in Consul. | [Route traffic to peered services in Kubernetes](/consul/docs/connect/gateways/api-gateway/define-routes/route-to-peered-services) |
|
||||
| [`ServiceIntentions`](/consul/docs/connect/config-entries/service-intentions) | Specifies traffic communication rules between services in the mesh. Intentions also enforce rules for service-to-service traffic routed through a Consul API gateway. | General configuration for securing a service mesh |
|
||||
| [`ServiceIntentions`](/consul/docs/connect/config-entries/service-intentions) | Specifies traffic communication rules between services in the mesh. Intentions also enforce rules for service-to-service traffic routed through a Consul API gateway. | General configuration for securing a service mesh |
|
||||
|
||||
<!-- Reuse later for a topic about creating custom api gateway classes
|
||||
You can create a basic Gateway object using the default [`gatewayClassName`](/consul/docs/connect/gateways/api-gateway/configuration/gateway#gatewayclassname) (`consul`). If you want to create custom Gateways suitable for your environment, complete the following steps:
|
||||
|
|
|
@ -465,6 +465,10 @@
|
|||
"title": "TCP route",
|
||||
"path": "connect/config-entries/tcp-route"
|
||||
},
|
||||
{
|
||||
"title": "File system certificate",
|
||||
"path": "connect/config-entries/file-system-certificate"
|
||||
},
|
||||
{
|
||||
"title": "Inline certificate",
|
||||
"path": "connect/config-entries/inline-certificate"
|
||||
|
|
Loading…
Reference in New Issue