Skip to content

Commit

Permalink
State of the world reconciler (#838)
Browse files Browse the repository at this point in the history
* FEAT: Policy Machinery

* FEAT: add kuadrant CR to topology 
This also includes the different policies (auth, DNS, ratelimit, TLS)
The kuadrant CR has been added as the root to the topology.
This does not take into account what happens if more than one kuadrant CR is added to the cluster

* RBAC: gatewayclasses
Adding RBAC to allow listing and watching the Gateway Class so they can be added to the graph.

* Feat: ConfigMap in topology
Topology configmap writes only happen if the data['topology'] is different.
- Acquire namespace from environment variable
- setting namespace
- panic if envvar is not there

---------

Signed-off-by: Jim Fitzpatrick <[email protected]>
  • Loading branch information
Boomatang authored Sep 16, 2024
1 parent f51be7b commit 8c1de21
Show file tree
Hide file tree
Showing 17 changed files with 533 additions and 104 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ tmp
/coverage/

# Vendor dependencies
vendor
vendor
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ build: generate fmt vet ## Build manager binary.

run: export LOG_LEVEL = debug
run: export LOG_MODE = development
run: export OPERATOR_NAMESPACE = kuadrant-system
run: generate fmt vet ## Run a controller from your host.
go run ./main.go

Expand Down
3 changes: 1 addition & 2 deletions api/v1alpha1/dnspolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package v1alpha1
import (
"context"

dnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand All @@ -27,8 +28,6 @@ import (
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"

dnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1"

kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi"
"github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant"
"github.com/kuadrant/kuadrant-operator/pkg/library/utils"
Expand Down
65 changes: 65 additions & 0 deletions api/v1alpha1/topology.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package v1alpha1

// Contains of this file allow the DNSPolicy and TLSPolicy to adhere to the machinery.Policy interface

import (
"github.com/kuadrant/policy-machinery/machinery"
"k8s.io/apimachinery/pkg/runtime/schema"
)

var (
DNSPoliciesResource = GroupVersion.WithResource("dnspolicies")
DNSPolicyKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "DNSPolicy"}
TLSPoliciesResource = GroupVersion.WithResource("tlspolicies")
TLSPolicyKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "TLSPolicy"}
)

var _ machinery.Policy = &DNSPolicy{}

func (p *DNSPolicy) GetTargetRefs() []machinery.PolicyTargetReference {
return []machinery.PolicyTargetReference{
machinery.LocalPolicyTargetReference{
LocalPolicyTargetReference: p.Spec.TargetRef,
PolicyNamespace: p.Namespace,
},
}
}

func (p *DNSPolicy) GetMergeStrategy() machinery.MergeStrategy {
return func(policy machinery.Policy, _ machinery.Policy) machinery.Policy {
return policy
}
}

func (p *DNSPolicy) Merge(other machinery.Policy) machinery.Policy {
return other
}

func (p *DNSPolicy) GetLocator() string {
return machinery.LocatorFromObject(p)
}

var _ machinery.Policy = &TLSPolicy{}

func (p *TLSPolicy) GetTargetRefs() []machinery.PolicyTargetReference {
return []machinery.PolicyTargetReference{
machinery.LocalPolicyTargetReference{
LocalPolicyTargetReference: p.Spec.TargetRef,
PolicyNamespace: p.Namespace,
},
}
}

func (p *TLSPolicy) GetMergeStrategy() machinery.MergeStrategy {
return func(policy machinery.Policy, _ machinery.Policy) machinery.Policy {
return policy
}
}

func (p *TLSPolicy) Merge(other machinery.Policy) machinery.Policy {
return other
}

func (p *TLSPolicy) GetLocator() string {
return machinery.LocatorFromObject(p)
}
36 changes: 36 additions & 0 deletions api/v1beta1/topology.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package v1beta1

import (
"github.com/kuadrant/policy-machinery/controller"
"github.com/kuadrant/policy-machinery/machinery"
"github.com/samber/lo"
"k8s.io/apimachinery/pkg/runtime/schema"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)

var (
KuadrantResource = GroupVersion.WithResource("kuadrants")
KuadrantKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "Kuadrant"}
)

var _ machinery.Object = &Kuadrant{}

func (p *Kuadrant) GetLocator() string {
return machinery.LocatorFromObject(p)
}

