Prefix sidecar proxy test files with source and destination. (#18620)

* mesh-controller: handle L4 protocols for a proxy without upstreams

* sidecar-controller: Support explicit destinations for L4 protocols and single ports.

* This controller generates and saves ProxyStateTemplate for sidecar proxies.
* It currently supports single-port L4 ports only.
* It keeps a cache of all destinations to make it easier to compute and retrieve destinations.
* It will update the status of the pbmesh.Upstreams resource if anything is invalid.

* endpoints-controller: add workload identity to the service endpoints resource

* small fixes

* review comments

* Address PR comments

* sidecar-proxy controller: Add support for transparent proxy

This currently does not support inferring destinations from intentions.

* PR review comments

* mesh-controller: handle L4 protocols for a proxy without upstreams

* sidecar-controller: Support explicit destinations for L4 protocols and single ports.

* This controller generates and saves ProxyStateTemplate for sidecar proxies.
* It currently supports single-port L4 ports only.
* It keeps a cache of all destinations to make it easier to compute and retrieve destinations.
* It will update the status of the pbmesh.Upstreams resource if anything is invalid.

* endpoints-controller: add workload identity to the service endpoints resource

* small fixes

* review comments

* Make sure endpoint refs route to mesh port instead of an app port

* Address PR comments

* fixing copyright

* tidy imports

* sidecar-proxy controller: Add support for transparent proxy

This currently does not support inferring destinations from intentions.

* tidy imports

* add copyright headers

* Prefix sidecar proxy test files with source and destination.

* Update controller_test.go

---------

Co-authored-by: Iryna Shustava <iryna@hashicorp.com>
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: github-team-consul-core <github-team-consul-core@hashicorp.com>
This commit is contained in:
John Murret 2023-09-08 17:28:55 -06:00 committed by GitHub
parent 1557e1d6a3
commit 3e78b4cf34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 784 additions and 22 deletions

View File

@ -1,4 +1,7 @@
#!/bin/bash
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
# Get the list of changed files
files_to_check=$(git diff --name-only origin/$GITHUB_BASE_REF)

View File

@ -8,6 +8,8 @@ import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
"github.com/hashicorp/consul/internal/catalog"
"github.com/hashicorp/consul/internal/catalog/internal/controllers/endpoints"
"github.com/hashicorp/consul/internal/catalog/internal/controllers/nodehealth"
@ -19,7 +21,6 @@ import (
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/proto/private/prototest"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/stretchr/testify/require"
)
var (

View File

@ -7,14 +7,15 @@ import (
"context"
"sort"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"github.com/hashicorp/consul/internal/catalog/internal/controllers/workloadhealth"
"github.com/hashicorp/consul/internal/catalog/internal/types"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/resource"
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1"
"github.com/hashicorp/consul/proto-public/pbresource"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
)
const (

View File

@ -7,6 +7,9 @@ import (
"context"
"testing"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
"github.com/hashicorp/consul/internal/catalog/internal/controllers/workloadhealth"
"github.com/hashicorp/consul/internal/catalog/internal/mappers/selectiontracker"
@ -18,8 +21,6 @@ import (
"github.com/hashicorp/consul/proto/private/prototest"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
var (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxycache
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxycache
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package builder
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package builder
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package builder
import (
@ -84,26 +87,29 @@ func TestBuildExplicitDestinations(t *testing.T) {
cases := map[string]struct {
destinations []*intermediate.Destination
}{
"l4-single-destination-ip-port-bind-address": {
"destination/l4-single-destination-ip-port-bind-address": {
destinations: []*intermediate.Destination{destinationIpPort},
},
"l4-single-destination-unix-socket-bind-address": {
"destination/l4-single-destination-unix-socket-bind-address": {
destinations: []*intermediate.Destination{destinationUnix},
},
"l4-multi-destination": {
"destination/l4-multi-destination": {
destinations: []*intermediate.Destination{destinationIpPort, destinationUnix},
},
}
for name, c := range cases {
t.Run(name, func(t *testing.T) {
proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", nil).
BuildDestinations(c.destinations).
Build()
actual := protoToJSON(t, proxyTmpl)
expected := golden.Get(t, actual, name)
expected := golden.Get(t, actual, name+".golden")
require.JSONEq(t, expected, actual)
})
}
}
@ -177,13 +183,13 @@ func TestBuildImplicitDestinations(t *testing.T) {
cases := map[string]struct {
destinations []*intermediate.Destination
}{
"l4-single-implicit-destination-tproxy": {
"destination/l4-single-implicit-destination-tproxy": {
destinations: []*intermediate.Destination{destination1},
},
"l4-multiple-implicit-destinations-tproxy": {
"destination/l4-multiple-implicit-destinations-tproxy": {
destinations: []*intermediate.Destination{destination1, destination2},
},
"l4-implicit-and-explicit-destinations-tproxy": {
"destination/l4-implicit-and-explicit-destinations-tproxy": {
destinations: []*intermediate.Destination{destination2, destination3},
},
}

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package builder
import (
@ -17,7 +20,7 @@ func TestBuildLocalApp(t *testing.T) {
cases := map[string]struct {
workload *pbcatalog.Workload
}{
"l4-single-workload-address-without-ports": {
"source/l4-single-workload-address-without-ports": {
workload: &pbcatalog.Workload{
Addresses: []*pbcatalog.WorkloadAddress{
{
@ -30,7 +33,7 @@ func TestBuildLocalApp(t *testing.T) {
},
},
},
"l4-multiple-workload-addresses-without-ports": {
"source/l4-multiple-workload-addresses-without-ports": {
workload: &pbcatalog.Workload{
Addresses: []*pbcatalog.WorkloadAddress{
{
@ -46,7 +49,7 @@ func TestBuildLocalApp(t *testing.T) {
},
},
},
"l4-multiple-workload-addresses-with-specific-ports": {
"source/l4-multiple-workload-addresses-with-specific-ports": {
workload: &pbcatalog.Workload{
Addresses: []*pbcatalog.WorkloadAddress{
{

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package builder
import (

View File

@ -0,0 +1,199 @@
{
"proxyState": {
"clusters": {
"api-1.default.dc1.internal.foo.consul": {
"endpointGroup": {
"dynamic": {
"config": {
"disablePanicThreshold": true
},
"outboundTls": {
"outboundMesh": {
"identityKey": "test-identity",
"sni": "api-1.default.dc1.internal.foo.consul",
"validationContext": {
"spiffeIds": [
"spiffe://foo.consul/ap/default/ns/default/identity/api1-identity"
]
}
}
}
}
}
},
"api-2.default.dc1.internal.foo.consul": {
"endpointGroup": {
"dynamic": {
"config": {
"disablePanicThreshold": true
},
"outboundTls": {
"outboundMesh": {
"identityKey": "test-identity",
"sni": "api-2.default.dc1.internal.foo.consul",
"validationContext": {
"spiffeIds": [
"spiffe://foo.consul/ap/default/ns/default/identity/api2-identity"
]
}
}
}
}
}
}
},
"identity": {
"name": "test-identity",
"tenancy": {
"namespace": "default",
"partition": "default",
"peerName": "local"
}
},
"listeners": [
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
},
{
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "1.1.1.1",
"port": 1234
},
"name": "api-1:tcp:1.1.1.1:1234",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
}
}
]
}
]
},
"requiredEndpoints": {
"api-1.default.dc1.internal.foo.consul": {
"id": {
"name": "api-1",
"tenancy": {
"namespace": "default",
"partition": "default",
"peerName": "local"
},
"type": {
"group": "catalog",
"groupVersion": "v1alpha1",
"kind": "ServiceEndpoints"
}
},
"port": "mesh"
},
"api-2.default.dc1.internal.foo.consul": {
"id": {
"name": "api-2",
"tenancy": {
"namespace": "default",
"partition": "default",
"peerName": "local"
},
"type": {
"group": "catalog",
"groupVersion": "v1alpha1",
"kind": "ServiceEndpoints"
}
},
"port": "mesh"
}
}
}

View File

@ -0,0 +1,360 @@
{
"proxyState": {
"clusters": {
"api-1.default.dc1.internal.foo.consul": {
"endpointGroup": {
"dynamic": {
"config": {
"disablePanicThreshold": true
},
"outboundTls": {
"outboundMesh": {
"identityKey": "test-identity",
"sni": "api-1.default.dc1.internal.foo.consul",
"validationContext": {
"spiffeIds": [
"spiffe://foo.consul/ap/default/ns/default/identity/api1-identity"
]
}
}
}
}
}
},
"api-2.default.dc1.internal.foo.consul": {
"endpointGroup": {
"dynamic": {
"config": {
"disablePanicThreshold": true
},
"outboundTls": {
"outboundMesh": {
"identityKey": "test-identity",
"sni": "api-2.default.dc1.internal.foo.consul",
"validationContext": {
"spiffeIds": [
"spiffe://foo.consul/ap/default/ns/default/identity/api2-identity"
]
}
}
}
}
}
}
},
"identity": {
"name": "test-identity",
"tenancy": {
"namespace": "default",
"partition": "default",
"peerName": "local"
}
},
"listeners": [
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
},
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
},
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
},
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
},
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
},
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
},
{
"l4": {
"name": "api-2.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-2.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "2.2.2.2",
"prefixLen": 32
},
{
"addressPrefix": "3.3.3.3",
"prefixLen": 32
}
]
}
}
]
}
]
},
"requiredEndpoints": {
"api-1.default.dc1.internal.foo.consul": {
"id": {
"name": "api-1",
"tenancy": {
"namespace": "default",
"partition": "default",
"peerName": "local"
},
"type": {
"group": "catalog",
"groupVersion": "v1alpha1",
"kind": "ServiceEndpoints"
}
},
"port": "mesh"
},
"api-2.default.dc1.internal.foo.consul": {
"id": {
"name": "api-2",
"tenancy": {
"namespace": "default",
"partition": "default",
"peerName": "local"
},
"type": {
"group": "catalog",
"groupVersion": "v1alpha1",
"kind": "ServiceEndpoints"
}
},
"port": "mesh"
}
}
}

View File

@ -0,0 +1,135 @@
{
"proxyState": {
"clusters": {
"api-1.default.dc1.internal.foo.consul": {
"endpointGroup": {
"dynamic": {
"config": {
"disablePanicThreshold": true
},
"outboundTls": {
"outboundMesh": {
"identityKey": "test-identity",
"sni": "api-1.default.dc1.internal.foo.consul",
"validationContext": {
"spiffeIds": [
"spiffe://foo.consul/ap/default/ns/default/identity/api1-identity"
]
}
}
}
}
}
}
},
"identity": {
"name": "test-identity",
"tenancy": {
"namespace": "default",
"partition": "default",
"peerName": "local"
}
},
"listeners": [
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
}
]
},
{
"capabilities": [
"CAPABILITY_TRANSPARENT"
],
"direction": "DIRECTION_OUTBOUND",
"hostPort": {
"host": "127.0.0.1",
"port": 15001
},
"name": "outbound_listener",
"routers": [
{
"l4": {
"name": "api-1.default.dc1.internal.foo.consul",
"statPrefix": "upstream.api-1.default.default.dc1"
},
"match": {
"prefixRanges": [
{
"addressPrefix": "1.1.1.1",
"prefixLen": 32
}
]
}
}
]
}
]
},
"requiredEndpoints": {
"api-1.default.dc1.internal.foo.consul": {
"id": {
"name": "api-1",
"tenancy": {
"namespace": "default",
"partition": "default",
"peerName": "local"
},
"type": {
"group": "catalog",
"groupVersion": "v1alpha1",
"kind": "ServiceEndpoints"
}
},
"port": "mesh"
}
}
}

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package fetcher
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package fetcher
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package status
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxymapper
import (

View File

@ -1,9 +1,14 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxymapper
import (
"context"
"testing"
"github.com/stretchr/testify/require"
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
"github.com/hashicorp/consul/internal/catalog"
"github.com/hashicorp/consul/internal/controller"
@ -15,7 +20,6 @@ import (
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1"
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v1alpha1"
"github.com/hashicorp/consul/proto/private/prototest"
"github.com/stretchr/testify/require"
)
func TestMapDestinationsToProxyStateTemplate(t *testing.T) {

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxymapper
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxymapper
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxymapper
import (

View File

@ -1,9 +1,14 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxymapper
import (
"context"
"testing"
"github.com/stretchr/testify/require"
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
"github.com/hashicorp/consul/internal/catalog"
"github.com/hashicorp/consul/internal/controller"
@ -15,7 +20,6 @@ import (
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v1alpha1"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/proto/private/prototest"
"github.com/stretchr/testify/require"
)
func TestProxyConfigurationMapper(t *testing.T) {

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxymapper
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sidecarproxymapper
import (

View File

@ -1,3 +1,6 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package intermediate
import (