Skip to content

Commit

Permalink
Merge branch 'main' of github.com:envoyproxy/gateway into xpolicy-status
Browse files Browse the repository at this point in the history
  • Loading branch information
shawnh2 committed Mar 10, 2024
2 parents d2aa5e5 + 69010d2 commit 83417eb
Show file tree
Hide file tree
Showing 12 changed files with 871 additions and 28 deletions.
5 changes: 3 additions & 2 deletions internal/infrastructure/kubernetes/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ func ExpectedServiceSpec(service *egv1a1.KubernetesServiceSpec) corev1.ServiceSp
return serviceSpec
}

// CompareSvc compare entire Svc.Spec but ignored the ports[*].nodePort, ClusterIP and ClusterIPs in case user have modified for some scene.
// CompareSvc compares the Service resource and ignores specific fields that may have been modified by other actors.
func CompareSvc(currentSvc, originalSvc *corev1.Service) bool {
return cmp.Equal(currentSvc.Spec, originalSvc.Spec,
cmpopts.IgnoreFields(corev1.ServicePort{}, "NodePort"),
cmpopts.IgnoreFields(corev1.ServiceSpec{}, "ClusterIP", "ClusterIPs"))
cmpopts.IgnoreFields(corev1.ServiceSpec{}, "ClusterIP", "ClusterIPs"),
cmpopts.IgnoreFields(metav1.ObjectMeta{}, "Finalizers"))
}

// ExpectedContainerEnv returns expected container envs.
Expand Down
42 changes: 42 additions & 0 deletions internal/infrastructure/kubernetes/resource/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,48 @@ func TestCompareSvc(t *testing.T) {
Type: "ClusterIP",
},
},
}, {
// Finalizers field differs
ExpectRet: true,
NewSvc: &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "my-service",
Namespace: "default",
Finalizers: []string{"service.k8s.aws/resources"},
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.FromInt(8080),
},
},
Selector: map[string]string{
"app": "my-app",
},
Type: "ClusterIP",
},
},
OriginalSvc: &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "my-service",
Namespace: "default",
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.FromInt(8080),
},
},
Selector: map[string]string{
"app": "my-app",
},
Type: "ClusterIP",
},
},
},
}

