diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go b/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go index ec173b6e7e..a10c2d0682 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go @@ -89,7 +89,9 @@ func (b *Builder) NewListenerBuilder(l *pbproxystate.Listener) *ListenerBuilder } func (l *ListenerBuilder) buildListener() { - l.builder.proxyStateTemplate.ProxyState.Listeners = append(l.builder.proxyStateTemplate.ProxyState.Listeners, l.listener) + if l.listener != nil { + l.builder.proxyStateTemplate.ProxyState.Listeners = append(l.builder.proxyStateTemplate.ProxyState.Listeners, l.listener) + } } type RouterBuilder struct { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder_multiport_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go similarity index 100% rename from internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder_multiport_test.go rename to internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go similarity index 100% rename from internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder.go rename to internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destinations_test.go similarity index 100% rename from internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder_test.go rename to internal/mesh/internal/controllers/sidecarproxy/builder/destinations_test.go diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go b/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go new file mode 100644 index 0000000000..3553ea02f0 --- /dev/null +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go @@ -0,0 +1,131 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package builder + +import ( + "fmt" + "regexp" + + 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" +) + +func (b *Builder) buildExposePaths(workload *pbcatalog.Workload) { + if b.proxyCfg.GetDynamicConfig() != nil && b.proxyCfg.GetDynamicConfig().GetExposeConfig() != nil { + for _, exposePath := range b.proxyCfg.GetDynamicConfig().GetExposeConfig().GetExposePaths() { + clusterName := exposePathClusterName(exposePath) + + b.addExposePathsListener(workload, exposePath). + addExposePathsRouter(exposePath). + buildListener() + + b.addExposePathsRoute(exposePath, clusterName). + addLocalAppCluster(clusterName). + addLocalAppStaticEndpoints(clusterName, exposePath.LocalPathPort) + } + } +} + +func (b *Builder) addExposePathsListener(workload *pbcatalog.Workload, exposePath *pbmesh.ExposePath) *ListenerBuilder { + listenerName := fmt.Sprintf("exposed_path_%s", exposePathName(exposePath)) + + listener := &pbproxystate.Listener{ + Name: listenerName, + Direction: pbproxystate.Direction_DIRECTION_INBOUND, + } + + meshAddress := workload.GetFirstNonExternalMeshAddress() + if meshAddress == nil { + return b.NewListenerBuilder(nil) + } + + listener.BindAddress = &pbproxystate.Listener_HostPort{ + HostPort: &pbproxystate.HostPortAddress{ + Host: meshAddress.Host, + Port: exposePath.LocalPathPort, + }, + } + + return b.NewListenerBuilder(listener) +} + +func (b *ListenerBuilder) addExposePathsRouter(exposePath *pbmesh.ExposePath) *ListenerBuilder { + if b.listener == nil { + return b + } + destinationName := exposePathDestinationName(exposePath) + + var l7Protocol pbproxystate.L7Protocol + + switch exposePath.Protocol { + case pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP: + l7Protocol = pbproxystate.L7Protocol_L7_PROTOCOL_HTTP + case pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2: + l7Protocol = pbproxystate.L7Protocol_L7_PROTOCOL_HTTP2 + default: + panic("unsupported expose paths protocol") + } + routerDestination := &pbproxystate.Router_L7{ + L7: &pbproxystate.L7Destination{ + Name: destinationName, + StatPrefix: destinationName, + StaticRoute: true, + Protocol: l7Protocol, + }, + } + + router := &pbproxystate.Router{ + Destination: routerDestination, + } + + b.listener.Routers = append(b.listener.Routers, router) + + return b +} + +func (b *Builder) addExposePathsRoute(exposePath *pbmesh.ExposePath, clusterName string) *Builder { + routeName := exposePathDestinationName(exposePath) + routeRule := &pbproxystate.RouteRule{ + Match: &pbproxystate.RouteMatch{ + PathMatch: &pbproxystate.PathMatch{ + PathMatch: &pbproxystate.PathMatch_Exact{ + Exact: exposePath.Path, + }, + }, + }, + Destination: &pbproxystate.RouteDestination{ + Destination: &pbproxystate.RouteDestination_Cluster{ + Cluster: &pbproxystate.DestinationCluster{ + Name: clusterName, + }, + }, + }, + } + virtualHost := &pbproxystate.VirtualHost{ + Name: routeName, + Domains: []string{"*"}, + RouteRules: []*pbproxystate.RouteRule{routeRule}, + } + route := &pbproxystate.Route{ + VirtualHosts: []*pbproxystate.VirtualHost{virtualHost}, + } + + b.proxyStateTemplate.ProxyState.Routes[routeName] = route + return b +} + +func exposePathName(exposePath *pbmesh.ExposePath) string { + r := regexp.MustCompile(`[^a-zA-Z0-9]+`) + return r.ReplaceAllString(exposePath.Path, "") +} + +func exposePathDestinationName(exposePath *pbmesh.ExposePath) string { + path := exposePathName(exposePath) + return fmt.Sprintf("exposed_path_filter_%s_%d", path, exposePath.ListenerPort) +} + +func exposePathClusterName(exposePath *pbmesh.ExposePath) string { + return fmt.Sprintf("exposed_cluster_%d", exposePath.LocalPathPort) +} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths_test.go new file mode 100644 index 0000000000..e75f65ed89 --- /dev/null +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths_test.go @@ -0,0 +1,103 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package builder + +import ( + "testing" + + "github.com/stretchr/testify/require" + + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/sdk/testutil" +) + +// This file contains tests only for error and edge cases cases. The happy case is tested in local_app_test.go + +func TestBuildExposePaths_NilChecks(t *testing.T) { + testutil.RunStep(t, "proxy cfg is nil", func(t *testing.T) { + b := New(nil, nil, "foo.consul", "dc1", true, nil) + require.NotPanics(t, func() { + b.buildExposePaths(nil) + }) + }) + + testutil.RunStep(t, "dynamic cfg is nil", func(t *testing.T) { + b := New(nil, nil, "foo.consul", "dc1", true, &pbmesh.ProxyConfiguration{}) + require.NotPanics(t, func() { + b.buildExposePaths(nil) + }) + }) + + testutil.RunStep(t, "expose cfg is nil", func(t *testing.T) { + b := New(nil, nil, "foo.consul", "dc1", true, &pbmesh.ProxyConfiguration{ + DynamicConfig: &pbmesh.DynamicConfig{}, + }) + require.NotPanics(t, func() { + b.buildExposePaths(nil) + }) + }) +} + +func TestBuildExposePaths_NoExternalMeshWorkloadAddress(t *testing.T) { + workload := &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1", External: true}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + "mesh": {Port: 20000}, + }, + } + + proxycfg := &pbmesh.ProxyConfiguration{ + DynamicConfig: &pbmesh.DynamicConfig{ + ExposeConfig: &pbmesh.ExposeConfig{ + ExposePaths: []*pbmesh.ExposePath{ + { + ListenerPort: 1234, + LocalPathPort: 9090, + Path: "/health", + }, + }, + }, + }, + } + + b := New(nil, nil, "foo.consul", "dc1", true, proxycfg) + b.buildExposePaths(workload) + require.Empty(t, b.proxyStateTemplate.ProxyState.Listeners) +} + +func TestBuildExposePaths_InvalidProtocol(t *testing.T) { + workload := &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, + }, + } + + proxycfg := &pbmesh.ProxyConfiguration{ + DynamicConfig: &pbmesh.DynamicConfig{ + ExposeConfig: &pbmesh.ExposeConfig{ + ExposePaths: []*pbmesh.ExposePath{ + { + ListenerPort: 1234, + LocalPathPort: 9090, + Path: "/health", + Protocol: 3, + }, + }, + }, + }, + } + + b := New(nil, nil, "foo.consul", "dc1", true, proxycfg) + require.PanicsWithValue(t, "unsupported expose paths protocol", func() { + b.buildExposePaths(workload) + }) +} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go index 3313b3ffae..1160321ac7 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go @@ -34,10 +34,12 @@ func (b *Builder) BuildLocalApp(workload *pbcatalog.Workload, ctp *pbauth.Comput addInboundTLS() b.addLocalAppCluster(clusterName). - addLocalAppStaticEndpoints(clusterName, port) + addLocalAppStaticEndpoints(clusterName, port.GetPort()) } } + b.buildExposePaths(workload) + // If there are no inbound ports other than the mesh port, we black-hole all inbound traffic. if !foundInboundNonMeshPorts { lb.addBlackHoleRouter() @@ -341,22 +343,20 @@ func (b *Builder) addBlackHoleCluster() *Builder { return b } -func (b *Builder) addLocalAppStaticEndpoints(clusterName string, port *pbcatalog.WorkloadPort) *Builder { +func (b *Builder) addLocalAppStaticEndpoints(clusterName string, port uint32) { // We're adding endpoints statically as opposed to creating an endpoint ref // because this endpoint is less likely to change as we're not tracking the health. endpoint := &pbproxystate.Endpoint{ Address: &pbproxystate.Endpoint_HostPort{ HostPort: &pbproxystate.HostPortAddress{ Host: "127.0.0.1", - Port: port.Port, + Port: port, }, }, } b.proxyStateTemplate.ProxyState.Endpoints[clusterName] = &pbproxystate.Endpoints{ Endpoints: []*pbproxystate.Endpoint{endpoint}, } - - return b } func (l *ListenerBuilder) addInboundTLS() *ListenerBuilder { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go index 2b117155ab..b6608f3608 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go @@ -101,21 +101,57 @@ func TestBuildLocalApp(t *testing.T) { } } -func testProxyStateTemplateID() *pbresource.ID { - return resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() -} - -func testIdentityRef() *pbresource.Reference { - return &pbresource.Reference{ - Name: "test-identity", - Tenancy: &pbresource.Tenancy{ - Namespace: "default", - Partition: "default", - PeerName: "local", +func TestBuildLocalApp_WithProxyConfiguration(t *testing.T) { + cases := map[string]struct { + workload *pbcatalog.Workload + proxyCfg *pbmesh.ProxyConfiguration + }{ + "source/l7-expose-paths": { + workload: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + { + Host: "10.0.0.1", + }, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, + "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, + }, + }, + proxyCfg: &pbmesh.ProxyConfiguration{ + DynamicConfig: &pbmesh.DynamicConfig{ + ExposeConfig: &pbmesh.ExposeConfig{ + ExposePaths: []*pbmesh.ExposePath{ + { + ListenerPort: 1234, + Path: "/health", + LocalPathPort: 9090, + Protocol: pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP, + }, + { + ListenerPort: 1235, + Path: "GetHealth", + LocalPathPort: 9091, + Protocol: pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2, + }, + }, + }, + }, + }, }, } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, c.proxyCfg). + BuildLocalApp(c.workload, nil). + Build() + actual := protoToJSON(t, proxyTmpl) + expected := golden.Get(t, actual, name+".golden") + + require.JSONEq(t, expected, actual) + }) + } } func TestBuildL4TrafficPermissions(t *testing.T) { @@ -437,3 +473,20 @@ func TestBuildL4TrafficPermissions(t *testing.T) { }) } } + +func testProxyStateTemplateID() *pbresource.ID { + return resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test"). + WithTenancy(resource.DefaultNamespacedTenancy()). + ID() +} + +func testIdentityRef() *pbresource.Reference { + return &pbresource.Reference{ + Name: "test-identity", + Tenancy: &pbresource.Tenancy{ + Namespace: "default", + Partition: "default", + PeerName: "local", + }, + } +} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-multiple-implicit-destinations-tproxy.golden index 53aacf8944..9a22fba0f1 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-multiple-implicit-destinations-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-multiple-implicit-destinations-tproxy.golden @@ -1,16 +1,6 @@ { "proxyState": { "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination" - }, "http.api-app.default.dc1.internal.foo.consul": { "altStatName": "http.api-app.default.dc1.internal.foo.consul", "endpointGroup": { @@ -65,6 +55,16 @@ }, "name": "http.api-app2.default.dc1.internal.foo.consul" }, + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination" + }, "tcp.api-app.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-tproxy.golden index 11d37d6b19..7694588797 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-tproxy.golden @@ -1,16 +1,6 @@ { "proxyState": { "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination" - }, "http.api-app.default.dc1.internal.foo.consul": { "altStatName": "http.api-app.default.dc1.internal.foo.consul", "endpointGroup": { @@ -38,6 +28,16 @@ }, "name": "http.api-app.default.dc1.internal.foo.consul" }, + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination" + }, "tcp.api-app.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-with-multiple-workloads-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-with-multiple-workloads-tproxy.golden index 11d37d6b19..7694588797 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -1,16 +1,6 @@ { "proxyState": { "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination" - }, "http.api-app.default.dc1.internal.foo.consul": { "altStatName": "http.api-app.default.dc1.internal.foo.consul", "endpointGroup": { @@ -38,6 +28,16 @@ }, "name": "http.api-app.default.dc1.internal.foo.consul" }, + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination" + }, "tcp.api-app.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden new file mode 100644 index 0000000000..a282a25342 --- /dev/null +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden @@ -0,0 +1,200 @@ +{ + "proxyState": { + "clusters": { + "exposed_cluster_9090": { + "endpointGroup": { + "static": {} + }, + "name": "exposed_cluster_9090" + }, + "exposed_cluster_9091": { + "endpointGroup": { + "static": {} + }, + "name": "exposed_cluster_9091" + }, + "local_app:port1": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:port1" + } + }, + "endpoints": { + "exposed_cluster_9090": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + }, + "exposed_cluster_9091": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9091 + } + } + ] + }, + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + } + }, + "listeners": [ + { + "capabilities": [ + "CAPABILITY_L4_TLS_INSPECTION" + ], + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:port1" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + } + ] + }, + { + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 9090 + }, + "name": "exposed_path_health", + "routers": [ + { + "l7": { + "name": "exposed_path_filter_health_1234", + "statPrefix": "exposed_path_filter_health_1234", + "staticRoute": true + } + } + ] + }, + { + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 9091 + }, + "name": "exposed_path_GetHealth", + "routers": [ + { + "l7": { + "name": "exposed_path_filter_GetHealth_1235", + "protocol": "L7_PROTOCOL_HTTP2", + "statPrefix": "exposed_path_filter_GetHealth_1235", + "staticRoute": true + } + } + ] + } + ], + "routes": { + "exposed_path_filter_GetHealth_1235": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "exposed_path_filter_GetHealth_1235", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "exposed_cluster_9091" + } + }, + "match": { + "pathMatch": { + "exact": "GetHealth" + } + } + } + ] + } + ] + }, + "exposed_path_filter_health_1234": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "exposed_path_filter_health_1234", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "exposed_cluster_9090" + } + }, + "match": { + "pathMatch": { + "exact": "/health" + } + } + } + ] + } + ] + } + } + }, + "requiredLeafCertificates": { + "test-identity": { + "name": "test-identity", + "namespace": "default", + "partition": "default" + } + }, + "requiredTrustBundles": { + "local": { + "peer": "local" + } + } +} \ No newline at end of file diff --git a/proto-public/pbcatalog/v2beta1/workload_addon.go b/proto-public/pbcatalog/v2beta1/workload_addon.go index 463e4eaa22..d09ef61454 100644 --- a/proto-public/pbcatalog/v2beta1/workload_addon.go +++ b/proto-public/pbcatalog/v2beta1/workload_addon.go @@ -5,7 +5,7 @@ import "golang.org/x/exp/slices" func (w *Workload) GetMeshPortName() (string, bool) { var meshPort string - for portName, port := range w.Ports { + for portName, port := range w.GetPorts() { if port.Protocol == Protocol_PROTOCOL_MESH { meshPort = portName return meshPort, true @@ -23,15 +23,20 @@ func (w *Workload) IsMeshEnabled() bool { func (w *Workload) GetNonExternalAddressesForPort(portName string) []*WorkloadAddress { var addresses []*WorkloadAddress - for _, address := range w.Addresses { - if address.External { + // If this port doesn't exist on a workload, return nil. + if _, ok := w.GetPorts()[portName]; !ok { + return nil + } + + for _, address := range w.GetAddresses() { + if address.GetExternal() { // Skip external addresses. continue } // If there are no ports, that means this port is selected. // Otherwise, check if the port is explicitly selected by this address - if len(address.Ports) == 0 || slices.Contains(address.Ports, portName) { + if len(address.Ports) == 0 || slices.Contains(address.GetPorts(), portName) { addresses = append(addresses, address) } } @@ -39,13 +44,32 @@ func (w *Workload) GetNonExternalAddressesForPort(portName string) []*WorkloadAd return addresses } +func (w *Workload) GetFirstNonExternalMeshAddress() *WorkloadAddress { + // Find mesh port. + meshPort, ok := w.GetMeshPortName() + if !ok { + return nil + } + + // Check if the workload has a specific address for the mesh port. + meshAddresses := w.GetNonExternalAddressesForPort(meshPort) + + // If there are no mesh addresses, return. This should be impossible. + if len(meshAddresses) == 0 { + return nil + } + + // If there are more than one mesh address, use the first one in the list. + return meshAddresses[0] +} + func (w *Workload) GetPortsByProtocol() map[Protocol][]string { if w == nil { return nil } - out := make(map[Protocol][]string, len(w.Ports)) - for name, port := range w.Ports { + out := make(map[Protocol][]string, len(w.GetPorts())) + for name, port := range w.GetPorts() { out[port.GetProtocol()] = append(out[port.GetProtocol()], name) } diff --git a/proto-public/pbcatalog/v2beta1/workload_addon_test.go b/proto-public/pbcatalog/v2beta1/workload_addon_test.go index 9ce7f9c1db..e8e5264fa4 100644 --- a/proto-public/pbcatalog/v2beta1/workload_addon_test.go +++ b/proto-public/pbcatalog/v2beta1/workload_addon_test.go @@ -1,6 +1,7 @@ package catalogv2beta1 import ( + "sort" "testing" "github.com/stretchr/testify/require" @@ -50,27 +51,71 @@ func TestGetMeshPort(t *testing.T) { } } +func TestIsMeshEnabled(t *testing.T) { + cases := map[string]struct { + ports map[string]*WorkloadPort + exp bool + }{ + "no ports": { + ports: nil, + exp: false, + }, + "no mesh": { + ports: map[string]*WorkloadPort{ + "p1": {Port: 8080}, + "p2": {Port: 8081}, + }, + exp: false, + }, + "with mesh": { + ports: map[string]*WorkloadPort{ + "p1": {Port: 8080}, + "p2": {Port: 8081, Protocol: Protocol_PROTOCOL_MESH}, + }, + exp: false, + }, + } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + w := &Workload{ + Ports: c.ports, + } + require.Equal(t, c.exp, w.IsMeshEnabled()) + }) + } +} + func TestGetAddressesForPort(t *testing.T) { cases := map[string]struct { addresses []*WorkloadAddress + ports map[string]*WorkloadPort portName string expAddresses []*WorkloadAddress }{ "empty addresses": { addresses: nil, + ports: nil, portName: "doesn't matter", expAddresses: nil, }, "addresses without selected port": { addresses: []*WorkloadAddress{{Host: "1.1.1.1"}}, + ports: nil, portName: "not-found", expAddresses: nil, }, - "single selected addresses": { + "single selected address": { addresses: []*WorkloadAddress{ {Host: "1.1.1.1", Ports: []string{"p1", "p2"}}, {Host: "2.2.2.2", Ports: []string{"p3", "p4"}}, }, + ports: map[string]*WorkloadPort{ + "p1": {Port: 8080}, + "p2": {Port: 8081}, + "p3": {Port: 8082}, + "p4": {Port: 8083}, + }, portName: "p1", expAddresses: []*WorkloadAddress{ {Host: "1.1.1.1", Ports: []string{"p1", "p2"}}, @@ -83,6 +128,12 @@ func TestGetAddressesForPort(t *testing.T) { {Host: "3.3.3.3"}, {Host: "3.3.3.3", Ports: []string{"p1"}, External: true}, }, + ports: map[string]*WorkloadPort{ + "p1": {Port: 8080}, + "p2": {Port: 8081}, + "p3": {Port: 8082}, + "p4": {Port: 8083}, + }, portName: "p1", expAddresses: []*WorkloadAddress{ {Host: "1.1.1.1", Ports: []string{"p1", "p2"}}, @@ -95,10 +146,114 @@ func TestGetAddressesForPort(t *testing.T) { t.Run(name, func(t *testing.T) { workload := Workload{ Addresses: c.addresses, + Ports: c.ports, } actualAddresses := workload.GetNonExternalAddressesForPort(c.portName) - require.Equal(t, actualAddresses, c.expAddresses) + require.Equal(t, c.expAddresses, actualAddresses) + }) + } +} + +func TestGetFirstNonExternalMeshAddress(t *testing.T) { + cases := map[string]struct { + workload *Workload + expAddress *WorkloadAddress + }{ + "empty addresses": { + workload: &Workload{}, + expAddress: nil, + }, + "no mesh port": { + workload: &Workload{ + Addresses: []*WorkloadAddress{{Host: "1.1.1.1"}}, + Ports: map[string]*WorkloadPort{ + "tcp": {Port: 8080}, + }, + }, + expAddress: nil, + }, + "only external mesh ports": { + workload: &Workload{ + Addresses: []*WorkloadAddress{{Host: "1.1.1.1", External: true}}, + Ports: map[string]*WorkloadPort{ + "mesh": {Port: 8080, Protocol: Protocol_PROTOCOL_MESH}, + }, + }, + expAddress: nil, + }, + "only external and internal mesh ports": { + workload: &Workload{ + Addresses: []*WorkloadAddress{ + {Host: "1.1.1.1"}, + {Host: "2.2.2.2", External: true}, + }, + Ports: map[string]*WorkloadPort{ + "mesh": {Port: 8080, Protocol: Protocol_PROTOCOL_MESH}, + }, + }, + expAddress: &WorkloadAddress{Host: "1.1.1.1"}, + }, + "multiple internal addresses for mesh port": { + workload: &Workload{ + Addresses: []*WorkloadAddress{ + {Host: "1.1.1.1"}, + {Host: "2.2.2.2", External: true}, + {Host: "3.3.3.3"}, + }, + Ports: map[string]*WorkloadPort{ + "mesh": {Port: 8080, Protocol: Protocol_PROTOCOL_MESH}, + }, + }, + expAddress: &WorkloadAddress{Host: "1.1.1.1"}, + }, + } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + actualAddress := c.workload.GetFirstNonExternalMeshAddress() + require.Equal(t, actualAddress, c.expAddress) + }) + } +} + +func TestGetPortsByProtocol(t *testing.T) { + cases := map[string]struct { + w *Workload + exp map[Protocol][]string + }{ + "nil": { + w: nil, + exp: nil, + }, + "ports with protocols": { + w: &Workload{ + Ports: map[string]*WorkloadPort{ + "p1": {Port: 8080, Protocol: Protocol_PROTOCOL_TCP}, + "p2": {Port: 8081, Protocol: Protocol_PROTOCOL_HTTP}, + "p3": {Port: 8082, Protocol: Protocol_PROTOCOL_HTTP2}, + "p4": {Port: 8083, Protocol: Protocol_PROTOCOL_TCP}, + "p5": {Port: 8084, Protocol: Protocol_PROTOCOL_MESH}, + "p6": {Port: 8085, Protocol: Protocol_PROTOCOL_MESH}, + }, + }, + exp: map[Protocol][]string{ + Protocol_PROTOCOL_TCP: {"p1", "p4"}, + Protocol_PROTOCOL_HTTP: {"p2"}, + Protocol_PROTOCOL_HTTP2: {"p3"}, + Protocol_PROTOCOL_MESH: {"p5", "p6"}, + }, + }, + } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + portsByProtocol := c.w.GetPortsByProtocol() + for protocol, ports := range portsByProtocol { + sort.Strings(ports) + portsByProtocol[protocol] = ports + } + require.Equal(t, c.exp, portsByProtocol) }) } } diff --git a/proto-public/pbmesh/v2beta1/expose.pb.go b/proto-public/pbmesh/v2beta1/expose.pb.go index 48224fb6ab..2413168436 100644 --- a/proto-public/pbmesh/v2beta1/expose.pb.go +++ b/proto-public/pbmesh/v2beta1/expose.pb.go @@ -10,7 +10,6 @@ package meshv2beta1 import ( - v2beta1 "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -24,6 +23,53 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type ExposePathProtocol int32 + +const ( + // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX + ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP ExposePathProtocol = 0 + ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2 ExposePathProtocol = 1 +) + +// Enum value maps for ExposePathProtocol. +var ( + ExposePathProtocol_name = map[int32]string{ + 0: "EXPOSE_PATH_PROTOCOL_HTTP", + 1: "EXPOSE_PATH_PROTOCOL_HTTP2", + } + ExposePathProtocol_value = map[string]int32{ + "EXPOSE_PATH_PROTOCOL_HTTP": 0, + "EXPOSE_PATH_PROTOCOL_HTTP2": 1, + } +) + +func (x ExposePathProtocol) Enum() *ExposePathProtocol { + p := new(ExposePathProtocol) + *p = x + return p +} + +func (x ExposePathProtocol) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExposePathProtocol) Descriptor() protoreflect.EnumDescriptor { + return file_pbmesh_v2beta1_expose_proto_enumTypes[0].Descriptor() +} + +func (ExposePathProtocol) Type() protoreflect.EnumType { + return &file_pbmesh_v2beta1_expose_proto_enumTypes[0] +} + +func (x ExposePathProtocol) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ExposePathProtocol.Descriptor instead. +func (ExposePathProtocol) EnumDescriptor() ([]byte, []int) { + return file_pbmesh_v2beta1_expose_proto_rawDescGZIP(), []int{0} +} + type ExposeConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -76,10 +122,10 @@ type ExposePath struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ListenerPort uint32 `protobuf:"varint,1,opt,name=listener_port,json=listenerPort,proto3" json:"listener_port,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` - LocalPathPort uint32 `protobuf:"varint,3,opt,name=local_path_port,json=localPathPort,proto3" json:"local_path_port,omitempty"` - Protocol v2beta1.Protocol `protobuf:"varint,4,opt,name=protocol,proto3,enum=hashicorp.consul.catalog.v2beta1.Protocol" json:"protocol,omitempty"` + ListenerPort uint32 `protobuf:"varint,1,opt,name=listener_port,json=listenerPort,proto3" json:"listener_port,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + LocalPathPort uint32 `protobuf:"varint,3,opt,name=local_path_port,json=localPathPort,proto3" json:"local_path_port,omitempty"` + Protocol ExposePathProtocol `protobuf:"varint,4,opt,name=protocol,proto3,enum=hashicorp.consul.mesh.v2beta1.ExposePathProtocol" json:"protocol,omitempty"` } func (x *ExposePath) Reset() { @@ -135,11 +181,11 @@ func (x *ExposePath) GetLocalPathPort() uint32 { return 0 } -func (x *ExposePath) GetProtocol() v2beta1.Protocol { +func (x *ExposePath) GetProtocol() ExposePathProtocol { if x != nil { return x.Protocol } - return v2beta1.Protocol(0) + return ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP } var File_pbmesh_v2beta1_expose_proto protoreflect.FileDescriptor @@ -148,44 +194,48 @@ var file_pbmesh_v2beta1_expose_proto_rawDesc = []byte{ 0x0a, 0x1b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x20, 0x70, 0x62, - 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5c, - 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4c, - 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x22, 0x5c, 0x0a, 0x0c, + 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4c, 0x0a, 0x0c, + 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0b, 0x65, + 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, 0xbc, 0x01, 0x0a, 0x0a, 0x45, + 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x4d, 0x0a, 0x08, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, + 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, + 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2a, 0x53, 0x0a, 0x12, 0x45, 0x78, 0x70, + 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, + 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x50, + 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x1e, + 0x0a, 0x1a, 0x45, 0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x50, 0x52, + 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x01, 0x42, 0x8c, + 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, - 0x0b, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, 0xb5, 0x01, 0x0a, - 0x0a, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x6c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x46, 0x0a, 0x08, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x42, 0x8c, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0b, 0x45, 0x78, 0x70, 0x6f, - 0x73, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 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, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, - 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x74, 0x61, 0x31, 0x42, 0x0b, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x43, 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, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, + 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, + 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, + 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, + 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, + 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -200,15 +250,16 @@ func file_pbmesh_v2beta1_expose_proto_rawDescGZIP() []byte { return file_pbmesh_v2beta1_expose_proto_rawDescData } +var file_pbmesh_v2beta1_expose_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_pbmesh_v2beta1_expose_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_pbmesh_v2beta1_expose_proto_goTypes = []interface{}{ - (*ExposeConfig)(nil), // 0: hashicorp.consul.mesh.v2beta1.ExposeConfig - (*ExposePath)(nil), // 1: hashicorp.consul.mesh.v2beta1.ExposePath - (v2beta1.Protocol)(0), // 2: hashicorp.consul.catalog.v2beta1.Protocol + (ExposePathProtocol)(0), // 0: hashicorp.consul.mesh.v2beta1.ExposePathProtocol + (*ExposeConfig)(nil), // 1: hashicorp.consul.mesh.v2beta1.ExposeConfig + (*ExposePath)(nil), // 2: hashicorp.consul.mesh.v2beta1.ExposePath } var file_pbmesh_v2beta1_expose_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.mesh.v2beta1.ExposeConfig.expose_paths:type_name -> hashicorp.consul.mesh.v2beta1.ExposePath - 2, // 1: hashicorp.consul.mesh.v2beta1.ExposePath.protocol:type_name -> hashicorp.consul.catalog.v2beta1.Protocol + 2, // 0: hashicorp.consul.mesh.v2beta1.ExposeConfig.expose_paths:type_name -> hashicorp.consul.mesh.v2beta1.ExposePath + 0, // 1: hashicorp.consul.mesh.v2beta1.ExposePath.protocol:type_name -> hashicorp.consul.mesh.v2beta1.ExposePathProtocol 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 @@ -252,13 +303,14 @@ func file_pbmesh_v2beta1_expose_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pbmesh_v2beta1_expose_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 2, NumExtensions: 0, NumServices: 0, }, GoTypes: file_pbmesh_v2beta1_expose_proto_goTypes, DependencyIndexes: file_pbmesh_v2beta1_expose_proto_depIdxs, + EnumInfos: file_pbmesh_v2beta1_expose_proto_enumTypes, MessageInfos: file_pbmesh_v2beta1_expose_proto_msgTypes, }.Build() File_pbmesh_v2beta1_expose_proto = out.File diff --git a/proto-public/pbmesh/v2beta1/expose.proto b/proto-public/pbmesh/v2beta1/expose.proto index 3c6ad0f07a..03c84c9abc 100644 --- a/proto-public/pbmesh/v2beta1/expose.proto +++ b/proto-public/pbmesh/v2beta1/expose.proto @@ -5,8 +5,6 @@ syntax = "proto3"; package hashicorp.consul.mesh.v2beta1; -import "pbcatalog/v2beta1/protocol.proto"; - message ExposeConfig { repeated ExposePath expose_paths = 1; } @@ -15,5 +13,11 @@ message ExposePath { uint32 listener_port = 1; string path = 2; uint32 local_path_port = 3; - hashicorp.consul.catalog.v2beta1.Protocol protocol = 4; + ExposePathProtocol protocol = 4; +} + +enum ExposePathProtocol { + // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX + EXPOSE_PATH_PROTOCOL_HTTP = 0; + EXPOSE_PATH_PROTOCOL_HTTP2 = 1; }