func LinkKuadrantToGatewayClasses(objs controller.Store) machinery.LinkFunc {
kuadrants := lo.Map(objs.FilterByGroupKind(KuadrantKind), controller.ObjectAs[*Kuadrant])

return machinery.LinkFunc{
From: KuadrantKind,
To: schema.GroupKind{Group: gwapiv1.GroupVersion.Group, Kind: "GatewayClass"},
Func: func(_ machinery.Object) []machinery.Object {
parents := make([]machinery.Object, len(kuadrants))
for _, parent := range kuadrants {
parents = append(parents, parent)
}
return parents
},
}
}
3 changes: 1 addition & 2 deletions api/v1beta2/ratelimitpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func (s *RateLimitPolicyStatus) GetConditions() []metav1.Condition {

var _ kuadrant.Policy = &RateLimitPolicy{}
var _ kuadrant.Referrer = &RateLimitPolicy{}
var _ kuadrantgatewayapi.Policy = &RateLimitPolicy{}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
Expand All @@ -233,8 +234,6 @@ type RateLimitPolicy struct {
Status RateLimitPolicyStatus `json:"status,omitempty"`
}

var _ kuadrantgatewayapi.Policy = &RateLimitPolicy{}

func (r *RateLimitPolicy) GetObservedGeneration() int64 { return r.Status.GetObservedGeneration() }
func (r *RateLimitPolicy) SetObservedGeneration(o int64) { r.Status.SetObservedGeneration(o) }

Expand Down
65 changes: 65 additions & 0 deletions api/v1beta2/topology.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package v1beta2

// Contains of this file allow the AuthPolicy and RateLimitPolicy to adhere to the machinery.Policy interface

import (
"github.com/kuadrant/policy-machinery/machinery"
"k8s.io/apimachinery/pkg/runtime/schema"
)

var (
AuthPoliciesResource = GroupVersion.WithResource("authpolicies")
AuthPolicyKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "AuthPolicy"}
RateLimitPoliciesResource = GroupVersion.WithResource("ratelimitpolicies")
RateLimitPolicyKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "RateLimitPolicy"}
)

var _ machinery.Policy = &AuthPolicy{}

func (ap *AuthPolicy) GetTargetRefs() []machinery.PolicyTargetReference {
return []machinery.PolicyTargetReference{
machinery.LocalPolicyTargetReference{
LocalPolicyTargetReference: ap.Spec.TargetRef,
PolicyNamespace: ap.Namespace,
},
}
}

func (ap *AuthPolicy) GetMergeStrategy() machinery.MergeStrategy {
return func(policy machinery.Policy, _ machinery.Policy) machinery.Policy {
return policy
}
}

func (ap *AuthPolicy) Merge(other machinery.Policy) machinery.Policy {
return other
}

func (ap *AuthPolicy) GetLocator() string {
return machinery.LocatorFromObject(ap)
}

var _ machinery.Policy = &RateLimitPolicy{}

func (r *RateLimitPolicy) GetTargetRefs() []machinery.PolicyTargetReference {
return []machinery.PolicyTargetReference{
machinery.LocalPolicyTargetReference{
LocalPolicyTargetReference: r.Spec.TargetRef,
PolicyNamespace: r.Namespace,
},
}
}

func (r *RateLimitPolicy) GetMergeStrategy() machinery.MergeStrategy {
return func(policy machinery.Policy, _ machinery.Policy) machinery.Policy {
return policy
}
}

func (r *RateLimitPolicy) Merge(other machinery.Policy) machinery.Policy {
return other
}

func (r *RateLimitPolicy) GetLocator() string {
return machinery.LocatorFromObject(r)
}
13 changes: 12 additions & 1 deletion bundle/manifests/kuadrant-operator.clusterserviceversion.yaml
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-08-20T09:51:49Z"
createdAt: "2024-09-12T15:37:42Z"
operators.operatorframework.io/builder: operator-sdk-v1.32.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
repository: https://github.com/Kuadrant/kuadrant-operator
Expand Down Expand Up @@ -282,6 +282,13 @@ spec:
- patch
- update
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- gatewayclasses
verbs:
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
Expand Down Expand Up @@ -592,6 +599,10 @@ spec:
env:
- name: RELATED_IMAGE_WASMSHIM
value: oci://quay.io/kuadrant/wasm-shim:latest
- name: OPERATOR_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/kuadrant/kuadrant-operator:latest
livenessProbe:
httpGet:
Expand Down
42 changes: 36 additions & 6 deletions bundle/manifests/kuadrant.io_authpolicies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -598,10 +598,15 @@ spec:
to the OAuth2 server.
properties:
name:
default: ""
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
Expand Down Expand Up @@ -3089,10 +3094,15 @@ spec:
to the resource registration API of the UMA server.
properties:
name:
default: ""
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
Expand Down Expand Up @@ -4904,10 +4914,15 @@ spec:
to the OAuth2 server.
properties:
name:
default: ""
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
Expand Down Expand Up @@ -7395,10 +7410,15 @@ spec:
to the resource registration API of the UMA server.
properties:
name:
default: ""
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
Expand Down Expand Up @@ -9201,10 +9221,15 @@ spec:
the OAuth2 server.
properties:
name:
default: ""
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
Expand Down Expand Up @@ -11680,10 +11705,15 @@ spec:
the resource registration API of the UMA server.
properties:
name:
default: ""
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
type: object
x-kubernetes-map-type: atomic
Expand Down
Loading

0 comments on commit 8c1de21

Please sign in to comment.