Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an excludeAddresses option in DNSPolicy #869

Merged
merged 1 commit into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions api/v1alpha1/dnspolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ type DNSPolicySpec struct {
// +kubebuilder:validation:MaxItems=1
// +kubebuilder:validation:MinItems=1
ProviderRefs []dnsv1alpha1.ProviderRef `json:"providerRefs"`

// ExcludeAddresses is a list of addresses (either hostnames, CIDR or IPAddresses) that DNSPolicy should not use as values in the configured DNS provider records. The default is to allow all addresses configured in the Gateway DNSPolicy is targeting
// +optional
// +kubebuilder:validation:MaxItems=20
ExcludeAddresses []string `json:"excludeAddresses,omitempty"`
}

type LoadBalancingSpec struct {
Expand Down Expand Up @@ -125,6 +130,9 @@ type DNSPolicyStatus struct {

// +optional
RecordConditions map[string][]metav1.Condition `json:"recordConditions,omitempty"`
// TotalRecords records the total number of individual DNSRecords managed by this DNSPolicy
// +optional
TotalRecords int32 `json:"totalRecords,omitempty"`
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikenairn added this maybe not needed? Thought it was a useful thing and planned to use it elsewhere

}

func (s *DNSPolicyStatus) GetConditions() []metav1.Condition {
Expand Down Expand Up @@ -251,6 +259,13 @@ func (p *DNSPolicy) WithProviderSecret(s corev1.Secret) *DNSPolicy {
})
}

//excludeAddresses

func (p *DNSPolicy) WithExcludeAddresses(excluded []string) *DNSPolicy {
p.Spec.ExcludeAddresses = excluded
return p
}

//TargetRef