Expand Down
15 changes: 3 additions & 12 deletions internal/provider/kubernetes/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ type resourceMappings struct {
allAssociatedNamespaces map[string]struct{}
// Map for storing backendRefs' NamespaceNames referred by various Route objects.
allAssociatedBackendRefs map[gwapiv1.BackendObjectReference]struct{}
// Map for storing referenceGrant NamespaceNames for BackendRefs, SecretRefs, ConfigMapRefs.
allAssociatedRefGrants map[types.NamespacedName]*gwapiv1b1.ReferenceGrant
// extensionRefFilters is a map of filters managed by an extension.
// The key is the namespaced name of the filter and the value is the
// unstructured form of the resource.
Expand All @@ -128,7 +126,6 @@ func newResourceMapping() *resourceMappings {
return &resourceMappings{
allAssociatedNamespaces: map[string]struct{}{},
allAssociatedBackendRefs: map[gwapiv1.BackendObjectReference]struct{}{},
allAssociatedRefGrants: map[types.NamespacedName]*gwapiv1b1.ReferenceGrant{},
extensionRefFilters: map[types.NamespacedName]unstructured.Unstructured{},
}
}
Expand Down Expand Up @@ -207,12 +204,6 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
// BackendRefs are referred by various Route objects and the ExtAuth in SecurityPolicies.
r.processBackendRefs(ctx, gwcResource, resourceMappings)

// Add all ReferenceGrants to the resourceTree
// TODO: zhaohuabing remove allAssociatedRefGrants from resourceMappings and directly add to gwcResource
for _, referenceGrant := range resourceMappings.allAssociatedRefGrants {
gwcResource.ReferenceGrants = append(gwcResource.ReferenceGrants, referenceGrant)
}

// For this particular Gateway, and all associated objects, check whether the
// namespace exists. Add to the resourceTree.
for ns := range resourceMappings.allAssociatedNamespaces {
Expand Down Expand Up @@ -459,7 +450,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs(
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down Expand Up @@ -540,7 +531,7 @@ func (r *gatewayAPIReconciler) processSecretRef(
from.kind, from.namespace, to.kind, to.namespace)
default:
// RefGrant found
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down Expand Up @@ -641,7 +632,7 @@ func (r *gatewayAPIReconciler) processConfigMapRef(
from.kind, from.namespace, to.kind, to.namespace)
default:
// RefGrant found
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down
12 changes: 6 additions & 6 deletions internal/provider/kubernetes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down Expand Up @@ -150,7 +150,7 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down Expand Up @@ -269,7 +269,7 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down Expand Up @@ -336,7 +336,7 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down Expand Up @@ -425,7 +425,7 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down Expand Up @@ -495,7 +495,7 @@ func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayName
r.log.Info("no matching ReferenceGrants found", "from", from.kind,
"from namespace", from.namespace, "target", to.kind, "target namespace", to.namespace)
default:
resourceMap.allAssociatedRefGrants[utils.NamespacedName(refGrant)] = refGrant
resourceTree.ReferenceGrants = append(resourceTree.ReferenceGrants, refGrant)
r.log.Info("added ReferenceGrant to resource map", "namespace", refGrant.Namespace,
"name", refGrant.Name)
}
Expand Down
20 changes: 16 additions & 4 deletions internal/xds/translator/extauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,20 +231,32 @@ func (*extAuth) patchResources(tCtx *types.ResourceVersionTable,
}

func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVersionTable) error {
var (
endpointType EndpointType
tSocket *corev3.TransportSocket
err error
)

// Get the address type from the first setting.
// This is safe because no mixed address types in the settings.
addrTypeState := rd.Settings[0].AddressType

var endpointType EndpointType
if addrTypeState != nil && *addrTypeState == ir.FQDN {
endpointType = EndpointTypeDNS
} else {
endpointType = EndpointTypeStatic
}
if err := addXdsCluster(tCtx, &xdsClusterArgs{

if rd.Settings[0].TLS != nil {
tSocket, err = processTLSSocket(rd.Settings[0].TLS, tCtx)
if err != nil {
return err
}
}

if err = addXdsCluster(tCtx, &xdsClusterArgs{
name: rd.Name,
settings: rd.Settings,
tSocket: nil,
tSocket: tSocket,
endpointType: endpointType,
}); err != nil && !errors.Is(err, ErrXdsClusterExists) {
return err
Expand Down
21 changes: 21 additions & 0 deletions internal/xds/translator/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,27 @@ func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute
return nil
}

// processTLSSocket generates a xDS TransportSocket for a given TLS config.
// It also adds the necessary secrets to the resource version table.
func processTLSSocket(tlsConfig *ir.TLSUpstreamConfig, tCtx *types.ResourceVersionTable) (*corev3.TransportSocket, error) {
if tlsConfig == nil {
return nil, nil
}
CaSecret := buildXdsUpstreamTLSCASecret(tlsConfig)
if CaSecret != nil {
if err := tCtx.AddXdsResource(resourcev3.SecretType, CaSecret); err != nil {
return nil, err
}
}
// for upstreamTLS , a fixed sni can be used. use auto_sni otherwise
// https://www.envoyproxy.io/docs/envoy/latest/faq/configuration/sni#faq-how-to-setup-sni:~:text=For%20clusters%2C%20a,for%20trust%20anchor.
tlsSocket, err := buildXdsUpstreamTLSSocketWthCert(tlsConfig)
if err != nil {
return nil, err
}
return tlsSocket, nil
}

// findXdsSecret finds a xds secret with the same name, and returns nil if there is no match.
func findXdsSecret(tCtx *types.ResourceVersionTable, name string) *tlsv3.Secret {
if tCtx == nil || tCtx.XdsResources == nil || tCtx.XdsResources[resourcev3.SecretType] == nil {
Expand Down
146 changes: 146 additions & 0 deletions site/content/en/latest/install/custom-cert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
title: Control Plane Authentication using custom certs
weight: -70
---

Envoy Gateway establishes a secure TLS connection for control plane communication between Envoy Gateway pods and the Envoy Proxy fleet. The TLS Certificates used here are self signed and generated using a job that runs before envoy gateway is created, and these certs and mounted on to the envoy gateway and envoy proxy pods.

In this guide, we'll walk you through configuring custom certs for control plane auth.

## Before you begin

We use Cert-Manager to manage the certificates. You can install it by following the [official guide](https://cert-manager.io/docs/installation/kubernetes/).

## Configure custom certs for control plane

1. First you need to set up the CA issuer, in this guide, we use the `selfsigned-issuer` as an example.

*You should not use the self-signed issuer in production, you should use a real CA issuer.*

```shell
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
labels:
app.kubernetes.io/name: envoy-gateway
name: selfsigned-issuer
namespace: envoy-gateway-system
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: envoy-gateway-ca
namespace: envoy-gateway-system
spec:
isCA: true
commonName: envoy-gateway
secretName: envoy-gateway-ca
privateKey:
algorithm: RSA
size: 2048
issuerRef:
name: selfsigned-issuer
kind: Issuer
group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
labels:
app.kubernetes.io/name: envoy-gateway
name: eg-issuer
namespace: envoy-gateway-system
spec:
ca:
secretName: envoy-gateway-ca
EOF
```
2. Create a cert for envoy gateway controller, the cert will be stored in secret `envoy-gatewy`.
```shell
cat<<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
labels:
app.kubernetes.io/name: envoy-gateway
name: envoy-gateway
namespace: envoy-gateway-system
spec:
commonName: envoy-gateway
dnsNames:
- "envoy-gateway"
- "envoy-gateway.envoy-gateway-system"
- "envoy-gateway.envoy-gateway-system.svc"
- "envoy-gateway.envoy-gateway-system.svc.cluster.local"
issuerRef:
kind: Issuer
name: eg-issuer
usages:
- "digital signature"
- "data encipherment"
- "key encipherment"
- "content commitment"
secretName: envoy-gateway
EOF
```
3. Create a cert for envoy proxy, the cert will be stored in secret `envoy`.
```shell
cat<<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
labels:
app.kubernetes.io/name: envoy-gateway
name: envoy
namespace: envoy-gateway-system
spec:
commonName: "*"
dnsNames:
- "*.envoy-gateway-system"
issuerRef:
kind: Issuer
name: eg-issuer
usages:
- "digital signature"
- "data encipherment"
- "key encipherment"
- "content commitment"
secretName: envoy
EOF
```
4. Create a cert for rate limit, the cert will be stored in secret `envoy-rate-limit`.
```shell
cat<<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
labels:
app.kubernetes.io/name: envoy-gateway
name: envoy-rate-limit
namespace: envoy-gateway-system
spec:
commonName: "*"
dnsNames:
- "*.envoy-gateway-system"
issuerRef:
kind: Issuer
name: eg-issuer
usages:
- "digital signature"
- "data encipherment"
- "key encipherment"
- "content commitment"
secretName: envoy-rate-limit
EOF
```
5. Now you can follow the helm chart [installation guide](../install-helm) to install envoy gateway with custom certs.
Loading

0 comments on commit 83417eb

Please sign in to comment.