Skip to content

Commit

Permalink
feat: convert BackendTLSPolicies into service anns
Browse files Browse the repository at this point in the history
Signed-off-by: Mattia Lavacca <[email protected]>
  • Loading branch information
mlavacca committed Dec 2, 2024
1 parent 1f1d0e5 commit 03b4d14
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
20 changes: 20 additions & 0 deletions internal/annotations/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,23 @@ func extractCommaDelimitedStrings(s string, sanitizeFns ...func(string) string)

return out
}

// SetTLSVerify sets the tls-verify annotation value.
func SetTLSVerify(anns map[string]string, value bool) {
anns[AnnotationPrefix+TLSVerifyKey] = strconv.FormatBool(value)
}

// SetCACertificates merge the ca-certificates secret names into the already existing CA certificates set via annotation.
func SetCACertificates(anns map[string]string, certificates []string) {
existingCACerts := anns[AnnotationPrefix+CACertificatesKey]
if existingCACerts == "" {
anns[AnnotationPrefix+CACertificatesKey] = strings.Join(certificates, ",")
} else {
anns[AnnotationPrefix+CACertificatesKey] = existingCACerts + "," + strings.Join(certificates, ",")
}
}

// SetHostHeader sets the host-header annotation value.
func SetHostHeader(anns map[string]string, value string) {
anns[AnnotationPrefix+HostHeaderKey] = value
}
47 changes: 47 additions & 0 deletions internal/dataplane/translator/ingressrules.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ func (ir *ingressRules) populateServices(
}

for _, k8sService := range k8sServices {
// TODO: comment
ir.handleBackendTLSPolices(logger, s, k8sService, failuresCollector, translatedObjectsCollector)

// at this point we know the Kubernetes service itself is valid and can be
// used for traffic, so cache it amongst the kong Services k8s services.
service.K8sServices[fmt.Sprintf("%s/%s", k8sService.Namespace, k8sService.Name)] = k8sService
Expand All @@ -105,6 +108,50 @@ func (ir *ingressRules) populateServices(
return serviceNamesToSkip
}

func (ir *ingressRules) handleBackendTLSPolices(
logger logr.Logger,
s store.Storer,
k8sService *corev1.Service,
failuresCollector *failures.ResourceFailuresCollector,
translatedObjectsCollector *ObjectsCollector,
) {
policies, err := s.ListBackendTLSPoliciesByTargetService(client.ObjectKeyFromObject(k8sService))
if err != nil {
failuresCollector.PushResourceFailure(
fmt.Sprintf("Failed to list backendTLSPolicies: %v", err), k8sService,
)
return
}
if len(policies) == 0 {
return
}
if len(policies) > 1 {
failuresCollector.PushResourceFailure(
"Multiple BackendTLSPolicies attached to service", k8sService,
)
return
}

if k8sService.Annotations == nil {
k8sService.Annotations = make(map[string]string)
}

annotations.SetTLSVerify(k8sService.Annotations, true)
caCerts := []string{}

policy := policies[0]

// TODO: change as this needs to be a configmap according to the spec
for _, cert := range policy.Spec.Validation.CACertificateRefs {
if cert.Group != "core" && cert.Group != "" || cert.Kind != "Secret" {
continue
}
caCerts = append(caCerts, string(cert.Name))
}
annotations.SetCACertificates(k8sService.Annotations, caCerts)
annotations.SetHostHeader(k8sService.Annotations, string(policy.Spec.Validation.Hostname))
}

func (ir *ingressRules) handleServiceClientCertificates(
s store.Storer,
k8sService *corev1.Service,
Expand Down
27 changes: 24 additions & 3 deletions internal/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"strings"

"github.com/go-logr/logr"
"github.com/samber/lo"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
netv1 "k8s.io/api/networking/v1"
Expand All @@ -30,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
Expand Down Expand Up @@ -102,7 +104,7 @@ type Storer interface {
ListGRPCRoutes() ([]*gatewayapi.GRPCRoute, error)
ListReferenceGrants() ([]*gatewayapi.ReferenceGrant, error)
ListGateways() ([]*gatewayapi.Gateway, error)
ListBackendTLSPolicies() ([]*gatewayapi.BackendTLSPolicy, error)
ListBackendTLSPoliciesByTargetService(service types.NamespacedName) ([]*gatewayapi.BackendTLSPolicy, error)
}

// Store implements Storer and can be used to list Ingress, Services
Expand Down Expand Up @@ -337,8 +339,27 @@ func (s Store) ListGateways() ([]*gatewayapi.Gateway, error) {
return List[*gatewayapi.Gateway](s.stores)
}

func (s Store) ListBackendTLSPolicies() ([]*gatewayapi.BackendTLSPolicy, error) {
return List[*gatewayapi.BackendTLSPolicy](s.stores)
// ListBackendTLSPoliciesByTargetService returns the list of BackendTLSPolicies in the BackendTLSPolicy cache store.
// The policies are filtered by the target service.
// TODO: implement indexers to speed up the lookup.
func (s Store) ListBackendTLSPoliciesByTargetService(service types.NamespacedName) ([]*gatewayapi.BackendTLSPolicy, error) {
policiesToReturn := []*gatewayapi.BackendTLSPolicy{}
policies, err := List[*gatewayapi.BackendTLSPolicy](s.stores)
if err != nil {
return nil, err
}

for _, policy := range policies {
if lo.ContainsBy(policy.Spec.TargetRefs, func(ref gatewayapi.LocalPolicyTargetReferenceWithSectionName) bool {
return (ref.Group == "" || ref.Group == "core") &&
ref.Kind == "Service" &&
(policy.Namespace == service.Namespace && string(ref.Name) == service.Name)
}) {
policiesToReturn = append(policiesToReturn, policy)
}
}

return policiesToReturn, nil
}

// ListTCPIngresses returns the list of TCP Ingresses from
Expand Down

0 comments on commit 03b4d14

Please sign in to comment.