Merge branch 'main' of https://github.com/hashicorp/consul into fix_#20409_chkdef

pull/20411/head
Vijay Srinivas 10 months ago
commit 6bf7e3fc5c

@ -0,0 +1,3 @@
```release-note:bug
mesh: Fix bug where envoy extensions could not be configured with "permissive" mTLS mode. Note that envoy extensions currently do not apply to non-mTLS traffic in permissive mode.
```

@ -0,0 +1,3 @@
```release-note:bug
connect: Fix regression with SAN matching on terminating gateways [GH-20360](https://github.com/hashicorp/consul/issues/20360)
```

@ -0,0 +1,3 @@
```release-note:bug
docs: Consul DNS Forwarding configuration for OpenShift update for [Resolve Consul DNS Requests in Kubernetes](https://developer.hashicorp.com/consul/docs/k8s/dns)
```

@ -1,4 +1,9 @@
## 1.17.2 (January 23, 2024)
KNOWN ISSUES:
* connect: Consul versions 1.17.2 and 1.16.5 perform excessively strict TLS SAN verification on terminating gateways, which prevents connections outside of the mesh to upstream services. Terminating gateway users are advised to avoid deploying these Consul versions. A fix will be present in a future release of Consul 1.17.3 and 1.16.6. [[GH-20360](https://github.com/hashicorp/consul/issues/20360)]
SECURITY:
* Upgrade OpenShift container images to use `ubi9-minimal:9.3` as the base image. [[GH-20014](https://github.com/hashicorp/consul/issues/20014)]
@ -163,6 +168,10 @@ BUG FIXES:
## 1.16.5 (January 23, 2024)
KNOWN ISSUES:
* connect: Consul versions 1.17.2 and 1.16.5 perform excessively strict TLS SAN verification on terminating gateways, which prevents connections outside of the mesh to upstream services. Terminating gateway users are advised to avoid deploying these Consul versions. A fix will be present in a future release of Consul 1.17.3 and 1.16.6 [[GH-20360](https://github.com/hashicorp/consul/issues/20360)].
SECURITY:
* Update RSA key generation to use a key size of at least 2048 bits. [[GH-20112](https://github.com/hashicorp/consul/issues/20112)]

@ -718,6 +718,7 @@ func (a *Agent) Start(ctx context.Context) error {
Time: a.config.GRPCKeepaliveInterval,
Timeout: a.config.GRPCKeepaliveTimeout,
},
nil,
)
if a.baseDeps.UseV2Resources() {
@ -754,6 +755,11 @@ func (a *Agent) Start(ctx context.Context) error {
return fmt.Errorf("can't start agent: client agents are not supported with v2 resources")
}
// the conn is used to connect to the consul server agent
conn, err := a.baseDeps.GRPCConnPool.ClientConn(a.baseDeps.RuntimeConfig.Datacenter)
if err != nil {
return err
}
a.externalGRPCServer = external.NewServer(
a.logger.Named("grpc.external"),
metrics.Default(),
@ -763,6 +769,7 @@ func (a *Agent) Start(ctx context.Context) error {
Time: a.config.GRPCKeepaliveInterval,
Timeout: a.config.GRPCKeepaliveTimeout,
},
conn,
)
client, err := consul.NewClient(consulCfg, a.baseDeps.Deps)

@ -353,7 +353,7 @@ func newServerWithDeps(t testutil.TestingTB, c *Config, deps Deps) (*Server, err
oldNotify()
}
}
grpcServer := external.NewServer(deps.Logger.Named("grpc.external"), nil, deps.TLSConfigurator, rpcRate.NullRequestLimitsHandler(), keepalive.ServerParameters{})
grpcServer := external.NewServer(deps.Logger.Named("grpc.external"), nil, deps.TLSConfigurator, rpcRate.NullRequestLimitsHandler(), keepalive.ServerParameters{}, nil)
proxyUpdater := proxytracker.NewProxyTracker(proxytracker.ProxyTrackerConfig{})
srv, err := NewServer(c, deps, grpcServer, nil, deps.Logger, proxyUpdater)
if err != nil {

@ -23,6 +23,7 @@ flowchart TD
demo/v2/album
demo/v2/artist
hcp/v2/link
hcp/v2/telemetrystate --> hcp/v2/link
internal/v1/tombstone
mesh/v2beta1/apigateway
mesh/v2beta1/computedexplicitdestinations --> catalog/v2beta1/service
@ -52,8 +53,8 @@ flowchart TD
mesh/v2beta1/proxystatetemplate --> mesh/v2beta1/computedproxyconfiguration
mesh/v2beta1/proxystatetemplate --> mesh/v2beta1/computedroutes
mesh/v2beta1/tcproute
multicluster/v2beta1/computedexportedservices --> catalog/v2beta1/service
multicluster/v2beta1/computedexportedservices --> multicluster/v2beta1/exportedservices
multicluster/v2beta1/computedexportedservices --> multicluster/v2beta1/namespaceexportedservices
multicluster/v2beta1/computedexportedservices --> multicluster/v2beta1/partitionexportedservices
multicluster/v2/computedexportedservices --> catalog/v2beta1/service
multicluster/v2/computedexportedservices --> multicluster/v2/exportedservices
multicluster/v2/computedexportedservices --> multicluster/v2/namespaceexportedservices
multicluster/v2/computedexportedservices --> multicluster/v2/partitionexportedservices
```

@ -4,20 +4,30 @@
package external
import (
"context"
"fmt"
"strings"
"time"
"github.com/armon/go-metrics"
middleware "github.com/grpc-ecosystem/go-grpc-middleware"
recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
"github.com/hashi-derek/grpc-proxy/proxy"
"github.com/hashicorp/go-hclog"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"github.com/hashicorp/consul/agent/consul/rate"
agentmiddleware "github.com/hashicorp/consul/agent/grpc-middleware"
"github.com/hashicorp/consul/tlsutil"
)
const FORWARD_SERVICE_NAME_PREFIX = "hashicorp.consul."
var (
metricsLabels = []metrics.Label{{
Name: "server_type",
@ -28,11 +38,12 @@ var (
// NewServer constructs a gRPC server for the external gRPC port, to which
// handlers can be registered.
func NewServer(
logger agentmiddleware.Logger,
logger hclog.Logger,
metricsObj *metrics.Metrics,
tls *tlsutil.Configurator,
limiter rate.RequestLimitsHandler,
keepaliveParams keepalive.ServerParameters,
serverConn *grpc.ClientConn,
) *grpc.Server {
if metricsObj == nil {
metricsObj = metrics.Default()
@ -71,6 +82,11 @@ func NewServer(
}),
}
// forward FORWARD_SERVICE_NAME_PREFIX services from client agent to server agent
if serverConn != nil {
opts = append(opts, grpc.UnknownServiceHandler(proxy.TransparentHandler(makeDirector(serverConn, logger))))
}
if tls != nil {
// Attach TLS credentials, if provided.
tlsCreds := agentmiddleware.NewOptionalTransportCredentials(
@ -80,3 +96,24 @@ func NewServer(
}
return grpc.NewServer(opts...)
}
func makeDirector(serverConn *grpc.ClientConn, logger hclog.Logger) func(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) {
return func(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) {
var mdCopy metadata.MD
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
mdCopy = metadata.MD{}
} else {
mdCopy = md.Copy()
}
outCtx := metadata.NewOutgoingContext(ctx, mdCopy)
logger.Debug("forwarding the request to the consul server", "method", fullMethodName)
// throw unimplemented error if the method is not meant to be forwarded
if !strings.HasPrefix(fullMethodName, FORWARD_SERVICE_NAME_PREFIX) {
return outCtx, nil, status.Errorf(codes.Unimplemented, fmt.Sprintf("Unknown method %s", fullMethodName))
}
return outCtx, serverConn, nil
}
}

@ -28,7 +28,7 @@ import (
func TestServer_EmitsStats(t *testing.T) {
sink, metricsObj := testutil.NewFakeSink(t)
srv := NewServer(hclog.Default(), metricsObj, nil, rate.NullRequestLimitsHandler(), keepalive.ServerParameters{})
srv := NewServer(hclog.Default(), metricsObj, nil, rate.NullRequestLimitsHandler(), keepalive.ServerParameters{}, nil)
testservice.RegisterSimpleServer(srv, &testservice.Simple{})

@ -35,6 +35,7 @@ const metricsGatewayPath = "/v1/metrics"
type Client interface {
FetchBootstrap(ctx context.Context) (*BootstrapConfig, error)
FetchTelemetryConfig(ctx context.Context) (*TelemetryConfig, error)
GetObservabilitySecret(ctx context.Context) (clientID, clientSecret string, err error)
PushServerStatus(ctx context.Context, status *ServerStatus) error
DiscoverServers(ctx context.Context) ([]string, error)
GetCluster(ctx context.Context) (*Cluster, error)
@ -369,3 +370,22 @@ func decodeError(err error) error {
return err
}
func (c *hcpClient) GetObservabilitySecret(ctx context.Context) (string, string, error) {
params := hcpgnm.NewGetObservabilitySecretParamsWithContext(ctx).
WithID(c.resource.ID).
WithLocationOrganizationID(c.resource.Organization).
WithLocationProjectID(c.resource.Project)
resp, err := c.gnm.GetObservabilitySecret(params, nil)
if err != nil {
return "", "", err
}
if len(resp.GetPayload().Keys) == 0 {
return "", "", fmt.Errorf("no observability keys returned for cluster")
}
key := resp.GetPayload().Keys[len(resp.GetPayload().Keys)-1]
return key.ClientID, key.ClientSecret, nil
}

@ -1,4 +1,4 @@
// Code generated by mockery v2.37.1. DO NOT EDIT.
// Code generated by mockery v2.39.2. DO NOT EDIT.
package client
@ -25,6 +25,10 @@ func (_m *MockClient) EXPECT() *MockClient_Expecter {
func (_m *MockClient) DiscoverServers(ctx context.Context) ([]string, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for DiscoverServers")
}
var r0 []string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) ([]string, error)); ok {
@ -79,6 +83,10 @@ func (_c *MockClient_DiscoverServers_Call) RunAndReturn(run func(context.Context
func (_m *MockClient) FetchBootstrap(ctx context.Context) (*BootstrapConfig, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for FetchBootstrap")
}
var r0 *BootstrapConfig
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (*BootstrapConfig, error)); ok {
@ -133,6 +141,10 @@ func (_c *MockClient_FetchBootstrap_Call) RunAndReturn(run func(context.Context)
func (_m *MockClient) FetchTelemetryConfig(ctx context.Context) (*TelemetryConfig, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for FetchTelemetryConfig")
}
var r0 *TelemetryConfig
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (*TelemetryConfig, error)); ok {
@ -187,6 +199,10 @@ func (_c *MockClient_FetchTelemetryConfig_Call) RunAndReturn(run func(context.Co
func (_m *MockClient) GetCluster(ctx context.Context) (*Cluster, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetCluster")
}
var r0 *Cluster
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (*Cluster, error)); ok {
@ -237,10 +253,77 @@ func (_c *MockClient_GetCluster_Call) RunAndReturn(run func(context.Context) (*C
return _c
}
// GetObservabilitySecret provides a mock function with given fields: ctx
func (_m *MockClient) GetObservabilitySecret(ctx context.Context) (string, string, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetObservabilitySecret")
}
var r0 string
var r1 string
var r2 error
if rf, ok := ret.Get(0).(func(context.Context) (string, string, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) string); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(context.Context) string); ok {
r1 = rf(ctx)
} else {
r1 = ret.Get(1).(string)
}
if rf, ok := ret.Get(2).(func(context.Context) error); ok {
r2 = rf(ctx)
} else {
r2 = ret.Error(2)
}
return r0, r1, r2
}
// MockClient_GetObservabilitySecret_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetObservabilitySecret'
type MockClient_GetObservabilitySecret_Call struct {
*mock.Call
}
// GetObservabilitySecret is a helper method to define mock.On call
// - ctx context.Context
func (_e *MockClient_Expecter) GetObservabilitySecret(ctx interface{}) *MockClient_GetObservabilitySecret_Call {
return &MockClient_GetObservabilitySecret_Call{Call: _e.mock.On("GetObservabilitySecret", ctx)}
}
func (_c *MockClient_GetObservabilitySecret_Call) Run(run func(ctx context.Context)) *MockClient_GetObservabilitySecret_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context))
})
return _c
}
func (_c *MockClient_GetObservabilitySecret_Call) Return(clientID string, clientSecret string, err error) *MockClient_GetObservabilitySecret_Call {
_c.Call.Return(clientID, clientSecret, err)
return _c
}
func (_c *MockClient_GetObservabilitySecret_Call) RunAndReturn(run func(context.Context) (string, string, error)) *MockClient_GetObservabilitySecret_Call {
_c.Call.Return(run)
return _c
}
// PushServerStatus provides a mock function with given fields: ctx, status
func (_m *MockClient) PushServerStatus(ctx context.Context, status *ServerStatus) error {
ret := _m.Called(ctx, status)
if len(ret) == 0 {
panic("no return value specified for PushServerStatus")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *ServerStatus) error); ok {
r0 = rf(ctx, status)

@ -1835,7 +1835,7 @@ func newTestServer(t *testing.T, cb func(conf *consul.Config)) testingServer {
conf.ACLResolverSettings.EnterpriseMeta = *conf.AgentEnterpriseMeta()
deps := newDefaultDeps(t, conf)
externalGRPCServer := external.NewServer(deps.Logger, nil, deps.TLSConfigurator, rate.NullRequestLimitsHandler(), keepalive.ServerParameters{})
externalGRPCServer := external.NewServer(deps.Logger, nil, deps.TLSConfigurator, rate.NullRequestLimitsHandler(), keepalive.ServerParameters{}, nil)
server, err := consul.NewServer(conf, deps, externalGRPCServer, nil, deps.Logger, nil)
require.NoError(t, err)

@ -481,7 +481,7 @@ func makeMTLSTransportSocket(cfgSnap *proxycfg.ConfigSnapshot, uid proxycfg.Upst
cfgSnap.RootPEMs(),
makeTLSParametersFromProxyTLSConfig(cfgSnap.MeshConfigTLSOutgoing()),
)
err := injectSANMatcher(commonTLSContext, spiffeID.URI().String())
err := injectSANMatcher(commonTLSContext, false, spiffeID.URI().String())
if err != nil {
return nil, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", sni, err)
}
@ -875,7 +875,7 @@ func (s *ResourceGenerator) injectGatewayServiceAddons(cfgSnap *proxycfg.ConfigS
}
if mapping.SNI != "" {
tlsContext.Sni = mapping.SNI
if err := injectSANMatcher(tlsContext.CommonTlsContext, mapping.SNI); err != nil {
if err := injectSANMatcher(tlsContext.CommonTlsContext, true, mapping.SNI); err != nil {
return fmt.Errorf("failed to inject SNI matcher into TLS context: %v", err)
}
}
@ -904,7 +904,7 @@ func (s *ResourceGenerator) injectGatewayDestinationAddons(cfgSnap *proxycfg.Con
}
if mapping.SNI != "" {
tlsContext.Sni = mapping.SNI
if err := injectSANMatcher(tlsContext.CommonTlsContext, mapping.SNI); err != nil {
if err := injectSANMatcher(tlsContext.CommonTlsContext, true, mapping.SNI); err != nil {
return fmt.Errorf("failed to inject SNI matcher into TLS context: %v", err)
}
}
@ -1226,7 +1226,7 @@ func (s *ResourceGenerator) makeUpstreamClusterForPeerService(
rootPEMs,
makeTLSParametersFromProxyTLSConfig(cfgSnap.MeshConfigTLSOutgoing()),
)
err = injectSANMatcher(commonTLSContext, peerMeta.SpiffeID...)
err = injectSANMatcher(commonTLSContext, false, peerMeta.SpiffeID...)
if err != nil {
return nil, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", clusterName, err)
}
@ -1329,7 +1329,7 @@ func (s *ResourceGenerator) makeUpstreamClusterForPreparedQuery(upstream structs
cfgSnap.RootPEMs(),
makeTLSParametersFromProxyTLSConfig(cfgSnap.MeshConfigTLSOutgoing()),
)
err = injectSANMatcher(commonTLSContext, spiffeIDs...)
err = injectSANMatcher(commonTLSContext, false, spiffeIDs...)
if err != nil {
return nil, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", sni, err)
}
@ -1609,7 +1609,7 @@ func (s *ResourceGenerator) makeExportedUpstreamClustersForMeshGateway(cfgSnap *
}
// injectSANMatcher updates a TLS context so that it verifies the upstream SAN.
func injectSANMatcher(tlsContext *envoy_tls_v3.CommonTlsContext, matchStrings ...string) error {
func injectSANMatcher(tlsContext *envoy_tls_v3.CommonTlsContext, terminatingEgress bool, matchStrings ...string) error {
if tlsContext == nil {
return fmt.Errorf("invalid type: expected CommonTlsContext_ValidationContext not to be nil")
}
@ -1620,16 +1620,37 @@ func injectSANMatcher(tlsContext *envoy_tls_v3.CommonTlsContext, matchStrings ..
tlsContext.ValidationContextType)
}
// All mesh services should match by URI
types := []envoy_tls_v3.SubjectAltNameMatcher_SanType{
envoy_tls_v3.SubjectAltNameMatcher_URI,
}
if terminatingEgress {
// Terminating gateways will need to match on many fields depending on user configuration,
// since they make egress calls outside of the cluster. Having more than one matcher behaves
// like an OR operation, where any match is sufficient to pass the certificate validation.
// To maintain backwards compatibility with the old untyped `match_subject_alt_names` behavior,
// we should match on all 4 enum types.
// https://github.com/hashicorp/consul/issues/20360
// https://github.com/envoyproxy/envoy/pull/18628/files#diff-cf088136dc052ddf1762fb3c96c0e8de472f3031f288e7e300558e6e72c8e129R69-R75
types = []envoy_tls_v3.SubjectAltNameMatcher_SanType{
envoy_tls_v3.SubjectAltNameMatcher_URI,
envoy_tls_v3.SubjectAltNameMatcher_DNS,
envoy_tls_v3.SubjectAltNameMatcher_EMAIL,
envoy_tls_v3.SubjectAltNameMatcher_IP_ADDRESS,
}
}
var matchers []*envoy_tls_v3.SubjectAltNameMatcher
for _, m := range matchStrings {
matchers = append(matchers, &envoy_tls_v3.SubjectAltNameMatcher{
SanType: envoy_tls_v3.SubjectAltNameMatcher_URI,
Matcher: &envoy_matcher_v3.StringMatcher{
MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{
Exact: m,
for _, t := range types {
matchers = append(matchers, &envoy_tls_v3.SubjectAltNameMatcher{
SanType: t,
Matcher: &envoy_matcher_v3.StringMatcher{
MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{
Exact: m,
},
},
},
})
})
}
}
validationCtx.ValidationContext.MatchTypedSubjectAltNames = matchers

@ -766,6 +766,23 @@ end`,
}, nil)
},
},
{
name: "tproxy-and-permissive-mtls-and-envoy-extension",
create: func(t testinf.T) *proxycfg.ConfigSnapshot {
return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) {
ns.Proxy.Config = map[string]any{"protocol": "http"}
ns.Proxy.MutualTLSMode = structs.MutualTLSModePermissive
ns.Proxy.Mode = structs.ProxyModeTransparent
ns.Proxy.TransparentProxy.OutboundListenerPort = 1234
// Arbitrarily chose ext-authz since it's available in CE
ns.Proxy.EnvoyExtensions = makeExtAuthzEnvoyExtension(
"https",
"dest=local",
)
},
nil)
},
},
}
latestEnvoyVersion := xdscommon.EnvoyVersions[0]

@ -132,7 +132,7 @@ func (s *ResourceGenerator) mapDiscoChainTargets(cfgSnap *proxycfg.ConfigSnapsho
makeTLSParametersFromProxyTLSConfig(cfgSnap.MeshConfigTLSOutgoing()),
)
err := injectSANMatcher(commonTLSContext, spiffeIDs...)
err := injectSANMatcher(commonTLSContext, false, spiffeIDs...)
if err != nil {
return failoverTargets, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", sni, err)
}

@ -10,9 +10,8 @@ import (
"testing"
"time"
"github.com/hashicorp/consul/agent/xds/proxystateconverter"
"github.com/hashicorp/consul/agent/xdsv2"
"github.com/hashicorp/consul/proto/private/pbpeering"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
@ -20,19 +19,19 @@ import (
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/consul/agent/connect"
"github.com/hashicorp/consul/agent/consul/discoverychain"
"github.com/hashicorp/consul/agent/xds/testcommon"
"github.com/hashicorp/consul/envoyextensions/xdscommon"
"github.com/hashicorp/consul/types"
testinf "github.com/mitchellh/go-testing-interface"
"github.com/stretchr/testify/require"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds/proxystateconverter"
"github.com/hashicorp/consul/agent/xds/response"
"github.com/hashicorp/consul/agent/xds/testcommon"
"github.com/hashicorp/consul/agent/xdsv2"
"github.com/hashicorp/consul/envoyextensions/xdscommon"
"github.com/hashicorp/consul/proto/private/pbpeering"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/types"
)
var testTypeUrlToPrettyName = map[string]string{

@ -0,0 +1,175 @@
{
"nonce": "00000001",
"resources": [
{
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"circuitBreakers": {},
"commonLbConfig": {
"healthyPanicThreshold": {}
},
"connectTimeout": "5s",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
"resourceApiVersion": "V3"
}
},
"name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"outlierDetection": {},
"transportSocket": {
"name": "tls",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
"commonTlsContext": {
"tlsCertificates": [
{
"certificateChain": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
},
"privateKey": {
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
}
}
],
"tlsParams": {},
"validationContext": {
"matchTypedSubjectAltNames": [
{
"matcher": {
"exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db"
},
"sanType": "URI"
}
],
"trustedCa": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
}
}
},
"sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul"
}
},
"type": "EDS"
},
{
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"circuitBreakers": {},
"connectTimeout": "5s",
"edsClusterConfig": {
"edsConfig": {
"ads": {},
"resourceApiVersion": "V3"
}
},
"name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
"outlierDetection": {},
"transportSocket": {
"name": "tls",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
"commonTlsContext": {
"tlsCertificates": [
{
"certificateChain": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
},
"privateKey": {
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
}
}
],
"tlsParams": {},
"validationContext": {
"matchTypedSubjectAltNames": [
{
"matcher": {
"exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target"
},
"sanType": "URI"
},
{
"matcher": {
"exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target"
},
"sanType": "URI"
}
],
"trustedCa": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
}
}
},
"sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul"
}
},
"type": "EDS"
},
{
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"connectTimeout": "5s",
"loadAssignment": {
"clusterName": "local_app",
"endpoints": [
{
"lbEndpoints": [
{
"endpoint": {
"address": {
"socketAddress": {
"address": "127.0.0.1",
"portValue": 8080
}
}
}
}
]
}
]
},
"name": "local_app",
"type": "STATIC"
},
{
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"loadAssignment": {
"clusterName": "local_ext_authz",
"endpoints": [
{
"lbEndpoints": [
{
"endpoint": {
"address": {
"socketAddress": {
"address": "127.0.0.1",
"portValue": 9191
}
}
}
}
]
}
]
},
"name": "local_ext_authz",
"type": "STATIC",
"typedExtensionProtocolOptions": {
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": {
"@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions",
"explicitHttpConfig": {
"http2ProtocolOptions": {}
}
}
}
},
{
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"connectTimeout": "5s",
"lbPolicy": "CLUSTER_PROVIDED",
"name": "original-destination",
"type": "ORIGINAL_DST"
}
],
"typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
"versionInfo": "00000001"
}