func (p *DNSPolicy) WithTargetGateway(gwName string) *DNSPolicy {
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ metadata:
capabilities: Basic Install
categories: Integration & Delivery
containerImage: quay.io/kuadrant/kuadrant-operator:latest
createdAt: "2024-10-04T07:47:31Z"
createdAt: "2024-10-04T10:00:39Z"
description: A Kubernetes Operator to manage the lifecycle of the Kuadrant system
operators.operatorframework.io/builder: operator-sdk-v1.32.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
Expand Down
14 changes: 14 additions & 0 deletions bundle/manifests/kuadrant.io_dnspolicies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ spec:
spec:
description: DNSPolicySpec defines the desired state of DNSPolicy
properties:
excludeAddresses:
description: ExcludeAddresses is a list of addresses (either hostnames,
CIDR or IPAddresses) that DNSPolicy should not use as values in
the configured DNS provider records. The default is to allow all
addresses configured in the Gateway DNSPolicy is targeting
items:
type: string
maxItems: 20
type: array
healthCheck:
description: |-
HealthCheckSpec configures health checks in the DNS provider.
Expand Down Expand Up @@ -511,6 +520,11 @@ spec:
type: object
type: array
type: object
totalRecords:
description: TotalRecords records the total number of individual DNSRecords
managed by this DNSPolicy
format: int32
type: integer
type: object
type: object
served: true
Expand Down
14 changes: 14 additions & 0 deletions charts/kuadrant-operator/templates/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13266,6 +13266,15 @@ spec:
spec:
description: DNSPolicySpec defines the desired state of DNSPolicy
properties:
excludeAddresses:
description: ExcludeAddresses is a list of addresses (either hostnames,
CIDR or IPAddresses) that DNSPolicy should not use as values in
the configured DNS provider records. The default is to allow all
addresses configured in the Gateway DNSPolicy is targeting
items:
type: string
maxItems: 20
type: array
healthCheck:
description: |-
HealthCheckSpec configures health checks in the DNS provider.
Expand Down Expand Up @@ -13711,6 +13720,11 @@ spec:
type: object
type: array
type: object
totalRecords:
description: TotalRecords records the total number of individual DNSRecords
managed by this DNSPolicy
format: int32
type: integer
type: object
type: object
served: true
Expand Down
14 changes: 14 additions & 0 deletions config/crd/bases/kuadrant.io_dnspolicies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ spec:
spec:
description: DNSPolicySpec defines the desired state of DNSPolicy
properties:
excludeAddresses:
description: ExcludeAddresses is a list of addresses (either hostnames,
CIDR or IPAddresses) that DNSPolicy should not use as values in
the configured DNS provider records. The default is to allow all
addresses configured in the Gateway DNSPolicy is targeting
items:
type: string
maxItems: 20
type: array
healthCheck:
description: |-
HealthCheckSpec configures health checks in the DNS provider.
Expand Down Expand Up @@ -510,6 +519,11 @@ spec:
type: object
type: array
type: object
totalRecords:
description: TotalRecords records the total number of individual DNSRecords
managed by this DNSPolicy
format: int32
type: integer
type: object
type: object
served: true
Expand Down
36 changes: 36 additions & 0 deletions controllers/dns_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package controllers
import (
"context"
"fmt"
"net"
"strings"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -97,6 +99,7 @@ func (dh *dnsHelper) deleteDNSRecordForListener(ctx context.Context, owner metav
// GatewayWrapper is a wrapper for gateway to implement interface form the builder
type GatewayWrapper struct {
*gatewayapiv1.Gateway
excludedAddresses []string
}

func NewGatewayWrapper(gateway *gatewayapiv1.Gateway) *GatewayWrapper {
Expand All @@ -113,3 +116,36 @@ func (g GatewayWrapper) GetAddresses() []builder.TargetAddress {
}
return addresses
}

func (g *GatewayWrapper) RemoveExcludedStatusAddresses(p *v1alpha1.DNSPolicy) error {
g.excludedAddresses = p.Spec.ExcludeAddresses
newAddresses := []gatewayapiv1.GatewayStatusAddress{}
for _, address := range g.Gateway.Status.Addresses {
found := false
for _, exclude := range p.Spec.ExcludeAddresses {
//Only a CIDR will have / in the address so attempt to parse fail if not valid
if strings.Contains(exclude, "/") {
_, network, err := net.ParseCIDR(exclude)
if err != nil {
return fmt.Errorf("could not parse the CIDR from the excludeAddresses field %w", err)
}
ip := net.ParseIP(address.Value)
// only check addresses that are actually IPs
if ip != nil && network.Contains(ip) {
found = true
break
}
}
if exclude == address.Value {
found = true
break
}
}
if !found {
newAddresses = append(newAddresses, address)
}
}
// setting this in memory only wont be saved to actual gateway
g.Status.Addresses = newAddresses
return nil
}
maleck13 marked this conversation as resolved.
Show resolved Hide resolved
167 changes: 167 additions & 0 deletions controllers/dns_helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package controllers_test

import (
"testing"

gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"

"github.com/kuadrant/kuadrant-operator/api/v1alpha1"
"github.com/kuadrant/kuadrant-operator/controllers"
)

func TestRemoveExcludedStatusAddresses(t *testing.T) {
ipaddress := gatewayapiv1.IPAddressType
hostaddress := gatewayapiv1.HostnameAddressType
testCases := []struct {
Name string
Gateway *gatewayapiv1.Gateway
DNSPolicy *v1alpha1.DNSPolicy
Validate func(t *testing.T, g *gatewayapiv1.GatewayStatus)
ExpectErr bool
}{
{
Name: "ensure addresses in ingore are are removed from status",
Gateway: &gatewayapiv1.Gateway{
Status: gatewayapiv1.GatewayStatus{
Addresses: []gatewayapiv1.GatewayStatusAddress{
{
Type: &ipaddress,
Value: "1.1.1.1",
},
{
Type: &hostaddress,
Value: "example.com",
},
},
},
},
DNSPolicy: &v1alpha1.DNSPolicy{
Spec: v1alpha1.DNSPolicySpec{
ExcludeAddresses: []string{
"1.1.1.1",
},
},
},
Validate: func(t *testing.T, g *gatewayapiv1.GatewayStatus) {
if len(g.Addresses) != 1 {
t.Fatalf("expected a single address but got %v ", len(g.Addresses))
}
for _, addr := range g.Addresses {
if addr.Value == "1.1.1.1" {
t.Fatalf("did not expect address %s to be present", "1.1.1.1")
}
}
},
},
{
Name: "ensure all addresses if nothing ignored",
Gateway: &gatewayapiv1.Gateway{
Status: gatewayapiv1.GatewayStatus{
Addresses: []gatewayapiv1.GatewayStatusAddress{
{
Type: &ipaddress,
Value: "1.1.1.1",
},
{
Type: &hostaddress,
Value: "example.com",
},
},
},
},
DNSPolicy: &v1alpha1.DNSPolicy{
Spec: v1alpha1.DNSPolicySpec{
ExcludeAddresses: []string{},
},
},
Validate: func(t *testing.T, g *gatewayapiv1.GatewayStatus) {
if len(g.Addresses) != 2 {
t.Fatalf("expected a both address but got %v ", len(g.Addresses))
}
},
},
{
Name: "ensure addresses removed if CIDR is set and hostname",
Gateway: &gatewayapiv1.Gateway{
Status: gatewayapiv1.GatewayStatus{
Addresses: []gatewayapiv1.GatewayStatusAddress{
{
Type: &ipaddress,
Value: "1.1.1.1",
},
{
Type: &hostaddress,
Value: "example.com",
},
{
Type: &ipaddress,
Value: "81.17.21.22",
},
},
},
},
DNSPolicy: &v1alpha1.DNSPolicy{
Spec: v1alpha1.DNSPolicySpec{
ExcludeAddresses: []string{
"1.1.0.0/16",
"10.0.0.1/32",
"example.com",
},
},
},
Validate: func(t *testing.T, g *gatewayapiv1.GatewayStatus) {
if len(g.Addresses) != 1 {
t.Fatalf("expected only a single address but got %v %v ", len(g.Addresses), g.Addresses)
}
if g.Addresses[0].Value != "81.17.21.22" {
t.Fatalf("expected the only remaining address to be 81.17.21.22 but got %s", g.Addresses[0].Value)
}
},
},
{
Name: "ensure invalid CIDR causes error",
ExpectErr: true,
Gateway: &gatewayapiv1.Gateway{
Status: gatewayapiv1.GatewayStatus{
Addresses: []gatewayapiv1.GatewayStatusAddress{
{
Type: &ipaddress,
Value: "1.1.1.1",
},
{
Type: &hostaddress,
Value: "example.com",
},
{
Type: &ipaddress,
Value: "81.17.21.22",
},
},
},
},
DNSPolicy: &v1alpha1.DNSPolicy{
Spec: v1alpha1.DNSPolicySpec{
ExcludeAddresses: []string{
"1.1.0.0/161",
"example.com",
},
},
},
Validate: func(t *testing.T, g *gatewayapiv1.GatewayStatus) {},
},
}

for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
gw := controllers.NewGatewayWrapper(tc.Gateway)
err := gw.RemoveExcludedStatusAddresses(tc.DNSPolicy)
if err != nil && !tc.ExpectErr {
t.Fatalf("unexpected error %s", err)
}
if tc.ExpectErr && err == nil {
t.Fatalf("expected an error but got none")
}
tc.Validate(t, &gw.Status)
})
}
}
2 changes: 1 addition & 1 deletion controllers/dnspolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func (r *DNSPolicyReconciler) reconcileResources(ctx context.Context, dnsPolicy
}

if err = r.reconcileDNSRecords(ctx, dnsPolicy, gatewayDiffObj); err != nil {
return fmt.Errorf("reconcile DNSRecords error %w", err)
return fmt.Errorf("error reconciling DNSRecords %w", err)
}

// set direct back ref - i.e. claim the target network object as taken asap
Expand Down
Loading
Loading