@ -0,0 +1,75 @@
{
"nonce": "00000001",
"resources": [
{
"@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
"clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"endpoints": [
{
"lbEndpoints": [
{
"endpoint": {
"address": {
"socketAddress": {
"address": "10.10.1.1",
"portValue": 8080
}
}
},
"healthStatus": "HEALTHY",
"loadBalancingWeight": 1
},
{
"endpoint": {
"address": {
"socketAddress": {
"address": "10.10.1.2",
"portValue": 8080
}
}
},
"healthStatus": "HEALTHY",
"loadBalancingWeight": 1
}
]
}
]
},
{
"@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
"clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
"endpoints": [
{
"lbEndpoints": [
{
"endpoint": {
"address": {
"socketAddress": {
"address": "10.10.1.1",
"portValue": 8080
}
}
},
"healthStatus": "HEALTHY",
"loadBalancingWeight": 1
},
{
"endpoint": {
"address": {
"socketAddress": {
"address": "10.20.1.2",
"portValue": 8080
}
}
},
"healthStatus": "HEALTHY",
"loadBalancingWeight": 1
}
]
}
]
}
],
"typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment",
"versionInfo": "00000001"
}

@ -0,0 +1,305 @@
{
"nonce": "00000001",
"resources": [
{
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
"address": {
"socketAddress": {
"address": "127.0.0.1",
"portValue": 9191
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.filters.network.tcp_proxy",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
"cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"statPrefix": "upstream.db.default.default.dc1"
}
}
]
}
],
"name": "db:127.0.0.1:9191",
"trafficDirection": "OUTBOUND"
},
{
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
"address": {
"socketAddress": {
"address": "127.0.0.1",
"portValue": 1234
}
},
"defaultFilterChain": {
"filters": [
{
"name": "envoy.filters.network.tcp_proxy",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
"cluster": "original-destination",
"statPrefix": "upstream.original-destination"
}
}
]
},
"listenerFilters": [
{
"name": "envoy.filters.listener.original_dst",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst"
}
}
],
"name": "outbound_listener:127.0.0.1:1234",
"trafficDirection": "OUTBOUND"
},
{
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
"address": {
"socketAddress": {
"address": "127.10.10.10",
"portValue": 8181
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.filters.network.tcp_proxy",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
"cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul",
"statPrefix": "upstream.prepared_query_geo-cache"
}
}
]
}
],
"name": "prepared_query:geo-cache:127.10.10.10:8181",
"trafficDirection": "OUTBOUND"
},
{
"@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
"address": {
"socketAddress": {
"address": "0.0.0.0",
"portValue": 9999
}
},
"filterChains": [
{
"filters": [
{
"name": "envoy.filters.network.http_connection_manager",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
"forwardClientCertDetails": "APPEND_FORWARD",
"httpFilters": [
{
"name": "envoy.filters.http.rbac",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC",
"rules": {}
}
},
{
"name": "envoy.filters.http.header_to_metadata",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config",
"requestRules": [
{
"header": "x-forwarded-client-cert",
"onHeaderPresent": {
"key": "trust-domain",
"metadataNamespace": "consul",
"regexValueRewrite": {
"pattern": {
"regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*"
},
"substitution": "\\1"
}
}
},
{
"header": "x-forwarded-client-cert",
"onHeaderPresent": {
"key": "partition",
"metadataNamespace": "consul",
"regexValueRewrite": {
"pattern": {
"regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*"
},
"substitution": "\\2"
}
}
},
{
"header": "x-forwarded-client-cert",
"onHeaderPresent": {
"key": "namespace",
"metadataNamespace": "consul",
"regexValueRewrite": {
"pattern": {
"regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*"
},
"substitution": "\\3"
}
}
},
{
"header": "x-forwarded-client-cert",
"onHeaderPresent": {
"key": "datacenter",
"metadataNamespace": "consul",
"regexValueRewrite": {
"pattern": {
"regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*"
},
"substitution": "\\4"
}
}
},
{
"header": "x-forwarded-client-cert",
"onHeaderPresent": {
"key": "service",
"metadataNamespace": "consul",
"regexValueRewrite": {
"pattern": {
"regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*"
},
"substitution": "\\5"
}
}
}
]
}
},
{
"name": "envoy.filters.http.ext_authz",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz",
"failureModeAllow": true,
"grpcService": {
"envoyGrpc": {
"clusterName": "local_ext_authz"
}
},
"metadataContextNamespaces": [
"consul"
],
"statPrefix": "response",
"transportApiVersion": "V3"
}
},
{
"name": "envoy.filters.http.router",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
}
}
],
"routeConfig": {
"name": "public_listener",
"virtualHosts": [
{
"domains": [
"*"
],
"name": "public_listener",
"routes": [
{
"match": {
"prefix": "/"
},
"route": {
"cluster": "local_app"
}
}
]
}
]
},
"setCurrentClientCertDetails": {
"cert": true,
"chain": true,
"dns": true,
"subject": true,
"uri": true
},
"statPrefix": "public_listener",
"tracing": {
"randomSampling": {}
},
"upgradeConfigs": [
{
"upgradeType": "websocket"
}
]
}
}
],
"transportSocket": {
"name": "tls",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext",
"commonTlsContext": {
"alpnProtocols": [
"http/1.1"
],
"tlsCertificates": [
{
"certificateChain": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n"
},
"privateKey": {
"inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n"
}
}
],
"tlsParams": {},
"validationContext": {
"trustedCa": {
"inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n"
}
}
},
"requireClientCertificate": true
}
}
},
{
"filterChainMatch": {
"destinationPort": 8080
},
"filters": [
{
"name": "envoy.filters.network.tcp_proxy",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
"cluster": "local_app",
"statPrefix": "permissive_public_listener"
}
}
]
}
],
"listenerFilters": [
{
"name": "envoy.filters.listener.original_dst",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst"
}
}
],
"name": "public_listener:0.0.0.0:9999",
"trafficDirection": "INBOUND"
}
],
"typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener",
"versionInfo": "00000001"
}

@ -0,0 +1,5 @@
{
"nonce": "00000001",
"typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
"versionInfo": "00000001"
}

@ -52,6 +52,24 @@
"exact": "bar.com"
},
"sanType": "URI"
},
{
"matcher": {
"exact": "bar.com"
},
"sanType": "DNS"
},
{
"matcher": {
"exact": "bar.com"
},
"sanType": "EMAIL"
},
{
"matcher": {
"exact": "bar.com"
},
"sanType": "IP_ADDRESS"
}
],
"trustedCa": {
@ -148,6 +166,24 @@
"exact": "foo.com"
},
"sanType": "URI"
},
{
"matcher": {
"exact": "foo.com"
},
"sanType": "DNS"
},
{
"matcher": {
"exact": "foo.com"
},
"sanType": "EMAIL"
},
{
"matcher": {
"exact": "foo.com"
},
"sanType": "IP_ADDRESS"
}
],
"trustedCa": {

@ -172,6 +172,24 @@
"exact": "api.test.com"
},
"sanType": "URI"
},
{
"matcher": {
"exact": "api.test.com"
},
"sanType": "DNS"
},
{
"matcher": {
"exact": "api.test.com"
},
"sanType": "EMAIL"
},
{
"matcher": {
"exact": "api.test.com"
},
"sanType": "IP_ADDRESS"
}
],
"trustedCa": {

@ -4,4 +4,4 @@
"@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC",
"rules": {}
}
}
}

@ -38,7 +38,7 @@ import (
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/xds/response"
"github.com/hashicorp/consul/envoyextensions/xdscommon"
"github.com/hashicorp/consul/internal/mesh/proxy-snapshot"
proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/sdk/testutil"
)
@ -295,7 +295,7 @@ func xdsNewTransportSocket(
},
}
if len(spiffeID) > 0 {
require.NoError(t, injectSANMatcher(commonTLSContext, spiffeID...))
require.NoError(t, injectSANMatcher(commonTLSContext, false, spiffeID...))
}
var tlsContext proto.Message

@ -491,3 +491,7 @@ client.Write(ctx, &pbresource.WriteRequest{
},
})
```
## Testing
Now that you have created your controller its time to test it. The types of tests each controller should have and boiler plat for test files is documented [here](./testing.md)

@ -0,0 +1,221 @@
# Controller Testing
For every controller we want to enable 3 types of testing.
1. Unit Tests - These should live alongside the controller and utilize mocks and the controller.TestController. Where possible split out controller functionality so that other functions can be independently tested.
2. Lightweight integration tests - These should live in an internal/<api group>/<api group>test package. These tests utilize the in-memory resource service and the standard controller manager. There are two types of tests that should be created.
* Lifecycle Integration Tests - These go step by step to modify resources and check what the controller did. They are meant to go through the lifecycle of resources and how they are reconciled. Verifications are typically intermingled with resource updates.
* One-Shot Integration Tests - These tests publish a bunch of resources and then perform all the verifications. These mainly are focused on the controller eventually converging given all the resources thrown at it and aren't as concerned with any intermediate states resources go through.
3. Container based integration tests - These tests live along with our other container based integration tests. They utilize a full multi-node cluster (and sometimes client agents). There are 3 types of tests that can be created here:
* Lifecycle Integration Tests - These are the same as for the lighweight integration tests.
* One-shot IntegrationTests - These are the same as for the lightweight integration tests.
* Upgrade Tests - These are a special form of One-shot Integration tests where the cluster is brought up with some original version, data is pushed in, an upgrade is done and then we verify the consistency of the data post-upgrade.
Between the lightweight and container based integration tests there is a lot of duplication in what is being tested. For this reason these integration test bodies should be defined as exported functions within the apigroups test package. The container based tests can then import those packages and invoke the same functionality with minimal overhead.
See the [internal/catalog/catalogtest](internal/catalog/catalogtest) package for an example.
For one-shot integration tests, functions to do the resource publishing should be split from functions to perform the verifications. This allows upgrade tests to publish the resources once pre-upgrade and then validate that their correctness post-upgrade without requiring rewriting them.
Sometimes it may also be a good idea to export functions in the test packages for running a specific controllers integration tests. This is a good idea when the controller will use a different version of a dependency in Consul Enterprise to allow for the enterprise implementations package to invoke the integration tests after setting up the controller with its injected dependency.
## Unit Test Template
These tests live alongside controller source.
```go
package foo
import (
"testing"
"github.com/stretchr/testif/mock"
"github.com/stretchr/testif/require"
"github.com/stretchr/testif/suite"
)
func TestReconcile(t *testing.T) {
rtest.RunWithTenancies(func(tenancy *pbresource.Tenancy) {
suite.Run(t, &reconcileSuite{tenancy: tenancy})
})
}
type reconcileSuite struct {
suite.Suite
tenancy *pbresource.Tenancy
ctx context.Context
ctl *controller.TestController
client *rtest.Client
// Mock objects needed for testing
}
func (suite *reconcileSuite) SetupTest() {
suite.ctx = testutil.TestContext(suite.T())
// Alternatively it is sometimes useful to use a mock resource service. For that
// you can use github.com/hashicorp/consul/grpcmocks.NewResourceServiceClient
// to create the client.
client := svctest.NewResourceServiceBuilder().
// register this API groups types. Also register any other
// types this controller depends on.
WithRegisterFns(types.Register).
WithTenancies(suite.tenancy).
Run(suite.T())
// Build any mock objects or other dependencies of the controller here.
// Build the TestController
suite.ctl = controller.NewTestController(Controller(), client)
suite.client = rtest.NewClient(suite.ctl.Runtime().Client)
}
// Implement tests on the suite as needed.
func (suite *reconcileSuite) TestSomething() {
// Setup Mock expectations
// Push resources into the resource service as needed.
// Issue the Reconcile call
suite.ctl.Reconcile(suite.ctx, controller.Request{})
}
```
## Integration Testing Templates
These tests should live in internal/<api group>/<api group>test. For these examples, assume the API group under test is named `foo` and the latest API group version is v2.
### `run_test.go`
This file is how `go test` knows to execute the tests. These integration tests should
be executed against an in-memory resource service with the standard controller manager.
```go
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package footest
import (
"testing"
"github.com/hashicorp/consul/internal/foo"
"github.com/hashicorp/consul/internal/controller/controllertest"
"github.com/hashicorp/consul/internal/resource/reaper"
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
"github.com/hashicorp/consul/proto-public/pbresource"
)
var (
// This makes the CLI options available to control timing delays of requests. The
// randomized timings helps to build confidence that regardless of resources writes
// occurring in quick succession, the controller under test will eventually converge
// on its steady state.
clientOpts = rtest.ConfigureTestCLIFlags()
)
func runInMemResourceServiceAndControllers(t *testing.T) pbresource.ResourceServiceClient {
t.Helper()
return controllertest.NewControllerTestBuilder().
// Register your types for the API group and any others that these tests will depend on
WithResourceRegisterFns(types.Register).
WithControllerRegisterFns(
reaper.RegisterControllers,
foo.RegisterControllers,
).Run(t)
}
// The basic integration test should operate mostly in a one-shot manner where resources
// are published and then verifications are performed.
func TestControllers_Integration(t *testing.T) {
client := runInMemResourceServiceAndControllers(t)
RunFooV2IntegrationTest(t, client, clientOpts.ClientOptions(t)...)
}
// The lifecycle integration test is typically more complex and deals with changing
// some values over time to cause the controllers to do something differently.
func TestControllers_Lifecycle(t *testing.T) {
client := runInMemResourceServiceAndControllers(t)
RunFooV2LifecycleTest(t, client, clientOpts.ClientOptions(t)...)
}
```
### `test_integration_v2.go`
```go
package footest
import (
"embed"
"fmt"
"testing"
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
"github.com/hashicorp/consul/proto-public/pbresource"
)
var (
//go:embed integration_test_data
testData embed.FS
)
// Execute the full integration test
func RunFooV2IntegrationTest(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) {
t.Helper
PublishFooV2IntegrationTestData(t, client, opts...)
VerifyFooV2IntegrationTestResults(t, client)
}
// PublishFooV2IntegrationTestData publishes all the data that needs to exist in the resource service
// for the controllers to converge on the desired state.
func PublishFooV2IntegrationTestData(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) {
t.Helper()
c := rtest.NewClient(client, opts...)
// Publishing resources manually is an option but alternatively you can store the resources on disk
// and use go:embed declarations to embed the whole test data filesystem into the test binary.
resources := rtest.ParseResourcesFromFilesystem(t, testData, "integration_test_data/v2")
c.PublishResources(t, resources)
}
func VerifyFooV2IntegrationTestResults(t *testing.T, client pbresource.ResourceServiceClient) {
t.Helper()
c := rtest.NewClient(client)
// Perform verifications here. All verifications should be retryable except in very exceptional circumstances.
// This could be in a retry.Run block or could be retryed by using one of the WaitFor* methods on the rtest.Client.
// Having them be retryable will prevent flakes especially when the verifications are run in the context of
// a multi-server cluster where a raft follower hasn't yet observed some change.
}
```
### `test_lifecycle_v2.go`
```go
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package footest
import (
"testing"
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
"github.com/hashicorp/consul/proto-public/pbresource"
)
func RunFooV2LifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) {
t.Helper()
// execute tests.
}
```

@ -296,6 +296,27 @@ func (b *BasicEnvoyExtender) patchSupportedListenerFilterChains(config *RuntimeC
func (b *BasicEnvoyExtender) patchListenerFilterChains(config *RuntimeConfig, l *envoy_listener_v3.Listener, nameOrSNI string) (*envoy_listener_v3.Listener, error) {
var resultErr error
// Special case for Permissive mTLS, which adds a filter chain
// containing a TCP Proxy only. We don't care about errors
// applying filters as long as the main filter chain is
// patched successfully.
if IsInboundPublicListener(l) && len(l.FilterChains) > 1 {
var isPatched bool
for idx, filterChain := range l.FilterChains {
patchedFilterChain, err := b.patchFilterChain(config, filterChain, l)
if err != nil {
resultErr = multierror.Append(resultErr, fmt.Errorf("error patching listener filter chain %q: %w", nameOrSNI, err))
continue
}
l.FilterChains[idx] = patchedFilterChain
isPatched = true
}
if isPatched {
return l, nil
}
return l, resultErr
}
for idx, filterChain := range l.FilterChains {
if patchedFilterChain, err := b.patchFilterChain(config, filterChain, l); err == nil {
l.FilterChains[idx] = patchedFilterChain

@ -37,6 +37,7 @@ require (
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1
github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/hashi-derek/grpc-proxy v0.0.0-20231207191910-191266484d75
github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706
github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69
github.com/hashicorp/consul/api v1.26.1

@ -443,6 +443,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/hashi-derek/grpc-proxy v0.0.0-20231207191910-191266484d75 h1:V5Uqf7VoWMd6UhNf/5EMA8LMPUm95GYvk2YF5SzT24o=
github.com/hashi-derek/grpc-proxy v0.0.0-20231207191910-191266484d75/go.mod h1:5eEnHfK72jOkp4gC1dI/Q/E9MFNOM/ewE/vql5ijV3g=
github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 h1:1ZEjnveDe20yFa6lSkfdQZm5BR/b271n0MsB5R2L3us=
github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706/go.mod h1:1Cs8FlmD1BfSQXJGcFLSV5FuIx1AbJP+EJGdxosoS2g=
github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 h1:wzWurXrxfSyG1PHskIZlfuXlTSCj1Tsyatp9DtaasuY=
@ -1070,6 +1072,7 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@ -1170,6 +1173,7 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -1365,6 +1369,7 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
@ -1482,6 +1487,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ=
k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU=

@ -10,7 +10,7 @@ import (
"github.com/hashicorp/consul/internal/auth/internal/types"
"github.com/hashicorp/consul/internal/resource"
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -9,7 +9,7 @@ import (
"github.com/hashicorp/consul/internal/auth/internal/types"
"github.com/hashicorp/consul/internal/controller"
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
)
type XTrafficPermissions interface {

@ -8,7 +8,7 @@ import (
"github.com/hashicorp/consul/internal/auth/internal/types"
"github.com/hashicorp/consul/internal/controller"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
)
// SamenessGroupExpander is used to expand sameness group for a ComputedTrafficPermission resource

@ -17,7 +17,7 @@ import (
"github.com/hashicorp/consul/internal/controller/dependency"
"github.com/hashicorp/consul/internal/resource"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -12,7 +12,7 @@ import (
"github.com/hashicorp/consul/internal/resource"
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/stretchr/testify/require"

@ -5,6 +5,7 @@ package link
import (
"context"
"crypto/tls"
"strings"
gnmmod "github.com/hashicorp/hcp-sdk-go/clients/cloud-global-network-manager-service/preview/2022-02-15/models"
@ -149,11 +150,7 @@ func (r *linkReconciler) Reconcile(ctx context.Context, rt controller.Runtime, r
// 1. The HCP configuration (i.e., how to connect to HCP) is preserved
// 2. The Consul agent's node ID and node name are preserved
existingCfg := r.hcpManager.GetCloudConfig()
newCfg := config.CloudConfig{
ResourceID: link.ResourceId,
ClientID: link.ClientId,
ClientSecret: link.ClientSecret,
}
newCfg := CloudConfigFromLink(&link)
cfg := config.Merge(existingCfg, newCfg)
hcpClient, err := r.hcpClientFn(cfg)
if err != nil {
@ -274,3 +271,22 @@ func (i *linkInitializer) Initialize(ctx context.Context, rt controller.Runtime)
return nil
}
func CloudConfigFromLink(link *pbhcp.Link) config.CloudConfig {
var cfg config.CloudConfig
if link == nil {
return cfg
}
cfg = config.CloudConfig{
ResourceID: link.GetResourceId(),
ClientID: link.GetClientId(),
ClientSecret: link.GetClientSecret(),
}
if link.GetHcpConfig() != nil {
cfg.AuthURL = link.GetHcpConfig().GetAuthUrl()
cfg.ScadaAddress = link.GetHcpConfig().GetScadaAddress()
cfg.Hostname = link.GetHcpConfig().GetApiAddress()
cfg.TLSConfig = &tls.Config{InsecureSkipVerify: link.GetHcpConfig().GetTlsInsecureSkipVerify()}
}
return cfg
}

@ -11,6 +11,7 @@ import (
"github.com/hashicorp/consul/agent/hcp/client"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/resource"
pbhcp "github.com/hashicorp/consul/proto-public/pbhcp/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)
@ -102,3 +103,21 @@ func linkingFailed(ctx context.Context, rt controller.Runtime, res *pbresource.R
return nil
}
func IsLinked(res *pbresource.Resource) (linked bool, reason string) {
if !resource.EqualType(res.GetId().GetType(), pbhcp.LinkType) {
return false, "resource is not hcp.Link type"
}
linkStatus, ok := res.GetStatus()[StatusKey]
if !ok {
return false, "link status not set"
}
for _, cond := range linkStatus.GetConditions() {
if cond.Type == StatusLinked && cond.GetState() == pbresource.Condition_STATE_TRUE {
return true, ""
}
}
return false, "link status does not include positive linked condition"
}

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/consul/agent/hcp/config"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/hcp/internal/controllers/link"
"github.com/hashicorp/consul/internal/hcp/internal/controllers/telemetrystate"
)
type Dependencies struct {
@ -27,4 +28,6 @@ func Register(mgr *controller.Manager, deps Dependencies) {
deps.DataDir,
deps.HCPManager,
))
mgr.Register(telemetrystate.TelemetryStateController(link.DefaultHCPClientFn))
}

@ -0,0 +1,168 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package telemetrystate
import (
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/anypb"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/controller/dependency"
"github.com/hashicorp/consul/internal/hcp/internal/controllers/link"
"github.com/hashicorp/consul/internal/hcp/internal/types"
"github.com/hashicorp/consul/internal/resource"
pbhcp "github.com/hashicorp/consul/proto-public/pbhcp/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)
var (
globalID = &pbresource.ID{
Name: "global",
Type: pbhcp.TelemetryStateType,
Tenancy: &pbresource.Tenancy{},
}
)
const MetaKeyDebugSkipDeletion = StatusKey + "/debug/skip-deletion"
func TelemetryStateController(hcpClientFn link.HCPClientFn) *controller.Controller {
return controller.NewController(StatusKey, pbhcp.TelemetryStateType).
WithWatch(pbhcp.LinkType, dependency.ReplaceType(pbhcp.TelemetryStateType)).
WithReconciler(&telemetryStateReconciler{
hcpClientFn: hcpClientFn,
})
}
type telemetryStateReconciler struct {
hcpClientFn link.HCPClientFn
}
func (r *telemetryStateReconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error {
// The runtime is passed by value so replacing it here for the remainder of this
// reconciliation request processing will not affect future invocations.
rt.Logger = rt.Logger.With("resource-id", req.ID, "controller", StatusKey)
rt.Logger.Trace("reconciling telemetry-state")
// First get the link resource in order to build a hcp client. If the link resource
// doesn't exist then the telemetry-state should not exist either.
res, err := getLinkResource(ctx, rt)
if err != nil {
rt.Logger.Error("failed to lookup Link resource", "error", err)
return err
}
if res == nil {
return ensureTelemetryStateDeleted(ctx, rt)
}
// Check that the link resource indicates the cluster is linked
// If the cluster is not linked, the telemetry-state resource should not exist
if linked, reason := link.IsLinked(res.GetResource()); !linked {
rt.Logger.Trace("cluster is not linked", "reason", reason)
return ensureTelemetryStateDeleted(ctx, rt)
}
hcpClient, err := r.hcpClientFn(link.CloudConfigFromLink(res.GetData()))
if err != nil {
rt.Logger.Error("error creating HCP Client", "error", err)
return err
}
// Get the telemetry configuration and observability scoped credentials from hcp
tCfg, err := hcpClient.FetchTelemetryConfig(ctx)
if err != nil {
rt.Logger.Error("error requesting telemetry config", "error", err)
return err
}
clientID, clientSecret, err := hcpClient.GetObservabilitySecret(ctx)
if err != nil {
rt.Logger.Error("error requesting telemetry credentials", "error", err)
return nil
}
// TODO allow hcp client config override from hcp TelemetryConfig
hcpCfg := res.GetData().GetHcpConfig()
// TODO implement proxy options from hcp
proxyCfg := &pbhcp.ProxyConfig{}
state := &pbhcp.TelemetryState{
ResourceId: res.GetData().ResourceId,
ClientId: clientID,
ClientSecret: clientSecret,
HcpConfig: hcpCfg,
Proxy: proxyCfg,
Metrics: &pbhcp.MetricsConfig{
Labels: tCfg.MetricsConfig.Labels,
Disabled: tCfg.MetricsConfig.Disabled,
},
}
if tCfg.MetricsConfig.Endpoint != nil {
state.Metrics.Endpoint = tCfg.MetricsConfig.Endpoint.String()
}
if tCfg.MetricsConfig.Filters != nil {
state.Metrics.IncludeList = []string{tCfg.MetricsConfig.Filters.String()}
}
stateData, err := anypb.New(state)
if err != nil {
rt.Logger.Error("error marshalling telemetry-state data", "error", err)
return err
}
_, err = rt.Client.Write(ctx, &pbresource.WriteRequest{Resource: &pbresource.Resource{
Id: &pbresource.ID{
Name: "global",
Type: pbhcp.TelemetryStateType,
},
Data: stateData,
}})
if err != nil {
rt.Logger.Error("error updating telemetry-state", "error", err)
return err
}
return nil
}
func ensureTelemetryStateDeleted(ctx context.Context, rt controller.Runtime) error {
resp, err := rt.Client.Read(ctx, &pbresource.ReadRequest{Id: &pbresource.ID{Name: "global", Type: pbhcp.TelemetryStateType}})
switch {
case status.Code(err) == codes.NotFound:
return nil
case err != nil:
rt.Logger.Error("the resource service has returned an unexpected error", "error", err)
return err
}
rt.Logger.Trace("deleting telemetry-state")
if _, ok := resp.GetResource().Metadata[MetaKeyDebugSkipDeletion]; ok {
rt.Logger.Debug("skip-deletion metadata key found, skipping deletion of telemetry-state resource")
return nil
}
if _, err := rt.Client.Delete(ctx, &pbresource.DeleteRequest{Id: resp.GetResource().GetId()}); err != nil {
rt.Logger.Error("error deleting telemetry-state resource", "error", err)
return err
}
return nil
}
// getLinkResource returns the cluster scoped pbhcp.Link resource. If the resource is not found a nil
// pointer and no error will be returned.
func getLinkResource(ctx context.Context, rt controller.Runtime) (*types.DecodedLink, error) {
resp, err := rt.Client.Read(ctx, &pbresource.ReadRequest{Id: &pbresource.ID{Name: "global", Type: pbhcp.LinkType}})
switch {
case status.Code(err) == codes.NotFound:
return nil, nil
case err != nil:
return nil, err
}
return resource.Decode[*pbhcp.Link](resp.GetResource())
}

@ -0,0 +1,140 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package telemetrystate
import (
"context"
"net/url"
"regexp"
"testing"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
hcpclient "github.com/hashicorp/consul/agent/hcp/client"
"github.com/hashicorp/consul/agent/hcp/config"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/hcp/internal/controllers/link"
"github.com/hashicorp/consul/internal/hcp/internal/types"
"github.com/hashicorp/consul/internal/resource"
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
pbhcp "github.com/hashicorp/consul/proto-public/pbhcp/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/sdk/testutil"
)
type controllerSuite struct {
suite.Suite
ctx context.Context
client *rtest.Client
rt controller.Runtime
ctl telemetryStateReconciler
tenancies []*pbresource.Tenancy
}
func mockHcpClientFn(t *testing.T) (*hcpclient.MockClient, link.HCPClientFn) {
mockClient := hcpclient.NewMockClient(t)
mockClientFunc := func(link config.CloudConfig) (hcpclient.Client, error) {
return mockClient, nil
}
return mockClient, mockClientFunc
}
func (suite *controllerSuite) SetupTest() {
suite.ctx = testutil.TestContext(suite.T())
suite.tenancies = rtest.TestTenancies()
client := svctest.NewResourceServiceBuilder().
WithRegisterFns(types.Register).
WithTenancies(suite.tenancies...).
Run(suite.T())
suite.rt = controller.Runtime{
Client: client,
Logger: testutil.Logger(suite.T()),
}
suite.client = rtest.NewClient(client)
}
func TestTelemetryStateController(t *testing.T) {
suite.Run(t, new(controllerSuite))
}
func (suite *controllerSuite) deleteResourceFunc(id *pbresource.ID) func() {
return func() {
suite.client.MustDelete(suite.T(), id)
}
}
func (suite *controllerSuite) TestController_Ok() {
// Run the controller manager
mgr := controller.NewManager(suite.client, suite.rt.Logger)
mockClient, mockClientFn := mockHcpClientFn(suite.T())
mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(&hcpclient.TelemetryConfig{
MetricsConfig: &hcpclient.MetricsConfig{
Endpoint: &url.URL{
Scheme: "http",
Host: "localhost",
Path: "/test",
},
Labels: map[string]string{"foo": "bar"},
Filters: regexp.MustCompile(".*"),
},
RefreshConfig: &hcpclient.RefreshConfig{},
}, nil)
mockClient.EXPECT().GetObservabilitySecret(mock.Anything).Return("xxx", "yyy", nil)
mgr.Register(TelemetryStateController(mockClientFn))
mgr.SetRaftLeader(true)
go mgr.Run(suite.ctx)
linkData := &pbhcp.Link{
ClientId: "abc",
ClientSecret: "abc",
ResourceId: types.GenerateTestResourceID(suite.T()),
}
link := rtest.Resource(pbhcp.LinkType, "global").
WithData(suite.T(), linkData).
WithStatus(link.StatusKey, &pbresource.Status{Conditions: []*pbresource.Condition{link.ConditionLinked(linkData.ResourceId)}}).
Write(suite.T(), suite.client)
suite.T().Cleanup(suite.deleteResourceFunc(link.Id))
tsRes := suite.client.WaitForResourceExists(suite.T(), &pbresource.ID{Name: "global", Type: pbhcp.TelemetryStateType})
decodedState, err := resource.Decode[*pbhcp.TelemetryState](tsRes)
require.NoError(suite.T(), err)
require.Equal(suite.T(), linkData.ResourceId, decodedState.GetData().ResourceId)
require.Equal(suite.T(), "xxx", decodedState.GetData().ClientId)
require.Equal(suite.T(), "http://localhost/test", decodedState.GetData().Metrics.Endpoint)
suite.client.MustDelete(suite.T(), link.Id)
suite.client.WaitForDeletion(suite.T(), tsRes.Id)
}
func (suite *controllerSuite) TestController_LinkingDisabled() {
// Run the controller manager
mgr := controller.NewManager(suite.client, suite.rt.Logger)
_, mockClientFn := mockHcpClientFn(suite.T())
mgr.Register(TelemetryStateController(mockClientFn))
mgr.SetRaftLeader(true)
go mgr.Run(suite.ctx)
linkData := &pbhcp.Link{
ClientId: "abc",
ClientSecret: "abc",
ResourceId: types.GenerateTestResourceID(suite.T()),
}
rtest.Resource(pbhcp.LinkType, "global").
WithData(suite.T(), linkData).
WithStatus(link.StatusKey, &pbresource.Status{Conditions: []*pbresource.Condition{link.ConditionDisabled}}).
Write(suite.T(), suite.client)
suite.client.WaitForDeletion(suite.T(), &pbresource.ID{Name: "global", Type: pbhcp.TelemetryStateType})
}

@ -0,0 +1,8 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package telemetrystate
const (
StatusKey = "consul.io/hcp/telemetry-state"
)

@ -6,12 +6,13 @@ package types
import (
"errors"
"github.com/hashicorp/go-multierror"
hcpresource "github.com/hashicorp/hcp-sdk-go/resource"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/internal/resource"
pbhcp "github.com/hashicorp/consul/proto-public/pbhcp/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/go-multierror"
hcpresource "github.com/hashicorp/hcp-sdk-go/resource"
)
type DecodedLink = resource.DecodedResource[*pbhcp.Link]

@ -0,0 +1,85 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package types
import (
"errors"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/consul/internal/resource"
pbhcp "github.com/hashicorp/consul/proto-public/pbhcp/v2"
)
type DecodedTelemetryState = resource.DecodedResource[*pbhcp.TelemetryState]
var (
telemetryStateConfigurationNameError = errors.New("only a single Telemetry resource is allowed and it must be named global")
)
func RegisterTelemetryState(r resource.Registry) {
r.Register(resource.Registration{
Type: pbhcp.TelemetryStateType,
Proto: &pbhcp.TelemetryState{},
Scope: resource.ScopeCluster,
Validate: ValidateTelemetryState,
})
}
var ValidateTelemetryState = resource.DecodeAndValidate(validateTelemetryState)
func validateTelemetryState(res *DecodedTelemetryState) error {
var err error
if res.GetId().GetName() != "global" {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "name",
Wrapped: telemetryStateConfigurationNameError,
})
}
if res.GetData().GetClientId() == "" {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "client_id",
Wrapped: resource.ErrMissing,
})
}
if res.GetData().GetClientSecret() == "" {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "client_secret",
Wrapped: resource.ErrMissing,
})
}
if res.GetData().GetResourceId() == "" {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "resource_id",
Wrapped: resource.ErrMissing,
})
}
if res.GetData().GetMetrics().GetEndpoint() == "" {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "metrics.endpoint",
Wrapped: resource.ErrMissing,
})
}
if res.GetData().GetMetrics().GetIncludeList() == nil {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "metrics.include_list",
Wrapped: resource.ErrMissing,
})
}
if res.GetData().GetMetrics().GetLabels() == nil {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "metrics.labels",
Wrapped: resource.ErrMissing,
})
}
return err
}

@ -7,4 +7,5 @@ import "github.com/hashicorp/consul/internal/resource"
func Register(r resource.Registry) {
RegisterLink(r)
RegisterTelemetryState(r)
}

@ -12,19 +12,21 @@ import (
"google.golang.org/protobuf/types/known/durationpb"
"github.com/hashicorp/consul/agent/connect"
"github.com/hashicorp/consul/envoyextensions/xdscommon"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/gatewayproxy/fetcher"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/meshgateways"
"github.com/hashicorp/consul/internal/mesh/internal/types"
"github.com/hashicorp/consul/internal/resource"
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
meshv2beta1 "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
"github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)
const nullRouteClusterName = "null_route_cluster"
const (
nullRouteClusterName = "null_route_cluster"
)
type proxyStateTemplateBuilder struct {
workload *types.DecodedWorkload
@ -33,9 +35,10 @@ type proxyStateTemplateBuilder struct {
exportedServices []*pbmulticluster.ComputedExportedService
logger hclog.Logger
trustDomain string
remoteGatewayIDs []*pbresource.ID
}
func NewProxyStateTemplateBuilder(workload *types.DecodedWorkload, exportedServices []*pbmulticluster.ComputedExportedService, logger hclog.Logger, dataFetcher *fetcher.Fetcher, dc, trustDomain string) *proxyStateTemplateBuilder {
func NewProxyStateTemplateBuilder(workload *types.DecodedWorkload, exportedServices []*pbmulticluster.ComputedExportedService, logger hclog.Logger, dataFetcher *fetcher.Fetcher, dc, trustDomain string, remoteGatewayIDs []*pbresource.ID) *proxyStateTemplateBuilder {
return &proxyStateTemplateBuilder{
workload: workload,
dataFetcher: dataFetcher,
@ -43,6 +46,7 @@ func NewProxyStateTemplateBuilder(workload *types.DecodedWorkload, exportedServi
exportedServices: exportedServices,
logger: logger,
trustDomain: trustDomain,
remoteGatewayIDs: remoteGatewayIDs,
}
}
@ -67,8 +71,15 @@ func (b *proxyStateTemplateBuilder) listeners() []*pbproxystate.Listener {
// if the address defines no ports we assume the intention is to bind to all
// ports on the workload
if len(address.Ports) == 0 {
for _, workloadPort := range b.workload.Data.Ports {
listeners = append(listeners, b.buildListener(address, workloadPort.Port))
for portName, workloadPort := range b.workload.Data.Ports {
switch portName {
case meshgateways.LANPortName:
listeners = append(listeners, b.meshListener(address, workloadPort.Port))
case meshgateways.WANPortName:
listeners = append(listeners, b.wanListener(address, workloadPort.Port))
default:
b.logger.Warn("encountered unexpected port on mesh gateway workload", "port", portName)
}
}
return listeners
}
@ -80,16 +91,38 @@ func (b *proxyStateTemplateBuilder) listeners() []*pbproxystate.Listener {
continue
}
listeners = append(listeners, b.buildListener(address, workloadPort.Port))
switch portName {
case meshgateways.LANPortName:
listeners = append(listeners, b.meshListener(address, workloadPort.Port))
case meshgateways.WANPortName:
listeners = append(listeners, b.wanListener(address, workloadPort.Port))
default:
b.logger.Warn("encountered unexpected port on mesh gateway workload", "port", portName)
}
}
return listeners
}
func (b *proxyStateTemplateBuilder) buildListener(address *pbcatalog.WorkloadAddress, port uint32) *pbproxystate.Listener {
// meshListener constructs a pbproxystate.Listener that receives outgoing
// traffic from the local partition where the mesh gateway mode is "local". This
// traffic will be sent to a mesh gateway in a remote partition.
func (b *proxyStateTemplateBuilder) meshListener(address *pbcatalog.WorkloadAddress, port uint32) *pbproxystate.Listener {
return b.listener("mesh_listener", address, port, pbproxystate.Direction_DIRECTION_OUTBOUND, b.meshRouters())
}
// wanListener constructs a pbproxystate.Listener that receives incoming
// traffic from the public internet, either from a mesh gateway in a remote partition
// where the mesh gateway mode is "local" or from a service in a remote partition
// where the mesh gateway mode is "remote".
func (b *proxyStateTemplateBuilder) wanListener(address *pbcatalog.WorkloadAddress, port uint32) *pbproxystate.Listener {
return b.listener("wan_listener", address, port, pbproxystate.Direction_DIRECTION_INBOUND, b.wanRouters())
}
func (b *proxyStateTemplateBuilder) listener(name string, address *pbcatalog.WorkloadAddress, port uint32, direction pbproxystate.Direction, routers []*pbproxystate.Router) *pbproxystate.Listener {
return &pbproxystate.Listener{
Name: xdscommon.PublicListenerName,
Direction: pbproxystate.Direction_DIRECTION_INBOUND,
Name: name,
Direction: direction,
BindAddress: &pbproxystate.Listener_HostPort{
HostPort: &pbproxystate.HostPortAddress{
Host: address.Host,
@ -111,14 +144,55 @@ func (b *proxyStateTemplateBuilder) buildListener(address *pbcatalog.WorkloadAdd
},
},
},
Routers: b.routers(),
Routers: routers,
}
}
// routers loops through the ports and consumers for each exported service and generates
// a pbproxystate.Router matching the SNI to the target cluster. The target port name
// will be included in the ALPN. The targeted cluster will marry this port name with the SNI.
func (b *proxyStateTemplateBuilder) routers() []*pbproxystate.Router {
// meshRouters loops through the list of mesh gateways in other partitions and generates
// a pbproxystate.Router matching the partition + datacenter of the SNI to the target
// cluster. Traffic flowing through this router originates in the local partition where
// the mesh gateway mode is "local".
func (b *proxyStateTemplateBuilder) meshRouters() []*pbproxystate.Router {
var routers []*pbproxystate.Router
for _, remoteGatewayID := range b.remoteGatewayIDs {
serviceID := resource.ReplaceType(pbcatalog.ServiceType, remoteGatewayID)
service, err := b.dataFetcher.FetchService(context.Background(), serviceID)
if err != nil {
b.logger.Trace("error reading exported service", "error", err)
continue
} else if service == nil {
b.logger.Trace("service does not exist, skipping router", "service", serviceID)
continue
}
routers = append(routers, &pbproxystate.Router{
Match: &pbproxystate.Match{
ServerNames: []string{
fmt.Sprintf("*.%s", b.clusterNameForRemoteGateway(remoteGatewayID)),
},
},
Destination: &pbproxystate.Router_L4{
L4: &pbproxystate.L4Destination{
Destination: &pbproxystate.L4Destination_Cluster{
Cluster: &pbproxystate.DestinationCluster{
Name: b.clusterNameForRemoteGateway(remoteGatewayID),
},
},
StatPrefix: "prefix",
},
},
})
}
return routers
}
// wanRouters loops through the ports and consumers for each exported service and generates
// a pbproxystate.Router matching the SNI to the target cluster. Traffic flowing through this
// router originates from a mesh gateway in a remote partition where the mesh gateway mode is
// "local" or from a service in a remote partition where the mesh gateway mode is "remote".
func (b *proxyStateTemplateBuilder) wanRouters() []*pbproxystate.Router {
var routers []*pbproxystate.Router
for _, exportedService := range b.exportedServices {
@ -133,17 +207,21 @@ func (b *proxyStateTemplateBuilder) routers() []*pbproxystate.Router {
}
for _, port := range service.Data.Ports {
if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH {
continue
}
for _, consumer := range exportedService.Consumers {
routers = append(routers, &pbproxystate.Router{
Match: &pbproxystate.Match{
AlpnProtocols: []string{alpnProtocol(port.TargetPort)},
ServerNames: []string{b.sni(exportedService.TargetRef, consumer)},
ServerNames: []string{b.sniForExportedService(exportedService.TargetRef, consumer)},
},
Destination: &pbproxystate.Router_L4{
L4: &pbproxystate.L4Destination{
Destination: &pbproxystate.L4Destination_Cluster{
Cluster: &pbproxystate.DestinationCluster{
Name: b.clusterName(exportedService.TargetRef, consumer, port.TargetPort),
Name: b.clusterNameForExportedService(exportedService.TargetRef, consumer, port.TargetPort),
},
},
StatPrefix: "prefix",
@ -160,6 +238,7 @@ func (b *proxyStateTemplateBuilder) routers() []*pbproxystate.Router {
func (b *proxyStateTemplateBuilder) clusters() map[string]*pbproxystate.Cluster {
clusters := map[string]*pbproxystate.Cluster{}
// Clusters handling incoming traffic from a remote partition
for _, exportedService := range b.exportedServices {
serviceID := resource.IDFromReference(exportedService.TargetRef)
service, err := b.dataFetcher.FetchService(context.Background(), serviceID)
@ -172,8 +251,12 @@ func (b *proxyStateTemplateBuilder) clusters() map[string]*pbproxystate.Cluster
}
for _, port := range service.Data.Ports {
if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH {
continue
}
for _, consumer := range exportedService.Consumers {
clusterName := b.clusterName(exportedService.TargetRef, consumer, port.TargetPort)
clusterName := b.clusterNameForExportedService(exportedService.TargetRef, consumer, port.TargetPort)
clusters[clusterName] = &pbproxystate.Cluster{
Name: clusterName,
Protocol: pbproxystate.Protocol_PROTOCOL_TCP, // TODO
@ -188,6 +271,31 @@ func (b *proxyStateTemplateBuilder) clusters() map[string]*pbproxystate.Cluster
}
}
// Clusters handling outgoing traffic from the local partition
for _, remoteGatewayID := range b.remoteGatewayIDs {
serviceID := resource.ReplaceType(pbcatalog.ServiceType, remoteGatewayID)
service, err := b.dataFetcher.FetchService(context.Background(), serviceID)
if err != nil {
b.logger.Trace("error reading exported service", "error", err)
continue
} else if service == nil {
b.logger.Trace("service does not exist, skipping router", "service", serviceID)
continue
}
clusterName := b.clusterNameForRemoteGateway(remoteGatewayID)
clusters[clusterName] = &pbproxystate.Cluster{
Name: clusterName,
Protocol: pbproxystate.Protocol_PROTOCOL_TCP, // TODO
Group: &pbproxystate.Cluster_EndpointGroup{
EndpointGroup: &pbproxystate.EndpointGroup{
Group: &pbproxystate.EndpointGroup_Dynamic{},
},
},
AltStatName: "prefix",
}
}
// Add null route cluster for any unmatched traffic
clusters[nullRouteClusterName] = &pbproxystate.Cluster{
Name: nullRouteClusterName,
@ -232,6 +340,7 @@ func (b *proxyStateTemplateBuilder) Build() *meshv2beta1.ProxyStateTemplate {
func (b *proxyStateTemplateBuilder) requiredEndpoints() map[string]*pbproxystate.EndpointRef {
requiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
// Endpoints for clusters handling incoming traffic from another partition
for _, exportedService := range b.exportedServices {
serviceID := resource.IDFromReference(exportedService.TargetRef)
service, err := b.dataFetcher.FetchService(context.Background(), serviceID)
@ -244,38 +353,74 @@ func (b *proxyStateTemplateBuilder) requiredEndpoints() map[string]*pbproxystate
}
for _, port := range service.Data.Ports {
if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH {
continue
}
for _, consumer := range exportedService.Consumers {
clusterName := b.clusterName(exportedService.TargetRef, consumer, port.TargetPort)
clusterName := b.clusterNameForExportedService(exportedService.TargetRef, consumer, port.TargetPort)
requiredEndpoints[clusterName] = &pbproxystate.EndpointRef{
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, serviceID),
// In the case of a mesh gateway, the route port and mesh port are the same, since you are always
// routing to same port that you add in the endpoint. This is different from a sidecar proxy, where
// the receiving proxy listens on the mesh port and forwards to a different workload port.
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, serviceID),
RoutePort: port.TargetPort,
MeshPort: port.TargetPort,
MeshPort: "mesh",
}
}
}
}
// Endpoints for clusters handling outgoing traffic from the local partition
for _, remoteGatewayID := range b.remoteGatewayIDs {
serviceID := resource.ReplaceType(pbcatalog.ServiceType, remoteGatewayID)
service, err := b.dataFetcher.FetchService(context.Background(), serviceID)
if err != nil {
b.logger.Trace("error reading exported service", "error", err)
continue
} else if service == nil {
b.logger.Trace("service does not exist, skipping router", "service", serviceID)
continue
}
clusterName := b.clusterNameForRemoteGateway(remoteGatewayID)
// In the case of a mesh gateway, the route port and mesh port are the same, since you are always
// routing to same port that you add in the endpoint. This is different from a sidecar proxy, where
// the receiving proxy listens on the mesh port and forwards to a different workload port.
requiredEndpoints[clusterName] = &pbproxystate.EndpointRef{
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, serviceID),
MeshPort: meshgateways.WANPortName,
RoutePort: meshgateways.WANPortName,
}
}
return requiredEndpoints
}
func (b *proxyStateTemplateBuilder) clusterName(serviceRef *pbresource.Reference, consumer *pbmulticluster.ComputedExportedServiceConsumer, port string) string {
return fmt.Sprintf("%s.%s", port, b.sni(serviceRef, consumer))
// clusterNameForExportedService generates a cluster name for a given service
// that is being exported from the local partition to a remote partition. This
// partition may reside in the same datacenter or in a remote datacenter.
func (b *proxyStateTemplateBuilder) clusterNameForExportedService(serviceRef *pbresource.Reference, consumer *pbmulticluster.ComputedExportedServiceConsumer, port string) string {
return fmt.Sprintf("%s.%s", port, b.sniForExportedService(serviceRef, consumer))
}
func (b *proxyStateTemplateBuilder) sni(serviceRef *pbresource.Reference, consumer *pbmulticluster.ComputedExportedServiceConsumer) string {
switch tConsumer := consumer.Tenancy.(type) {
func (b *proxyStateTemplateBuilder) sniForExportedService(serviceRef *pbresource.Reference, consumer *pbmulticluster.ComputedExportedServiceConsumer) string {
switch consumer.Tenancy.(type) {
case *pbmulticluster.ComputedExportedServiceConsumer_Partition:
return connect.ServiceSNI(serviceRef.Name, "", serviceRef.Tenancy.Namespace, tConsumer.Partition, b.dc, b.trustDomain)
return connect.ServiceSNI(serviceRef.Name, "", serviceRef.Tenancy.Namespace, serviceRef.Tenancy.Partition, b.dc, b.trustDomain)
case *pbmulticluster.ComputedExportedServiceConsumer_Peer:
return connect.PeeredServiceSNI(serviceRef.Name, serviceRef.Tenancy.Namespace, serviceRef.Tenancy.Partition, tConsumer.Peer, b.trustDomain)
return connect.PeeredServiceSNI(serviceRef.Name, serviceRef.Tenancy.Namespace, serviceRef.Tenancy.Partition, b.dc, b.trustDomain)
default:
return ""
}
}
// clusterNameForRemoteGateway generates a cluster name for a given remote mesh
// gateway. This will be used to route traffic from the local partition to the mesh
// gateway for a remote partition.
func (b *proxyStateTemplateBuilder) clusterNameForRemoteGateway(remoteGatewayID *pbresource.ID) string {
return connect.GatewaySNI(b.dc, remoteGatewayID.Tenancy.Partition, b.trustDomain)
}
func alpnProtocol(portName string) string {
return fmt.Sprintf("consul~%s", portName)
}

@ -15,7 +15,6 @@ import (
"github.com/hashicorp/consul/agent/connect"
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
"github.com/hashicorp/consul/envoyextensions/xdscommon"
"github.com/hashicorp/consul/internal/catalog"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/gatewayproxy/fetcher"
@ -28,7 +27,7 @@ import (
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
"github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/version/versiontest"
@ -200,7 +199,7 @@ func (suite *proxyStateTemplateBuilderSuite) TestProxyStateTemplateBuilder_Build
"without address ports": suite.workloadWithOutAddressPorts,
} {
testutil.RunStep(suite.T(), name, func(t *testing.T) {
builder := NewProxyStateTemplateBuilder(workload, suite.exportedServicesPeerData.Data.Services, logger, f, dc, trustDomain)
builder := NewProxyStateTemplateBuilder(workload, suite.exportedServicesPeerData.Data.Services, logger, f, dc, trustDomain, nil)
expectedProxyStateTemplate := &pbmesh.ProxyStateTemplate{
ProxyState: &pbmesh.ProxyState{
Identity: &pbresource.Reference{
@ -210,7 +209,7 @@ func (suite *proxyStateTemplateBuilderSuite) TestProxyStateTemplateBuilder_Build
},
Listeners: []*pbproxystate.Listener{
{
Name: xdscommon.PublicListenerName,
Name: "wan_listener",
Direction: pbproxystate.Direction_DIRECTION_INBOUND,
BindAddress: &pbproxystate.Listener_HostPort{
HostPort: &pbproxystate.HostPortAddress{
@ -237,29 +236,13 @@ func (suite *proxyStateTemplateBuilderSuite) TestProxyStateTemplateBuilder_Build
{
Match: &pbproxystate.Match{
AlpnProtocols: []string{"consul~tcp"},
ServerNames: []string{connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")},
ServerNames: []string{connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, dc, "trustDomain")},
},
Destination: &pbproxystate.Router_L4{
L4: &pbproxystate.L4Destination{
Destination: &pbproxystate.L4Destination_Cluster{
Cluster: &pbproxystate.DestinationCluster{
Name: fmt.Sprintf("tcp.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")),
},
},
StatPrefix: "prefix",
},
},
},
{
Match: &pbproxystate.Match{
AlpnProtocols: []string{"consul~mesh"},
ServerNames: []string{connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")},
},
Destination: &pbproxystate.Router_L4{
L4: &pbproxystate.L4Destination{
Destination: &pbproxystate.L4Destination_Cluster{
Cluster: &pbproxystate.DestinationCluster{
Name: fmt.Sprintf("mesh.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")),
Name: fmt.Sprintf("tcp.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, dc, "trustDomain")),
},
},
StatPrefix: "prefix",
@ -285,18 +268,8 @@ func (suite *proxyStateTemplateBuilderSuite) TestProxyStateTemplateBuilder_Build
},
Protocol: pbproxystate.Protocol_PROTOCOL_TCP,
},
fmt.Sprintf("mesh.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")): {
Name: fmt.Sprintf("mesh.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")),
Group: &pbproxystate.Cluster_EndpointGroup{
EndpointGroup: &pbproxystate.EndpointGroup{
Group: &pbproxystate.EndpointGroup_Dynamic{},
},
},
AltStatName: "prefix",
Protocol: pbproxystate.Protocol_PROTOCOL_TCP, // TODO
},
fmt.Sprintf("tcp.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")): {
Name: fmt.Sprintf("tcp.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")),
fmt.Sprintf("tcp.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, dc, "trustDomain")): {
Name: fmt.Sprintf("tcp.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, dc, "trustDomain")),
Group: &pbproxystate.Cluster_EndpointGroup{
EndpointGroup: &pbproxystate.EndpointGroup{
Group: &pbproxystate.EndpointGroup_Dynamic{},
@ -308,23 +281,14 @@ func (suite *proxyStateTemplateBuilderSuite) TestProxyStateTemplateBuilder_Build
},
},
RequiredEndpoints: map[string]*pbproxystate.EndpointRef{
fmt.Sprintf("mesh.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")): {
Id: &pbresource.ID{
Name: "api-1",
Type: pbcatalog.ServiceEndpointsType,
Tenancy: tenancy,
},
RoutePort: "mesh",
MeshPort: "mesh",
},
fmt.Sprintf("tcp.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, "api-1", "trustDomain")): {
fmt.Sprintf("tcp.%s", connect.PeeredServiceSNI("api-1", tenancy.Namespace, tenancy.Partition, dc, "trustDomain")): {
Id: &pbresource.ID{
Name: "api-1",
Type: pbcatalog.ServiceEndpointsType,
Tenancy: tenancy,
},
RoutePort: "tcp",
MeshPort: "tcp",
MeshPort: "mesh",
},
},
RequiredLeafCertificates: make(map[string]*pbproxystate.LeafCertificateRef),

@ -18,7 +18,7 @@ import (
"github.com/hashicorp/consul/internal/resource"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)
@ -79,27 +79,6 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
return nil
}
// TODO NET-7014 Determine what gateway controls this workload
// For now, we cheat by knowing the MeshGateway's name, type + tenancy ahead of time
gatewayID := &pbresource.ID{
Name: "mesh-gateway",
Type: pbmesh.MeshGatewayType,
Tenancy: resource.DefaultPartitionedTenancy(),
}
// Check if the gateway exists.
gateway, err := dataFetcher.FetchMeshGateway(ctx, gatewayID)
if err != nil {
rt.Logger.Error("error reading the associated gateway", "error", err)
return err
}
if gateway == nil {
// If gateway has been deleted, then return as ProxyStateTemplate should be
// cleaned up by the garbage collector because of the owner reference.
rt.Logger.Trace("gateway doesn't exist; skipping reconciliation", "gateway", gatewayID)
return nil
}
proxyStateTemplate, err := dataFetcher.FetchProxyStateTemplate(ctx, req.ID)
if err != nil {
rt.Logger.Error("error reading proxy state template", "error", err)
@ -119,6 +98,7 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
Type: pbmulticluster.ComputedExportedServicesType,
}
// This covers any incoming requests from outside my partition to services inside my partition
var exportedServices []*pbmulticluster.ComputedExportedService
dec, err := dataFetcher.FetchComputedExportedServices(ctx, exportedServicesID)
if err != nil {
@ -129,13 +109,27 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
exportedServices = dec.Data.Services
}
// This covers any incoming requests from inside my partition to services outside my partition
meshGateways, err := dataFetcher.FetchMeshGateways(ctx)
if err != nil {
rt.Logger.Warn("error reading the associated mesh gateways", "error", err)
}
var remoteGatewayIDs []*pbresource.ID
for _, meshGateway := range meshGateways {
// If this is the mesh gateway in my local partition + datacenter, skip
if meshGateway.Id.Tenancy.Partition != req.ID.Tenancy.Partition {
remoteGatewayIDs = append(remoteGatewayIDs, meshGateway.Id)
}
}
trustDomain, err := r.getTrustDomain()
if err != nil {
rt.Logger.Error("error fetching trust domain to compute proxy state template", "error", err)
return err
}
newPST := builder.NewProxyStateTemplateBuilder(workload, exportedServices, rt.Logger, dataFetcher, r.dc, trustDomain).Build()
newPST := builder.NewProxyStateTemplateBuilder(workload, exportedServices, rt.Logger, dataFetcher, r.dc, trustDomain, remoteGatewayIDs).Build()
proxyTemplateData, err := anypb.New(newPST)
if err != nil {

@ -7,12 +7,13 @@ import (
"context"
"fmt"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
"github.com/hashicorp/consul/internal/mesh/internal/types"
"github.com/hashicorp/consul/internal/resource"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"google.golang.org/protobuf/proto"
)
@ -44,6 +45,22 @@ func (f *Fetcher) FetchMeshGateway(ctx context.Context, id *pbresource.ID) (*typ
return dec, nil
}
// FetchMeshGateways fetches all MeshGateway resources known to the local server.
func (f *Fetcher) FetchMeshGateways(ctx context.Context) ([]*types.DecodedMeshGateway, error) {
tenancy := resource.DefaultClusteredTenancy()
tenancy.Partition = acl.WildcardPartitionName
dec, err := resource.ListDecodedResource[*pbmesh.MeshGateway](ctx, f.client, &pbresource.ListRequest{
Type: pbmesh.MeshGatewayType,
Tenancy: tenancy,
})
if err != nil {
return nil, err
}
return dec, nil
}
// FetchProxyStateTemplate fetches a service resource from the resource service.
// This will panic if the type field in the ID argument is not a ProxyStateTemplate type.
func (f *Fetcher) FetchProxyStateTemplate(ctx context.Context, id *pbresource.ID) (*types.DecodedProxyStateTemplate, error) {

@ -21,7 +21,7 @@ import (
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/sdk/testutil"
)
@ -69,9 +69,14 @@ func (suite *dataFetcherSuite) setupWithTenancy(tenancy *pbresource.Tenancy) {
).
Write(suite.T(), suite.client)
suite.meshGateway = resourcetest.Resource(pbmesh.MeshGatewayType, "mesh-gateway-1").
suite.meshGateway = resourcetest.Resource(pbmesh.MeshGatewayType, "mesh-gateway").
WithData(suite.T(), &pbmesh.MeshGateway{
GatewayClassName: "gateway-class-1",
Listeners: []*pbmesh.MeshGatewayListener{
{
Name: "wan",
},
},
}).
Write(suite.T(), suite.client)

@ -190,15 +190,34 @@ func (f *Fetcher) FetchComputedExplicitDestinationsData(
targetServiceID := resource.IDFromReference(routeTarget.BackendRef.Ref)
// Fetch ServiceEndpoints.
serviceEndpointsRef := &pbproxystate.EndpointRef{
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID),
MeshPort: routeTarget.MeshPort,
RoutePort: routeTarget.BackendRef.Port,
serviceEndpointID := resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID)
se, err := f.FetchServiceEndpoints(ctx, serviceEndpointID)
if err != nil {
return nil, err
}
if se != nil {
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
Id: se.Id,
MeshPort: routeTarget.MeshPort,
RoutePort: routeTarget.BackendRef.Port,
}
routeTarget.ServiceEndpoints = se.Data
// Gather all identities.
var identities []*pbresource.Reference
for _, identity := range se.GetData().GetIdentities() {
identities = append(identities, &pbresource.Reference{
Name: identity,
Tenancy: se.Resource.Id.Tenancy,
})
}
routeTarget.IdentityRefs = identities
}
// If the target service is in a different partition and the mesh gateway mode is
// "local" or "remote", use the ServiceEndpoints for the corresponding MeshGateway
// instead of the ServiceEndpoints for the target service.
// instead of the ServiceEndpoints for the target service. The IdentityRefs on the
// target will remain the same for TCP targets.
//
// TODO(nathancoleman) Consider cross-datacenter case as well
if routeTarget.BackendRef.Ref.Tenancy.Partition != proxyID.Tenancy.Partition {
@ -210,7 +229,7 @@ func (f *Fetcher) FetchComputedExplicitDestinationsData(
switch mode {
case pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_LOCAL:
// Use ServiceEndpoints for the MeshGateway in the source service's partition
serviceEndpointsRef = &pbproxystate.EndpointRef{
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
Id: &pbresource.ID{
Type: pbcatalog.ServiceEndpointsType,
Name: meshgateways.GatewayName,
@ -219,9 +238,16 @@ func (f *Fetcher) FetchComputedExplicitDestinationsData(
MeshPort: meshgateways.LANPortName,
RoutePort: meshgateways.LANPortName,
}
se, err := f.FetchServiceEndpoints(ctx, routeTarget.ServiceEndpointsRef.Id)
if err != nil {
return nil, err
} else if se != nil {
routeTarget.ServiceEndpoints = se.GetData()
}
case pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_REMOTE:
// Use ServiceEndpoints for the MeshGateway in the target service's partition
serviceEndpointsRef = &pbproxystate.EndpointRef{
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
Id: &pbresource.ID{
Type: pbcatalog.ServiceEndpointsType,
Name: meshgateways.GatewayName,
@ -230,28 +256,14 @@ func (f *Fetcher) FetchComputedExplicitDestinationsData(
MeshPort: meshgateways.WANPortName,
RoutePort: meshgateways.WANPortName,
}
}
}
se, err := f.FetchServiceEndpoints(ctx, serviceEndpointsRef.Id)
if err != nil {
return nil, err
}
if se != nil {
// We need to make sure the Uid is set
serviceEndpointsRef.Id = se.Id
routeTarget.ServiceEndpointsRef = serviceEndpointsRef
routeTarget.ServiceEndpoints = se.Data
// Gather all identities.
var identities []*pbresource.Reference
for _, identity := range se.GetData().GetIdentities() {
identities = append(identities, &pbresource.Reference{
Name: identity,
Tenancy: se.Resource.Id.Tenancy,
})
se, err := f.FetchServiceEndpoints(ctx, routeTarget.ServiceEndpointsRef.Id)
if err != nil {
return nil, err
} else if se != nil {
routeTarget.ServiceEndpoints = se.GetData()
}
}
routeTarget.IdentityRefs = identities
}
}

@ -8,7 +8,7 @@ import (
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
)
type (

@ -4,6 +4,12 @@
package types
import (
"errors"
"fmt"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/meshgateways"
"github.com/hashicorp/consul/internal/resource"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
)
@ -15,6 +21,24 @@ func RegisterMeshGateway(r resource.Registry) {
Scope: resource.ScopePartition,
ACLs: nil, // TODO NET-6416
Mutate: nil, // TODO NET-6418
Validate: nil, // TODO NET-6417
Validate: resource.DecodeAndValidate(validateMeshGateway),
})
}
func validateMeshGateway(res *DecodedMeshGateway) error {
var merr error
if res.GetId().GetName() != meshgateways.GatewayName {
merr = multierror.Append(merr, fmt.Errorf("invalid gateway name, must be %q", meshgateways.GatewayName))
}
if len(res.GetData().Listeners) != 1 {
merr = multierror.Append(merr, errors.New("invalid listeners, must have exactly one listener"))
}
if len(res.GetData().Listeners) > 0 && (res.GetData().Listeners[0].GetName() != meshgateways.WANPortName) {
merr = multierror.Append(merr, fmt.Errorf("invalid listener name, must be %q", meshgateways.WANPortName))
}
return merr
}

@ -0,0 +1,97 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package types
import (
"github.com/hashicorp/consul/internal/resource"
"testing"
"github.com/hashicorp/consul/internal/resource/resourcetest"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/stretchr/testify/require"
)
func TestValidateMeshGateway(t *testing.T) {
type testcase struct {
mgwName string
mgw *pbmesh.MeshGateway
expectErr string
}
run := func(t *testing.T, tc testcase) {
res := resourcetest.Resource(pbmesh.MeshGatewayType, tc.mgwName).
WithData(t, tc.mgw).
Build()
err := resource.DecodeAndValidate(validateMeshGateway)(res)
if tc.expectErr == "" {
require.NoError(t, err)
} else {
testutil.RequireErrorContains(t, err, tc.expectErr)
}
}
cases := map[string]testcase{
"happy path": {
mgwName: "mesh-gateway",
mgw: &pbmesh.MeshGateway{
Listeners: []*pbmesh.MeshGatewayListener{
{
Name: "wan",
},
},
},
expectErr: "",
},
"wrong name for mesh-gateway": {
mgwName: "my-mesh-gateway",
mgw: &pbmesh.MeshGateway{
Listeners: []*pbmesh.MeshGatewayListener{
{
Name: "wan",
},
},
},
expectErr: "invalid gateway name, must be \"mesh-gateway\"",
},
"too many listeners on mesh-gateway": {
mgwName: "mesh-gateway",
mgw: &pbmesh.MeshGateway{
Listeners: []*pbmesh.MeshGatewayListener{
{
Name: "obi",
},
{
Name: "wan",
},
},
},
expectErr: "invalid listeners, must have exactly one listener",
},
"zero listeners on mesh-gateway": {
mgwName: "mesh-gateway",
mgw: &pbmesh.MeshGateway{},
expectErr: "invalid listeners, must have exactly one listener",
},
"incorrect listener name on mesh-gateway": {
mgwName: "mesh-gateway",
mgw: &pbmesh.MeshGateway{
Listeners: []*pbmesh.MeshGatewayListener{
{
Name: "kenobi",
},
},
},
expectErr: "invalid listener name, must be \"wan\"",
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
run(t, tc)
})
}
}

@ -9,7 +9,7 @@ import (
expanderTypes "github.com/hashicorp/consul/internal/multicluster/internal/controllers/exportedservices/expander/types"
"github.com/hashicorp/consul/internal/multicluster/internal/types"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -17,7 +17,7 @@ import (
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/storage"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -20,7 +20,7 @@ import (
"github.com/hashicorp/consul/internal/resource"
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/proto/private/prototest"
"github.com/hashicorp/consul/sdk/testutil"

@ -10,7 +10,7 @@ import (
"github.com/hashicorp/consul/internal/controller"
expanderTypes "github.com/hashicorp/consul/internal/multicluster/internal/controllers/exportedservices/expander/types"
"github.com/hashicorp/consul/internal/multicluster/internal/types"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
)
type SamenessGroupExpander struct{}

@ -6,7 +6,7 @@ package expander_ce
import (
"testing"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)

@ -14,7 +14,7 @@ import (
"github.com/hashicorp/consul/internal/multicluster/internal/types"
"github.com/hashicorp/consul/internal/resource"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -6,7 +6,7 @@ package types
import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -11,7 +11,7 @@ import (
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/resource/resourcetest"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/version/versiontest"
)

@ -5,7 +5,7 @@ package types
import (
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
)
type (

@ -6,7 +6,7 @@ package types
import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -11,7 +11,7 @@ import (
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/resource/resourcetest"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/version/versiontest"
)

@ -7,7 +7,7 @@ import (
"fmt"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/go-multierror"
)

@ -11,7 +11,7 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
)
func validateExportedServicesConsumer(consumer *pbmulticluster.ExportedServicesConsumer, indx int) error {

@ -6,7 +6,7 @@ package types
import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -10,7 +10,7 @@ import (
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/resource/resourcetest"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/version/versiontest"
)

@ -6,7 +6,7 @@ package types
import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
)

@ -10,7 +10,7 @@ import (
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/resource/resourcetest"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/version/versiontest"
)

@ -0,0 +1,18 @@
// Code generated by protoc-gen-go-binary. DO NOT EDIT.
// source: pbhcp/v2/hcp_config.proto
package hcpv2
import (
"google.golang.org/protobuf/proto"
)
// MarshalBinary implements encoding.BinaryMarshaler
func (msg *HCPConfig) MarshalBinary() ([]byte, error) {
return proto.Marshal(msg)
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler
func (msg *HCPConfig) UnmarshalBinary(b []byte) error {
return proto.Unmarshal(b, msg)
}

@ -0,0 +1,199 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: pbhcp/v2/hcp_config.proto
package hcpv2
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// HCPConfig is used to configure the HCP SDK for communicating with
// the HashiCorp Cloud Platform. All configuration is optional with default
// values provided by the SDK.
type HCPConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// AuthUrl is the URL which will be used to authenticate.
AuthUrl string `protobuf:"bytes,1,opt,name=auth_url,json=authUrl,proto3" json:"auth_url,omitempty"`
// ApiAddress is the address (<hostname>[:port]) of the HCP api.
ApiAddress string `protobuf:"bytes,2,opt,name=api_address,json=apiAddress,proto3" json:"api_address,omitempty"`
// ScadaAddress is the address (<hostname>[:port]) of the HCP SCADA endpoint.
ScadaAddress string `protobuf:"bytes,3,opt,name=scada_address,json=scadaAddress,proto3" json:"scada_address,omitempty"`
// TlsInsecureSkipVerify if true will ignore server name verification when making HTTPS requests
TlsInsecureSkipVerify bool `protobuf:"varint,4,opt,name=tls_insecure_skip_verify,json=tlsInsecureSkipVerify,proto3" json:"tls_insecure_skip_verify,omitempty"`
}
func (x *HCPConfig) Reset() {
*x = HCPConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_pbhcp_v2_hcp_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HCPConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HCPConfig) ProtoMessage() {}
func (x *HCPConfig) ProtoReflect() protoreflect.Message {
mi := &file_pbhcp_v2_hcp_config_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HCPConfig.ProtoReflect.Descriptor instead.
func (*HCPConfig) Descriptor() ([]byte, []int) {
return file_pbhcp_v2_hcp_config_proto_rawDescGZIP(), []int{0}
}
func (x *HCPConfig) GetAuthUrl() string {
if x != nil {
return x.AuthUrl
}
return ""
}
func (x *HCPConfig) GetApiAddress() string {
if x != nil {
return x.ApiAddress
}
return ""
}
func (x *HCPConfig) GetScadaAddress() string {
if x != nil {
return x.ScadaAddress
}
return ""
}
func (x *HCPConfig) GetTlsInsecureSkipVerify() bool {
if x != nil {
return x.TlsInsecureSkipVerify
}
return false
}
var File_pbhcp_v2_hcp_config_proto protoreflect.FileDescriptor
var file_pbhcp_v2_hcp_config_proto_rawDesc = []byte{
0x0a, 0x19, 0x70, 0x62, 0x68, 0x63, 0x70, 0x2f, 0x76, 0x32, 0x2f, 0x68, 0x63, 0x70, 0x5f, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x68, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63,
0x70, 0x2e, 0x76, 0x32, 0x22, 0xa5, 0x01, 0x0a, 0x09, 0x48, 0x43, 0x50, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x75, 0x74, 0x68, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a,
0x0b, 0x61, 0x70, 0x69, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23,
0x0a, 0x0d, 0x73, 0x63, 0x61, 0x64, 0x61, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x63, 0x61, 0x64, 0x61, 0x41, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x18, 0x74, 0x6c, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x65, 0x63,
0x75, 0x72, 0x65, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18,
0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x74, 0x6c, 0x73, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75,
0x72, 0x65, 0x53, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x42, 0xe5, 0x01, 0x0a,
0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63,
0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e, 0x76, 0x32, 0x42, 0x0e, 0x48, 0x63,
0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37,
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, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x68, 0x63, 0x70, 0x2f, 0x76,
0x32, 0x3b, 0x68, 0x63, 0x70, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x48, 0xaa, 0x02, 0x17,
0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
0x2e, 0x48, 0x63, 0x70, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x17, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63,
0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x48, 0x63, 0x70, 0x5c, 0x56,
0x32, 0xe2, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f,
0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x48, 0x63, 0x70, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d,
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63,
0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x48, 0x63, 0x70,
0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pbhcp_v2_hcp_config_proto_rawDescOnce sync.Once
file_pbhcp_v2_hcp_config_proto_rawDescData = file_pbhcp_v2_hcp_config_proto_rawDesc
)
func file_pbhcp_v2_hcp_config_proto_rawDescGZIP() []byte {
file_pbhcp_v2_hcp_config_proto_rawDescOnce.Do(func() {
file_pbhcp_v2_hcp_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbhcp_v2_hcp_config_proto_rawDescData)
})
return file_pbhcp_v2_hcp_config_proto_rawDescData
}
var file_pbhcp_v2_hcp_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_pbhcp_v2_hcp_config_proto_goTypes = []interface{}{
(*HCPConfig)(nil), // 0: hashicorp.consul.hcp.v2.HCPConfig
}
var file_pbhcp_v2_hcp_config_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_pbhcp_v2_hcp_config_proto_init() }
func file_pbhcp_v2_hcp_config_proto_init() {
if File_pbhcp_v2_hcp_config_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_pbhcp_v2_hcp_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HCPConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pbhcp_v2_hcp_config_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_pbhcp_v2_hcp_config_proto_goTypes,
DependencyIndexes: file_pbhcp_v2_hcp_config_proto_depIdxs,
MessageInfos: file_pbhcp_v2_hcp_config_proto_msgTypes,
}.Build()
File_pbhcp_v2_hcp_config_proto = out.File
file_pbhcp_v2_hcp_config_proto_rawDesc = nil
file_pbhcp_v2_hcp_config_proto_goTypes = nil
file_pbhcp_v2_hcp_config_proto_depIdxs = nil
}

@ -0,0 +1,23 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
syntax = "proto3";
package hashicorp.consul.hcp.v2;
// HCPConfig is used to configure the HCP SDK for communicating with
// the HashiCorp Cloud Platform. All configuration is optional with default
// values provided by the SDK.
message HCPConfig {
// AuthUrl is the URL which will be used to authenticate.
string auth_url = 1;
// ApiAddress is the address (<hostname>[:port]) of the HCP api.
string api_address = 2;
// ScadaAddress is the address (<hostname>[:port]) of the HCP SCADA endpoint.
string scada_address = 3;
// TlsInsecureSkipVerify if true will ignore server name verification when making HTTPS requests
bool tls_insecure_skip_verify = 4;
}

@ -0,0 +1,27 @@
// Code generated by protoc-gen-deepcopy. DO NOT EDIT.
package hcpv2
import (
proto "google.golang.org/protobuf/proto"
)
// DeepCopyInto supports using HCPConfig within kubernetes types, where deepcopy-gen is used.
func (in *HCPConfig) DeepCopyInto(out *HCPConfig) {
proto.Reset(out)
proto.Merge(out, proto.Clone(in))
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HCPConfig. Required by controller-gen.
func (in *HCPConfig) DeepCopy() *HCPConfig {
if in == nil {
return nil
}
out := new(HCPConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HCPConfig. Required by controller-gen.
func (in *HCPConfig) DeepCopyInterface() interface{} {
return in.DeepCopy()
}

@ -0,0 +1,22 @@
// Code generated by protoc-json-shim. DO NOT EDIT.
package hcpv2
import (
protojson "google.golang.org/protobuf/encoding/protojson"
)
// MarshalJSON is a custom marshaler for HCPConfig
func (this *HCPConfig) MarshalJSON() ([]byte, error) {
str, err := HcpConfigMarshaler.Marshal(this)
return []byte(str), err
}
// UnmarshalJSON is a custom unmarshaler for HCPConfig
func (this *HCPConfig) UnmarshalJSON(b []byte) error {
return HcpConfigUnmarshaler.Unmarshal(b, this)
}
var (
HcpConfigMarshaler = &protojson.MarshalOptions{}
HcpConfigUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false}
)

@ -83,6 +83,7 @@ type Link struct {
ClientSecret string `protobuf:"bytes,3,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
HcpClusterUrl string `protobuf:"bytes,4,opt,name=hcp_cluster_url,json=hcpClusterUrl,proto3" json:"hcp_cluster_url,omitempty"`
AccessLevel AccessLevel `protobuf:"varint,5,opt,name=access_level,json=accessLevel,proto3,enum=hashicorp.consul.hcp.v2.AccessLevel" json:"access_level,omitempty"`
HcpConfig *HCPConfig `protobuf:"bytes,6,opt,name=hcp_config,json=hcpConfig,proto3" json:"hcp_config,omitempty"`
}
func (x *Link) Reset() {
@ -152,50 +153,63 @@ func (x *Link) GetAccessLevel() AccessLevel {
return AccessLevel_ACCESS_LEVEL_UNSPECIFIED
}
func (x *Link) GetHcpConfig() *HCPConfig {
if x != nil {
return x.HcpConfig
}
return nil
}
var File_pbhcp_v2_link_proto protoreflect.FileDescriptor
var file_pbhcp_v2_link_proto_rawDesc = []byte{
0x0a, 0x13, 0x70, 0x62, 0x68, 0x63, 0x70, 0x2f, 0x76, 0x32, 0x2f, 0x6c, 0x69, 0x6e, 0x6b, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e, 0x76, 0x32, 0x1a, 0x1c,
0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe2, 0x01, 0x0a,
0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65,
0x63, 0x72, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x68, 0x63, 0x70, 0x5f,
0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0d, 0x68, 0x63, 0x70, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x6c,
0x12, 0x47, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c,
0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e, 0x76, 0x32,
0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x0b, 0x61, 0x63,
0x63, 0x65, 0x73, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08,
0x01, 0x2a, 0x72, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c,
0x12, 0x1c, 0x0a, 0x18, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c,
0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x22,
0x0a, 0x1e, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x47,
0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45,
0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x45, 0x56,
0x45, 0x4c, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f,
0x4e, 0x4c, 0x59, 0x10, 0x02, 0x42, 0xe0, 0x01, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61,
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68,
0x63, 0x70, 0x2e, 0x76, 0x32, 0x42, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f,
0x50, 0x01, 0x5a, 0x37, 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, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x68,
0x63, 0x70, 0x2f, 0x76, 0x32, 0x3b, 0x68, 0x63, 0x70, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x48, 0x43,
0x48, 0xaa, 0x02, 0x17, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f,
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x48, 0x63, 0x70, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x17, 0x48, 0x61,
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x48,
0x63, 0x70, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x48, 0x63, 0x70, 0x5c, 0x56, 0x32, 0x5c,
0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x48, 0x61,
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a,
0x3a, 0x48, 0x63, 0x70, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e, 0x76, 0x32, 0x1a, 0x19,
0x70, 0x62, 0x68, 0x63, 0x70, 0x2f, 0x76, 0x32, 0x2f, 0x68, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa5, 0x02, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b,
0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49,
0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23,
0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63,
0x72, 0x65, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x68, 0x63, 0x70, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74,
0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x68, 0x63,
0x70, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x47, 0x0a, 0x0c, 0x61,
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x63, 0x63, 0x65,
0x73, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c,
0x65, 0x76, 0x65, 0x6c, 0x12, 0x41, 0x0a, 0x0a, 0x68, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e,
0x76, 0x32, 0x2e, 0x48, 0x43, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x68, 0x63,
0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x01, 0x2a,
0x72, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1c,
0x0a, 0x18, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55,
0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e,
0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x47, 0x4c, 0x4f,
0x42, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01,
0x12, 0x21, 0x0a, 0x1d, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c,
0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c,
0x59, 0x10, 0x02, 0x42, 0xe0, 0x01, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68,
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70,
0x2e, 0x76, 0x32, 0x42, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
0x5a, 0x37, 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, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x68, 0x63, 0x70,
0x2f, 0x76, 0x32, 0x3b, 0x68, 0x63, 0x70, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x48, 0xaa,
0x02, 0x17, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73,
0x75, 0x6c, 0x2e, 0x48, 0x63, 0x70, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x17, 0x48, 0x61, 0x73, 0x68,
0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x48, 0x63, 0x70,
0x5c, 0x56, 0x32, 0xe2, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c,
0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x48, 0x63, 0x70, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50,
0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x48, 0x61, 0x73, 0x68,
0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x48,
0x63, 0x70, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -213,16 +227,18 @@ func file_pbhcp_v2_link_proto_rawDescGZIP() []byte {
var file_pbhcp_v2_link_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_pbhcp_v2_link_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_pbhcp_v2_link_proto_goTypes = []interface{}{
(AccessLevel)(0), // 0: hashicorp.consul.hcp.v2.AccessLevel
(*Link)(nil), // 1: hashicorp.consul.hcp.v2.Link
(AccessLevel)(0), // 0: hashicorp.consul.hcp.v2.AccessLevel
(*Link)(nil), // 1: hashicorp.consul.hcp.v2.Link
(*HCPConfig)(nil), // 2: hashicorp.consul.hcp.v2.HCPConfig
}
var file_pbhcp_v2_link_proto_depIdxs = []int32{
0, // 0: hashicorp.consul.hcp.v2.Link.access_level:type_name -> hashicorp.consul.hcp.v2.AccessLevel
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
2, // 1: hashicorp.consul.hcp.v2.Link.hcp_config:type_name -> hashicorp.consul.hcp.v2.HCPConfig
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_pbhcp_v2_link_proto_init() }
@ -230,6 +246,7 @@ func file_pbhcp_v2_link_proto_init() {
if File_pbhcp_v2_link_proto != nil {
return
}
file_pbhcp_v2_hcp_config_proto_init()
if !protoimpl.UnsafeEnabled {
file_pbhcp_v2_link_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Link); i {

@ -5,6 +5,7 @@ syntax = "proto3";
package hashicorp.consul.hcp.v2;
import "pbhcp/v2/hcp_config.proto";
import "pbresource/annotations.proto";
enum AccessLevel {
@ -21,4 +22,5 @@ message Link {
string client_secret = 3;
string hcp_cluster_url = 4;
AccessLevel access_level = 5;
HCPConfig hcp_config = 6;
}

@ -10,7 +10,8 @@ const (
GroupName = "hcp"
Version = "v2"
LinkKind = "Link"
LinkKind = "Link"
TelemetryStateKind = "TelemetryState"
)
var (
@ -19,4 +20,10 @@ var (
GroupVersion: Version,
Kind: LinkKind,
}
TelemetryStateType = &pbresource.Type{
Group: GroupName,
GroupVersion: Version,
Kind: TelemetryStateKind,
}
)

@ -0,0 +1,38 @@
// Code generated by protoc-gen-go-binary. DO NOT EDIT.
// source: pbhcp/v2/telemetry_state.proto
package hcpv2
import (
"google.golang.org/protobuf/proto"
)
// MarshalBinary implements encoding.BinaryMarshaler
func (msg *TelemetryState) MarshalBinary() ([]byte, error) {
return proto.Marshal(msg)
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler
func (msg *TelemetryState) UnmarshalBinary(b []byte) error {
return proto.Unmarshal(b, msg)
}
// MarshalBinary implements encoding.BinaryMarshaler
func (msg *MetricsConfig) MarshalBinary() ([]byte, error) {
return proto.Marshal(msg)
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler
func (msg *MetricsConfig) UnmarshalBinary(b []byte) error {
return proto.Unmarshal(b, msg)
}
// MarshalBinary implements encoding.BinaryMarshaler
func (msg *ProxyConfig) MarshalBinary() ([]byte, error) {
return proto.Marshal(msg)
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler
func (msg *ProxyConfig) UnmarshalBinary(b []byte) error {
return proto.Unmarshal(b, msg)
}

@ -0,0 +1,426 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: pbhcp/v2/telemetry_state.proto
package hcpv2
import (
_ "github.com/hashicorp/consul/proto-public/pbresource"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// TelemetryState describes configuration required to forward telemetry to the HashiCorp Cloud Platform.
// This resource is managed internally and is only written if the cluster is linked to HCP. Any
// manual changes to the resource will be reconciled and overwritten with the internally computed
// state.
type TelemetryState struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// ResourceId is the identifier for the cluster linked with HCP.
ResourceId string `protobuf:"bytes,1,opt,name=resource_id,json=resourceId,proto3" json:"resource_id,omitempty"`
// ClientId is the oauth client identifier for cluster.
// This client has capabilities limited to writing telemetry data for this cluster.
ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
// ClientSecret is the oauth secret used to authenticate requests to send telemetry data to HCP.
ClientSecret string `protobuf:"bytes,3,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
HcpConfig *HCPConfig `protobuf:"bytes,4,opt,name=hcp_config,json=hcpConfig,proto3" json:"hcp_config,omitempty"`
Proxy *ProxyConfig `protobuf:"bytes,5,opt,name=proxy,proto3" json:"proxy,omitempty"`
Metrics *MetricsConfig `protobuf:"bytes,6,opt,name=metrics,proto3" json:"metrics,omitempty"`
}
func (x *TelemetryState) Reset() {
*x = TelemetryState{}
if protoimpl.UnsafeEnabled {
mi := &file_pbhcp_v2_telemetry_state_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *TelemetryState) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TelemetryState) ProtoMessage() {}
func (x *TelemetryState) ProtoReflect() protoreflect.Message {
mi := &file_pbhcp_v2_telemetry_state_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TelemetryState.ProtoReflect.Descriptor instead.
func (*TelemetryState) Descriptor() ([]byte, []int) {
return file_pbhcp_v2_telemetry_state_proto_rawDescGZIP(), []int{0}
}
func (x *TelemetryState) GetResourceId() string {
if x != nil {
return x.ResourceId
}
return ""
}
func (x *TelemetryState) GetClientId() string {
if x != nil {
return x.ClientId
}
return ""
}
func (x *TelemetryState) GetClientSecret() string {
if x != nil {
return x.ClientSecret
}
return ""
}
func (x *TelemetryState) GetHcpConfig() *HCPConfig {
if x != nil {
return x.HcpConfig
}
return nil
}
func (x *TelemetryState) GetProxy() *ProxyConfig {
if x != nil {
return x.Proxy
}
return nil
}
func (x *TelemetryState) GetMetrics() *MetricsConfig {
if x != nil {
return x.Metrics
}
return nil
}
// MetricsConfig configures metric specific collection details
type MetricsConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Endpoint is the HTTPS address and path to forward metrics to
Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
// IncludeList contains patterns to match against metric names. Only matched metrics are forwarded.
IncludeList []string `protobuf:"bytes,2,rep,name=include_list,json=includeList,proto3" json:"include_list,omitempty"`
// Labels contains key value pairs that are associated with all metrics collected and fowarded.
Labels map[string]string `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// Disabled toggles metric forwarding. If true, metric forwarding will stop until disabled is set to false.
Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"`
}
func (x *MetricsConfig) Reset() {
*x = MetricsConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_pbhcp_v2_telemetry_state_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MetricsConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MetricsConfig) ProtoMessage() {}
func (x *MetricsConfig) ProtoReflect() protoreflect.Message {
mi := &file_pbhcp_v2_telemetry_state_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use MetricsConfig.ProtoReflect.Descriptor instead.
func (*MetricsConfig) Descriptor() ([]byte, []int) {
return file_pbhcp_v2_telemetry_state_proto_rawDescGZIP(), []int{1}
}
func (x *MetricsConfig) GetEndpoint() string {
if x != nil {
return x.Endpoint
}
return ""
}
func (x *MetricsConfig) GetIncludeList() []string {
if x != nil {
return x.IncludeList
}
return nil
}
func (x *MetricsConfig) GetLabels() map[string]string {
if x != nil {
return x.Labels
}
return nil
}
func (x *MetricsConfig) GetDisabled() bool {
if x != nil {
return x.Disabled
}
return false
}
// ProxyConfig describes configuration for forwarding requests through an http proxy
type ProxyConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// HttpProxy configures the http proxy to use for HTTP (non-TLS) requests.
HttpProxy string `protobuf:"bytes,1,opt,name=http_proxy,json=httpProxy,proto3" json:"http_proxy,omitempty"`
// HttpsProxy configures the http proxy to use for HTTPS (TLS) requests.
HttpsProxy string `protobuf:"bytes,2,opt,name=https_proxy,json=httpsProxy,proto3" json:"https_proxy,omitempty"`
// NoProxy can be configured to include domains which should NOT be forwarded through the configured http proxy
NoProxy []string `protobuf:"bytes,3,rep,name=no_proxy,json=noProxy,proto3" json:"no_proxy,omitempty"`
}
func (x *ProxyConfig) Reset() {
*x = ProxyConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_pbhcp_v2_telemetry_state_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ProxyConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ProxyConfig) ProtoMessage() {}
func (x *ProxyConfig) ProtoReflect() protoreflect.Message {
mi := &file_pbhcp_v2_telemetry_state_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ProxyConfig.ProtoReflect.Descriptor instead.
func (*ProxyConfig) Descriptor() ([]byte, []int) {
return file_pbhcp_v2_telemetry_state_proto_rawDescGZIP(), []int{2}
}
func (x *ProxyConfig) GetHttpProxy() string {
if x != nil {
return x.HttpProxy
}
return ""
}
func (x *ProxyConfig) GetHttpsProxy() string {
if x != nil {
return x.HttpsProxy
}
return ""
}
func (x *ProxyConfig) GetNoProxy() []string {
if x != nil {
return x.NoProxy
}
return nil
}
var File_pbhcp_v2_telemetry_state_proto protoreflect.FileDescriptor
var file_pbhcp_v2_telemetry_state_proto_rawDesc = []byte{
0x0a, 0x1e, 0x70, 0x62, 0x68, 0x63, 0x70, 0x2f, 0x76, 0x32, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x6d,
0x65, 0x74, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x17, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e, 0x76, 0x32, 0x1a, 0x19, 0x70, 0x62, 0x68, 0x63, 0x70,
0x2f, 0x76, 0x32, 0x2f, 0x68, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0xbc, 0x02, 0x0a, 0x0e, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79,
0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65,
0x63, 0x72, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x41, 0x0a, 0x0a, 0x68, 0x63, 0x70, 0x5f,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x68,
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
0x68, 0x63, 0x70, 0x2e, 0x76, 0x32, 0x2e, 0x48, 0x43, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x52, 0x09, 0x68, 0x63, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3a, 0x0a, 0x05, 0x70,
0x72, 0x6f, 0x78, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63,
0x70, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x52, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x40, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69,
0x63, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e,
0x76, 0x32, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08,
0x01, 0x22, 0xf1, 0x01, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12,
0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18,
0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x69,
0x73, 0x74, 0x12, 0x4a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63,
0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1a,
0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61,
0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x68, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x70, 0x72, 0x6f,
0x78, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x68, 0x74, 0x74, 0x70, 0x50, 0x72,
0x6f, 0x78, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x5f, 0x70, 0x72, 0x6f,
0x78, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x50,
0x72, 0x6f, 0x78, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79,
0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x6f, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x42,
0xea, 0x01, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x68, 0x63, 0x70, 0x2e, 0x76, 0x32, 0x42,
0x13, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50,
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 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, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x2f, 0x70, 0x62, 0x68, 0x63, 0x70, 0x2f, 0x76, 0x32, 0x3b, 0x68, 0x63, 0x70, 0x76, 0x32, 0xa2,
0x02, 0x03, 0x48, 0x43, 0x48, 0xaa, 0x02, 0x17, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x48, 0x63, 0x70, 0x2e, 0x56, 0x32, 0xca,
0x02, 0x17, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73,
0x75, 0x6c, 0x5c, 0x48, 0x63, 0x70, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68,
0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x48, 0x63, 0x70,
0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
0x02, 0x1a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e,
0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x48, 0x63, 0x70, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pbhcp_v2_telemetry_state_proto_rawDescOnce sync.Once
file_pbhcp_v2_telemetry_state_proto_rawDescData = file_pbhcp_v2_telemetry_state_proto_rawDesc
)
func file_pbhcp_v2_telemetry_state_proto_rawDescGZIP() []byte {
file_pbhcp_v2_telemetry_state_proto_rawDescOnce.Do(func() {
file_pbhcp_v2_telemetry_state_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbhcp_v2_telemetry_state_proto_rawDescData)
})
return file_pbhcp_v2_telemetry_state_proto_rawDescData
}
var file_pbhcp_v2_telemetry_state_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_pbhcp_v2_telemetry_state_proto_goTypes = []interface{}{
(*TelemetryState)(nil), // 0: hashicorp.consul.hcp.v2.TelemetryState
(*MetricsConfig)(nil), // 1: hashicorp.consul.hcp.v2.MetricsConfig
(*ProxyConfig)(nil), // 2: hashicorp.consul.hcp.v2.ProxyConfig
nil, // 3: hashicorp.consul.hcp.v2.MetricsConfig.LabelsEntry
(*HCPConfig)(nil), // 4: hashicorp.consul.hcp.v2.HCPConfig
}
var file_pbhcp_v2_telemetry_state_proto_depIdxs = []int32{
4, // 0: hashicorp.consul.hcp.v2.TelemetryState.hcp_config:type_name -> hashicorp.consul.hcp.v2.HCPConfig
2, // 1: hashicorp.consul.hcp.v2.TelemetryState.proxy:type_name -> hashicorp.consul.hcp.v2.ProxyConfig
1, // 2: hashicorp.consul.hcp.v2.TelemetryState.metrics:type_name -> hashicorp.consul.hcp.v2.MetricsConfig
3, // 3: hashicorp.consul.hcp.v2.MetricsConfig.labels:type_name -> hashicorp.consul.hcp.v2.MetricsConfig.LabelsEntry
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_pbhcp_v2_telemetry_state_proto_init() }
func file_pbhcp_v2_telemetry_state_proto_init() {
if File_pbhcp_v2_telemetry_state_proto != nil {
return
}
file_pbhcp_v2_hcp_config_proto_init()
if !protoimpl.UnsafeEnabled {
file_pbhcp_v2_telemetry_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TelemetryState); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pbhcp_v2_telemetry_state_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MetricsConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pbhcp_v2_telemetry_state_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProxyConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pbhcp_v2_telemetry_state_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_pbhcp_v2_telemetry_state_proto_goTypes,
DependencyIndexes: file_pbhcp_v2_telemetry_state_proto_depIdxs,
MessageInfos: file_pbhcp_v2_telemetry_state_proto_msgTypes,
}.Build()
File_pbhcp_v2_telemetry_state_proto = out.File
file_pbhcp_v2_telemetry_state_proto_rawDesc = nil
file_pbhcp_v2_telemetry_state_proto_goTypes = nil
file_pbhcp_v2_telemetry_state_proto_depIdxs = nil
}

@ -0,0 +1,55 @@
syntax = "proto3";
package hashicorp.consul.hcp.v2;
import "pbhcp/v2/hcp_config.proto";
import "pbresource/annotations.proto";
// TelemetryState describes configuration required to forward telemetry to the HashiCorp Cloud Platform.
// This resource is managed internally and is only written if the cluster is linked to HCP. Any
// manual changes to the resource will be reconciled and overwritten with the internally computed
// state.
message TelemetryState {
option (hashicorp.consul.resource.spec) = {scope: SCOPE_CLUSTER};
// ResourceId is the identifier for the cluster linked with HCP.
string resource_id = 1;
// ClientId is the oauth client identifier for cluster.
// This client has capabilities limited to writing telemetry data for this cluster.
string client_id = 2;
// ClientSecret is the oauth secret used to authenticate requests to send telemetry data to HCP.
string client_secret = 3;
HCPConfig hcp_config = 4;
ProxyConfig proxy = 5;
MetricsConfig metrics = 6;
}
// MetricsConfig configures metric specific collection details
message MetricsConfig {
// Endpoint is the HTTPS address and path to forward metrics to
string endpoint = 1;
// IncludeList contains patterns to match against metric names. Only matched metrics are forwarded.
repeated string include_list = 2;
// Labels contains key value pairs that are associated with all metrics collected and fowarded.
map<string, string> labels = 3;
// Disabled toggles metric forwarding. If true, metric forwarding will stop until disabled is set to false.
bool disabled = 4;
}
// ProxyConfig describes configuration for forwarding requests through an http proxy
message ProxyConfig {
// HttpProxy configures the http proxy to use for HTTP (non-TLS) requests.
string http_proxy = 1;
// HttpsProxy configures the http proxy to use for HTTPS (TLS) requests.
string https_proxy = 2;
// NoProxy can be configured to include domains which should NOT be forwarded through the configured http proxy
repeated string no_proxy = 3;
}

@ -0,0 +1,69 @@
// Code generated by protoc-gen-deepcopy. DO NOT EDIT.
package hcpv2
import (
proto "google.golang.org/protobuf/proto"
)
// DeepCopyInto supports using TelemetryState within kubernetes types, where deepcopy-gen is used.
func (in *TelemetryState) DeepCopyInto(out *TelemetryState) {
proto.Reset(out)
proto.Merge(out, proto.Clone(in))
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TelemetryState. Required by controller-gen.
func (in *TelemetryState) DeepCopy() *TelemetryState {
if in == nil {
return nil
}
out := new(TelemetryState)
in.DeepCopyInto(out)
return out
}
// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TelemetryState. Required by controller-gen.
func (in *TelemetryState) DeepCopyInterface() interface{} {
return in.DeepCopy()
}
// DeepCopyInto supports using MetricsConfig within kubernetes types, where deepcopy-gen is used.
func (in *MetricsConfig) DeepCopyInto(out *MetricsConfig) {
proto.Reset(out)
proto.Merge(out, proto.Clone(in))
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsConfig. Required by controller-gen.
func (in *MetricsConfig) DeepCopy() *MetricsConfig {
if in == nil {
return nil
}
out := new(MetricsConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new MetricsConfig. Required by controller-gen.
func (in *MetricsConfig) DeepCopyInterface() interface{} {
return in.DeepCopy()
}
// DeepCopyInto supports using ProxyConfig within kubernetes types, where deepcopy-gen is used.
func (in *ProxyConfig) DeepCopyInto(out *ProxyConfig) {
proto.Reset(out)
proto.Merge(out, proto.Clone(in))
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyConfig. Required by controller-gen.
func (in *ProxyConfig) DeepCopy() *ProxyConfig {
if in == nil {
return nil
}
out := new(ProxyConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ProxyConfig. Required by controller-gen.
func (in *ProxyConfig) DeepCopyInterface() interface{} {
return in.DeepCopy()
}

@ -0,0 +1,44 @@
// Code generated by protoc-json-shim. DO NOT EDIT.
package hcpv2
import (
protojson "google.golang.org/protobuf/encoding/protojson"
)
// MarshalJSON is a custom marshaler for TelemetryState
func (this *TelemetryState) MarshalJSON() ([]byte, error) {
str, err := TelemetryStateMarshaler.Marshal(this)
return []byte(str), err
}
// UnmarshalJSON is a custom unmarshaler for TelemetryState
func (this *TelemetryState) UnmarshalJSON(b []byte) error {
return TelemetryStateUnmarshaler.Unmarshal(b, this)
}
// MarshalJSON is a custom marshaler for MetricsConfig
func (this *MetricsConfig) MarshalJSON() ([]byte, error) {
str, err := TelemetryStateMarshaler.Marshal(this)
return []byte(str), err
}
// UnmarshalJSON is a custom unmarshaler for MetricsConfig
func (this *MetricsConfig) UnmarshalJSON(b []byte) error {
return TelemetryStateUnmarshaler.Unmarshal(b, this)
}
// MarshalJSON is a custom marshaler for ProxyConfig
func (this *ProxyConfig) MarshalJSON() ([]byte, error) {
str, err := TelemetryStateMarshaler.Marshal(this)
return []byte(str), err
}
// UnmarshalJSON is a custom unmarshaler for ProxyConfig
func (this *ProxyConfig) UnmarshalJSON(b []byte) error {
return TelemetryStateUnmarshaler.Unmarshal(b, this)
}
var (
TelemetryStateMarshaler = &protojson.MarshalOptions{}
TelemetryStateUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false}
)

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-binary. DO NOT EDIT.
// source: pbmulticluster/v2beta1/computed_exported_services.proto
// source: pbmulticluster/v2/computed_exported_services.proto
package multiclusterv2beta1
package multiclusterv2
import (
"google.golang.org/protobuf/proto"

@ -0,0 +1,367 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: pbmulticluster/v2/computed_exported_services.proto
package multiclusterv2
import (
pbresource "github.com/hashicorp/consul/proto-public/pbresource"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ComputedExportedServices struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Services []*ComputedExportedService `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"`
}
func (x *ComputedExportedServices) Reset() {
*x = ComputedExportedServices{}
if protoimpl.UnsafeEnabled {
mi := &file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ComputedExportedServices) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ComputedExportedServices) ProtoMessage() {}
func (x *ComputedExportedServices) ProtoReflect() protoreflect.Message {
mi := &file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ComputedExportedServices.ProtoReflect.Descriptor instead.
func (*ComputedExportedServices) Descriptor() ([]byte, []int) {
return file_pbmulticluster_v2_computed_exported_services_proto_rawDescGZIP(), []int{0}
}
func (x *ComputedExportedServices) GetServices() []*ComputedExportedService {
if x != nil {
return x.Services
}
return nil
}
type ComputedExportedService struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
TargetRef *pbresource.Reference `protobuf:"bytes,1,opt,name=target_ref,json=targetRef,proto3" json:"target_ref,omitempty"`
Consumers []*ComputedExportedServiceConsumer `protobuf:"bytes,2,rep,name=consumers,proto3" json:"consumers,omitempty"`
}
func (x *ComputedExportedService) Reset() {
*x = ComputedExportedService{}
if protoimpl.UnsafeEnabled {
mi := &file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ComputedExportedService) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ComputedExportedService) ProtoMessage() {}
func (x *ComputedExportedService) ProtoReflect() protoreflect.Message {
mi := &file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ComputedExportedService.ProtoReflect.Descriptor instead.
func (*ComputedExportedService) Descriptor() ([]byte, []int) {
return file_pbmulticluster_v2_computed_exported_services_proto_rawDescGZIP(), []int{1}
}
func (x *ComputedExportedService) GetTargetRef() *pbresource.Reference {
if x != nil {
return x.TargetRef
}
return nil
}
func (x *ComputedExportedService) GetConsumers() []*ComputedExportedServiceConsumer {
if x != nil {
return x.Consumers
}
return nil
}
type ComputedExportedServiceConsumer struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// no sameness group
//
// Types that are assignable to Tenancy:
//
// *ComputedExportedServiceConsumer_Peer
// *ComputedExportedServiceConsumer_Partition
Tenancy isComputedExportedServiceConsumer_Tenancy `protobuf_oneof:"tenancy"`
}
func (x *ComputedExportedServiceConsumer) Reset() {
*x = ComputedExportedServiceConsumer{}
if protoimpl.UnsafeEnabled {
mi := &file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ComputedExportedServiceConsumer) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ComputedExportedServiceConsumer) ProtoMessage() {}
func (x *ComputedExportedServiceConsumer) ProtoReflect() protoreflect.Message {
mi := &file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ComputedExportedServiceConsumer.ProtoReflect.Descriptor instead.
func (*ComputedExportedServiceConsumer) Descriptor() ([]byte, []int) {
return file_pbmulticluster_v2_computed_exported_services_proto_rawDescGZIP(), []int{2}
}
func (m *ComputedExportedServiceConsumer) GetTenancy() isComputedExportedServiceConsumer_Tenancy {
if m != nil {
return m.Tenancy
}
return nil
}
func (x *ComputedExportedServiceConsumer) GetPeer() string {
if x, ok := x.GetTenancy().(*ComputedExportedServiceConsumer_Peer); ok {
return x.Peer
}
return ""
}
func (x *ComputedExportedServiceConsumer) GetPartition() string {
if x, ok := x.GetTenancy().(*ComputedExportedServiceConsumer_Partition); ok {
return x.Partition
}
return ""
}
type isComputedExportedServiceConsumer_Tenancy interface {
isComputedExportedServiceConsumer_Tenancy()
}
type ComputedExportedServiceConsumer_Peer struct {
Peer string `protobuf:"bytes,3,opt,name=peer,proto3,oneof"`
}
type ComputedExportedServiceConsumer_Partition struct {
Partition string `protobuf:"bytes,4,opt,name=partition,proto3,oneof"`
}
func (*ComputedExportedServiceConsumer_Peer) isComputedExportedServiceConsumer_Tenancy() {}
func (*ComputedExportedServiceConsumer_Partition) isComputedExportedServiceConsumer_Tenancy() {}
var File_pbmulticluster_v2_computed_exported_services_proto protoreflect.FileDescriptor
var file_pbmulticluster_v2_computed_exported_services_proto_rawDesc = []byte{
0x0a, 0x32, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x78, 0x70,
0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73,
0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0x79, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72,
0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x55, 0x0a, 0x08, 0x73,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e,
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32,
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65,
0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x22, 0xbf, 0x01, 0x0a, 0x17, 0x43,
0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x5f, 0x0a, 0x09, 0x63,
0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41,
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76,
0x32, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74,
0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x22, 0x62, 0x0a, 0x1f,
0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x12,
0x14, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79,
0x42, 0xb3, 0x02, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63,
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x42, 0x1d, 0x43, 0x6f, 0x6d, 0x70, 0x75,
0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 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, 0x2d, 0x70, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73,
0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x3b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73,
0x74, 0x65, 0x72, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x20, 0x48, 0x61,
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d,
0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0xca, 0x02,
0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75,
0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56,
0x32, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f,
0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
0x72, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f,
0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74,
0x65, 0x72, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pbmulticluster_v2_computed_exported_services_proto_rawDescOnce sync.Once
file_pbmulticluster_v2_computed_exported_services_proto_rawDescData = file_pbmulticluster_v2_computed_exported_services_proto_rawDesc
)
func file_pbmulticluster_v2_computed_exported_services_proto_rawDescGZIP() []byte {
file_pbmulticluster_v2_computed_exported_services_proto_rawDescOnce.Do(func() {
file_pbmulticluster_v2_computed_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2_computed_exported_services_proto_rawDescData)
})
return file_pbmulticluster_v2_computed_exported_services_proto_rawDescData
}
var file_pbmulticluster_v2_computed_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_pbmulticluster_v2_computed_exported_services_proto_goTypes = []interface{}{
(*ComputedExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2.ComputedExportedServices
(*ComputedExportedService)(nil), // 1: hashicorp.consul.multicluster.v2.ComputedExportedService
(*ComputedExportedServiceConsumer)(nil), // 2: hashicorp.consul.multicluster.v2.ComputedExportedServiceConsumer
(*pbresource.Reference)(nil), // 3: hashicorp.consul.resource.Reference
}
var file_pbmulticluster_v2_computed_exported_services_proto_depIdxs = []int32{
1, // 0: hashicorp.consul.multicluster.v2.ComputedExportedServices.services:type_name -> hashicorp.consul.multicluster.v2.ComputedExportedService
3, // 1: hashicorp.consul.multicluster.v2.ComputedExportedService.target_ref:type_name -> hashicorp.consul.resource.Reference
2, // 2: hashicorp.consul.multicluster.v2.ComputedExportedService.consumers:type_name -> hashicorp.consul.multicluster.v2.ComputedExportedServiceConsumer
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_pbmulticluster_v2_computed_exported_services_proto_init() }
func file_pbmulticluster_v2_computed_exported_services_proto_init() {
if File_pbmulticluster_v2_computed_exported_services_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ComputedExportedServices); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ComputedExportedService); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ComputedExportedServiceConsumer); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_pbmulticluster_v2_computed_exported_services_proto_msgTypes[2].OneofWrappers = []interface{}{
(*ComputedExportedServiceConsumer_Peer)(nil),
(*ComputedExportedServiceConsumer_Partition)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pbmulticluster_v2_computed_exported_services_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_pbmulticluster_v2_computed_exported_services_proto_goTypes,
DependencyIndexes: file_pbmulticluster_v2_computed_exported_services_proto_depIdxs,
MessageInfos: file_pbmulticluster_v2_computed_exported_services_proto_msgTypes,
}.Build()
File_pbmulticluster_v2_computed_exported_services_proto = out.File
file_pbmulticluster_v2_computed_exported_services_proto_rawDesc = nil
file_pbmulticluster_v2_computed_exported_services_proto_goTypes = nil
file_pbmulticluster_v2_computed_exported_services_proto_depIdxs = nil
}

@ -3,7 +3,7 @@
syntax = "proto3";
package hashicorp.consul.multicluster.v2beta1;
package hashicorp.consul.multicluster.v2;
import "pbresource/annotations.proto";
import "pbresource/resource.proto";

@ -1,5 +1,5 @@
// Code generated by protoc-gen-deepcopy. DO NOT EDIT.
package multiclusterv2beta1
package multiclusterv2
import (
proto "google.golang.org/protobuf/proto"

@ -1,5 +1,5 @@
// Code generated by protoc-json-shim. DO NOT EDIT.
package multiclusterv2beta1
package multiclusterv2
import (
protojson "google.golang.org/protobuf/encoding/protojson"

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-binary. DO NOT EDIT.
// source: pbmulticluster/v2beta1/exported_services.proto
// source: pbmulticluster/v2/exported_services.proto
package multiclusterv2beta1
package multiclusterv2
import (
"google.golang.org/protobuf/proto"

@ -0,0 +1,190 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: pbmulticluster/v2/exported_services.proto
package multiclusterv2
import (
_ "github.com/hashicorp/consul/proto-public/pbresource"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ExportedServices struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Services []string `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"`
Consumers []*ExportedServicesConsumer `protobuf:"bytes,2,rep,name=consumers,proto3" json:"consumers,omitempty"`
}
func (x *ExportedServices) Reset() {
*x = ExportedServices{}
if protoimpl.UnsafeEnabled {
mi := &file_pbmulticluster_v2_exported_services_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ExportedServices) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ExportedServices) ProtoMessage() {}
func (x *ExportedServices) ProtoReflect() protoreflect.Message {
mi := &file_pbmulticluster_v2_exported_services_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ExportedServices.ProtoReflect.Descriptor instead.
func (*ExportedServices) Descriptor() ([]byte, []int) {
return file_pbmulticluster_v2_exported_services_proto_rawDescGZIP(), []int{0}
}
func (x *ExportedServices) GetServices() []string {
if x != nil {
return x.Services
}
return nil
}
func (x *ExportedServices) GetConsumers() []*ExportedServicesConsumer {
if x != nil {
return x.Consumers
}
return nil
}
var File_pbmulticluster_v2_exported_services_proto protoreflect.FileDescriptor
var file_pbmulticluster_v2_exported_services_proto_rawDesc = []byte{
0x0a, 0x29, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
0x2f, 0x76, 0x32, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75,
0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x1a, 0x32, 0x70,
0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32,
0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e,
0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0x90, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
0x12, 0x58, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73,
0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52,
0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02,
0x08, 0x03, 0x42, 0xab, 0x02, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74,
0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x42, 0x15, 0x45, 0x78, 0x70,
0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f,
0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 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, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70,
0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32,
0x3b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0xa2,
0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c,
0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74,
0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x2c, 0x48, 0x61,
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d,
0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x5c, 0x47,
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a,
0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x32,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pbmulticluster_v2_exported_services_proto_rawDescOnce sync.Once
file_pbmulticluster_v2_exported_services_proto_rawDescData = file_pbmulticluster_v2_exported_services_proto_rawDesc
)
func file_pbmulticluster_v2_exported_services_proto_rawDescGZIP() []byte {
file_pbmulticluster_v2_exported_services_proto_rawDescOnce.Do(func() {
file_pbmulticluster_v2_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2_exported_services_proto_rawDescData)
})
return file_pbmulticluster_v2_exported_services_proto_rawDescData
}
var file_pbmulticluster_v2_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_pbmulticluster_v2_exported_services_proto_goTypes = []interface{}{
(*ExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2.ExportedServices
(*ExportedServicesConsumer)(nil), // 1: hashicorp.consul.multicluster.v2.ExportedServicesConsumer
}
var file_pbmulticluster_v2_exported_services_proto_depIdxs = []int32{
1, // 0: hashicorp.consul.multicluster.v2.ExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2.ExportedServicesConsumer
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_pbmulticluster_v2_exported_services_proto_init() }
func file_pbmulticluster_v2_exported_services_proto_init() {
if File_pbmulticluster_v2_exported_services_proto != nil {
return
}
file_pbmulticluster_v2_exported_services_consumer_proto_init()
if !protoimpl.UnsafeEnabled {
file_pbmulticluster_v2_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExportedServices); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pbmulticluster_v2_exported_services_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_pbmulticluster_v2_exported_services_proto_goTypes,
DependencyIndexes: file_pbmulticluster_v2_exported_services_proto_depIdxs,
MessageInfos: file_pbmulticluster_v2_exported_services_proto_msgTypes,
}.Build()
File_pbmulticluster_v2_exported_services_proto = out.File
file_pbmulticluster_v2_exported_services_proto_rawDesc = nil
file_pbmulticluster_v2_exported_services_proto_goTypes = nil
file_pbmulticluster_v2_exported_services_proto_depIdxs = nil
}

@ -3,9 +3,9 @@
syntax = "proto3";
package hashicorp.consul.multicluster.v2beta1;
package hashicorp.consul.multicluster.v2;
import "pbmulticluster/v2beta1/exported_services_consumer.proto";
import "pbmulticluster/v2/exported_services_consumer.proto";
import "pbresource/annotations.proto";
message ExportedServices {

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-binary. DO NOT EDIT.
// source: pbmulticluster/v2beta1/exported_services_consumer.proto
// source: pbmulticluster/v2/exported_services_consumer.proto
package multiclusterv2beta1
package multiclusterv2
import (
"google.golang.org/protobuf/proto"

@ -0,0 +1,230 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: pbmulticluster/v2/exported_services_consumer.proto
package multiclusterv2
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// +kubebuilder:validation:Type=object
// +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields
type ExportedServicesConsumer struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Types that are assignable to ConsumerTenancy:
//
// *ExportedServicesConsumer_Peer
// *ExportedServicesConsumer_Partition
// *ExportedServicesConsumer_SamenessGroup
ConsumerTenancy isExportedServicesConsumer_ConsumerTenancy `protobuf_oneof:"consumer_tenancy"`
}
func (x *ExportedServicesConsumer) Reset() {
*x = ExportedServicesConsumer{}
if protoimpl.UnsafeEnabled {
mi := &file_pbmulticluster_v2_exported_services_consumer_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ExportedServicesConsumer) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ExportedServicesConsumer) ProtoMessage() {}
func (x *ExportedServicesConsumer) ProtoReflect() protoreflect.Message {
mi := &file_pbmulticluster_v2_exported_services_consumer_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ExportedServicesConsumer.ProtoReflect.Descriptor instead.
func (*ExportedServicesConsumer) Descriptor() ([]byte, []int) {
return file_pbmulticluster_v2_exported_services_consumer_proto_rawDescGZIP(), []int{0}
}
func (m *ExportedServicesConsumer) GetConsumerTenancy() isExportedServicesConsumer_ConsumerTenancy {
if m != nil {
return m.ConsumerTenancy
}
return nil
}
func (x *ExportedServicesConsumer) GetPeer() string {
if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_Peer); ok {
return x.Peer
}
return ""
}
func (x *ExportedServicesConsumer) GetPartition() string {
if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_Partition); ok {
return x.Partition
}
return ""
}
func (x *ExportedServicesConsumer) GetSamenessGroup() string {
if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_SamenessGroup); ok {
return x.SamenessGroup
}
return ""
}
type isExportedServicesConsumer_ConsumerTenancy interface {
isExportedServicesConsumer_ConsumerTenancy()
}
type ExportedServicesConsumer_Peer struct {
Peer string `protobuf:"bytes,1,opt,name=peer,proto3,oneof"`
}
type ExportedServicesConsumer_Partition struct {
Partition string `protobuf:"bytes,2,opt,name=partition,proto3,oneof"`
}
type ExportedServicesConsumer_SamenessGroup struct {
SamenessGroup string `protobuf:"bytes,3,opt,name=sameness_group,json=samenessGroup,proto3,oneof"`
}
func (*ExportedServicesConsumer_Peer) isExportedServicesConsumer_ConsumerTenancy() {}
func (*ExportedServicesConsumer_Partition) isExportedServicesConsumer_ConsumerTenancy() {}
func (*ExportedServicesConsumer_SamenessGroup) isExportedServicesConsumer_ConsumerTenancy() {}
var File_pbmulticluster_v2_exported_services_consumer_proto protoreflect.FileDescriptor
var file_pbmulticluster_v2_exported_services_consumer_proto_rawDesc = []byte{
0x0a, 0x32, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
0x2f, 0x76, 0x32, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73,
0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x22, 0x8d, 0x01, 0x0a, 0x18, 0x45, 0x78, 0x70, 0x6f, 0x72,
0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75,
0x6d, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x48, 0x00, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x09, 0x70, 0x61, 0x72,
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09,
0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0e, 0x73, 0x61, 0x6d,
0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f,
0x75, 0x70, 0x42, 0x12, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x5f, 0x74,
0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x42, 0xb3, 0x02, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x68,
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x42,
0x1d, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
0x5a, 0x49, 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, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c,
0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x3b, 0x6d, 0x75, 0x6c,
0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x48, 0x43,
0x4d, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f,
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
0x72, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75,
0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63,
0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69,
0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74,
0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pbmulticluster_v2_exported_services_consumer_proto_rawDescOnce sync.Once
file_pbmulticluster_v2_exported_services_consumer_proto_rawDescData = file_pbmulticluster_v2_exported_services_consumer_proto_rawDesc
)
func file_pbmulticluster_v2_exported_services_consumer_proto_rawDescGZIP() []byte {
file_pbmulticluster_v2_exported_services_consumer_proto_rawDescOnce.Do(func() {
file_pbmulticluster_v2_exported_services_consumer_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2_exported_services_consumer_proto_rawDescData)
})
return file_pbmulticluster_v2_exported_services_consumer_proto_rawDescData
}
var file_pbmulticluster_v2_exported_services_consumer_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_pbmulticluster_v2_exported_services_consumer_proto_goTypes = []interface{}{
(*ExportedServicesConsumer)(nil), // 0: hashicorp.consul.multicluster.v2.ExportedServicesConsumer
}
var file_pbmulticluster_v2_exported_services_consumer_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_pbmulticluster_v2_exported_services_consumer_proto_init() }
func file_pbmulticluster_v2_exported_services_consumer_proto_init() {
if File_pbmulticluster_v2_exported_services_consumer_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_pbmulticluster_v2_exported_services_consumer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExportedServicesConsumer); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_pbmulticluster_v2_exported_services_consumer_proto_msgTypes[0].OneofWrappers = []interface{}{
(*ExportedServicesConsumer_Peer)(nil),
(*ExportedServicesConsumer_Partition)(nil),
(*ExportedServicesConsumer_SamenessGroup)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pbmulticluster_v2_exported_services_consumer_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_pbmulticluster_v2_exported_services_consumer_proto_goTypes,
DependencyIndexes: file_pbmulticluster_v2_exported_services_consumer_proto_depIdxs,
MessageInfos: file_pbmulticluster_v2_exported_services_consumer_proto_msgTypes,
}.Build()
File_pbmulticluster_v2_exported_services_consumer_proto = out.File
file_pbmulticluster_v2_exported_services_consumer_proto_rawDesc = nil
file_pbmulticluster_v2_exported_services_consumer_proto_goTypes = nil
file_pbmulticluster_v2_exported_services_consumer_proto_depIdxs = nil
}

@ -3,7 +3,7 @@
syntax = "proto3";
package hashicorp.consul.multicluster.v2beta1;
package hashicorp.consul.multicluster.v2;
// +kubebuilder:validation:Type=object
// +kubebuilder:validation:Schemaless

@ -1,5 +1,5 @@
// Code generated by protoc-gen-deepcopy. DO NOT EDIT.
package multiclusterv2beta1
package multiclusterv2
import (
proto "google.golang.org/protobuf/proto"

@ -1,5 +1,5 @@
// Code generated by protoc-json-shim. DO NOT EDIT.
package multiclusterv2beta1
package multiclusterv2
import (
protojson "google.golang.org/protobuf/encoding/protojson"

@ -1,5 +1,5 @@
// Code generated by protoc-gen-deepcopy. DO NOT EDIT.
package multiclusterv2beta1
package multiclusterv2
import (
proto "google.golang.org/protobuf/proto"

@ -1,5 +1,5 @@
// Code generated by protoc-json-shim. DO NOT EDIT.
package multiclusterv2beta1
package multiclusterv2
import (
protojson "google.golang.org/protobuf/encoding/protojson"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save