Skip to content
Closed
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
6 changes: 6 additions & 0 deletions api/bases/ovn.openstack.org_ovndbclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,12 @@ spec:
description: InternalDBAddress - DB IP address used by other Pods
in the cluster
type: string
internalDbAddressRbacFullAccess:
description: |-
InternalDBAddressRbacFullAccess - DB IP address used by other Pods which
requires full access to the SB db, like e.g. Northd. This is used only
when OVN RBAC for ovn-controllers is used (TLS enabled)
type: string
lastAppliedTopology:
description: LastAppliedTopology - the last applied Topology
properties:
Expand Down
1 change: 1 addition & 0 deletions api/test/helpers/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func (th *TestHelper) SimulateOVNNorthdReady(name types.NamespacedName) {
gomega.Eventually(func(g gomega.Gomega) {
service := th.GetOVNNorthd(name)
service.Status.ObservedGeneration = service.Generation
service.Status.ReadyCount = 1
service.Status.Conditions.MarkTrue(condition.ReadyCondition, "Ready")
g.Expect(th.K8sClient.Status().Update(th.Ctx, service)).To(gomega.Succeed())
}, th.Timeout, th.Interval).Should(gomega.Succeed())
Expand Down
21 changes: 21 additions & 0 deletions api/v1beta1/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,27 @@ func getItems(list client.ObjectList) []client.Object {
return items
}

// GetOVNNorthd - return OVNNorthd in the given namespace
func GetOVNNorthd(
ctx context.Context,
h *helper.Helper,
namespace string,
) (*OVNNorthd, error) {
ovnNorthdList := &OVNNorthdList{}
listOpts := []client.ListOption{
client.InNamespace(namespace),
}
err := h.GetClient().List(ctx, ovnNorthdList, listOpts...)
if err != nil {
return nil, err
}
if len(ovnNorthdList.Items) > 0 {
return &ovnNorthdList.Items[0], nil
}

return nil, nil
}

// OVNCRNamespaceMapFunc // Generic function to watch any OVN CR
func OVNCRNamespaceMapFunc(crs client.ObjectList, reader client.Reader) handler.MapFunc {
return func(ctx context.Context, obj client.Object) []reconcile.Request {
Expand Down
22 changes: 22 additions & 0 deletions api/v1beta1/ovndbcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ type OVNDBClusterStatus struct {
// InternalDBAddress - DB IP address used by other Pods in the cluster
InternalDBAddress string `json:"internalDbAddress,omitempty"`

// InternalDBAddressRbacFullAccess - DB IP address used by other Pods which
// requires full access to the SB db, like e.g. Northd. This is used only
// when OVN RBAC for ovn-controllers is used (TLS enabled)
InternalDBAddressRbacFullAccess string `json:"internalDbAddressRbacFullAccess,omitempty"`

// NetworkAttachments status of the deployment pods
NetworkAttachments map[string][]string `json:"networkAttachments,omitempty"`

Expand Down Expand Up @@ -238,6 +243,23 @@ func (instance OVNDBCluster) GetInternalEndpoint() (string, error) {
return instance.Status.InternalDBAddress, nil
}

// GetInternalEndpointRbacFullAccess - return the DNS name that openshift coreDNS can resolve
func (instance OVNDBCluster) GetInternalEndpointRbacFullAccess() (string, error) {
if !instance.Spec.TLS.Enabled() {
// if TLS is disabled, this is the same as internalDbAddress
return instance.GetInternalEndpoint()
}
if instance.Spec.DBType != SBDBType {
// if DBType is not SB, this is the same as internalDbAddress
return instance.GetInternalEndpoint()
}

if instance.Status.InternalDBAddressRbacFullAccess == "" {
return "", fmt.Errorf("internal DBEndpoint not ready yet for %s", instance.Spec.DBType)
}
return instance.Status.InternalDBAddressRbacFullAccess, nil
}

// GetExternalEndpoint - return the DNS that openstack dnsmasq can resolve
func (instance OVNDBCluster) GetExternalEndpoint() (string, error) {
if (instance.Spec.NetworkAttachment != "" || instance.Spec.Override.Service != nil) && instance.Status.DBAddress == "" {
Expand Down
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import (

// +kubebuilder:scaffold:imports

certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
infranetworkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1"
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
Expand All @@ -62,6 +63,7 @@ var (

func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(certmgrv1.AddToScheme(scheme))
utilruntime.Must(ovnv1.AddToScheme(scheme))
utilruntime.Must(networkv1.AddToScheme(scheme))
utilruntime.Must(infranetworkv1.AddToScheme(scheme))
Expand Down
6 changes: 6 additions & 0 deletions config/crd/bases/ovn.openstack.org_ovndbclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,12 @@ spec:
description: InternalDBAddress - DB IP address used by other Pods
in the cluster
type: string
internalDbAddressRbacFullAccess:
description: |-
InternalDBAddressRbacFullAccess - DB IP address used by other Pods which
requires full access to the SB db, like e.g. Northd. This is used only
when OVN RBAC for ovn-controllers is used (TLS enabled)
type: string
lastAppliedTopology:
description: LastAppliedTopology - the last applied Topology
properties:
Expand Down
21 changes: 21 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ rules:
- patch
- update
- watch
- apiGroups:
- cert-manager.io
resources:
- certificates
- issuers
verbs:
- create
- get
- list
- patch
- update
- watch
- apiGroups:
- k8s.cni.cncf.io
resources:
Expand Down Expand Up @@ -158,6 +170,15 @@ rules:
- securitycontextconstraints
verbs:
- use
- apiGroups:
- security.openshift.io
resourceNames:
- privileged
- restricted-v2
resources:
- securitycontextconstraints
verbs:
- use
- apiGroups:
- security.openshift.io
resourceNames:
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ module github.com/openstack-k8s-operators/ovn-operator
go 1.24.4

require (
github.com/cert-manager/cert-manager v1.16.5
github.com/go-logr/logr v1.4.3
github.com/google/uuid v1.6.0
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7
github.com/onsi/ginkgo/v2 v2.28.1
github.com/onsi/gomega v1.39.1
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6
github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20251122131503-b76943960b6c
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260417092244-81c71b39e981
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260417092244-81c71b39e981
github.com/openstack-k8s-operators/ovn-operator/api v0.0.0-20230418071801-b5843d9e05fb
Expand Down Expand Up @@ -65,7 +67,7 @@ require (
github.com/prometheus/procfs v0.16.1 // indirect
github.com/spf13/cobra v1.9.1 // indirect
github.com/spf13/pflag v1.0.7 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
Expand Down Expand Up @@ -103,6 +105,7 @@ require (
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250902184714-7fc278399c7f // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect
sigs.k8s.io/gateway-api v1.2.1 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
Expand Down
18 changes: 14 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cert-manager/cert-manager v1.16.5 h1:XIhKoS4zQV9RHXAkqQW0NLivvoxAnWzbPsy9BG6cPVc=
github.com/cert-manager/cert-manager v1.16.5/go.mod h1:0DwmIGjMOreiP7/6gAqnjaBRJ+yHCfZ5DP7NNqKV+tY=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
Expand Down Expand Up @@ -118,6 +120,8 @@ github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e h1:E1OdwSpqWuDPCedyU
github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6 h1:117Gu9HCSu2tAp579WnCJ9QtnslH2qnPB8UFvn8ZpqE=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6/go.mod h1:i7l8cihvFktd/LSuyvL2z6OcwauarQGoVhDMePL4VyI=
github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20251122131503-b76943960b6c h1:cPnMoKY5QkPF3ynahGs2+epjYVBb59vqt+uO6RHGFHE=
github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:3zDlaWh4PKwFAhYM6zcKe+bAnCggnSB94v4unP4snUM=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260417092244-81c71b39e981 h1:v1viH0gmNb+AXMg/0GxDcj8VUTdjVLotfOIGrNyMxHk=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260417092244-81c71b39e981/go.mod h1:I/VBXZLdjk8DUGsEbB+Ha72JBFYYntP7Pm2FpEto9K8=
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260417092244-81c71b39e981 h1:KAQ8T+Ri3JWgsyK1D6QybScMh6fpkYUUA+0ntnOiAl4=
Expand All @@ -143,11 +147,15 @@ github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wx
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
Expand Down Expand Up @@ -254,9 +262,9 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.31.14 h1:xYn/S/WFJsksI7dk/5uBRd3Umm/D8W5g7sRnd4csotA=
Expand All @@ -281,6 +289,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsA
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/controller-runtime v0.19.7 h1:DLABZfMr20A+AwCZOHhcbcu+TqBXnJZaVBri9K3EO48=
sigs.k8s.io/controller-runtime v0.19.7/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
sigs.k8s.io/gateway-api v1.2.1 h1:fZZ/+RyRb+Y5tGkwxFKuYuSRQHu9dZtbjenblleOLHM=
sigs.k8s.io/gateway-api v1.2.1/go.mod h1:EpNfEXNjiYfUJypf0eZ0P5iXA9ekSGWaS1WgPaM42X0=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
Expand Down
9 changes: 9 additions & 0 deletions internal/common/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ const (
// OVNMetricsKeyPath is the path to the metrics private key file
OVNMetricsKeyPath string = "/etc/pki/tls/private/ovnmetrics.key"

// OVNRbacPkiCaMountPath is the mount path for the OVN RBAC PKI CA secret volume
OVNRbacPkiCaMountPath string = "/etc/pki/ovn-rbac-ca"
// OVNRbacPkiCaCertPath is the path where the OVN RBAC PKI CA certificate
// is mounted inside the container
OVNRbacPkiCaCertPath string = OVNRbacPkiCaMountPath + "/tls.crt"
// OVNRbacPkiCaKeyPath is the path where the OVN RBAC PKI CA private key
// is mounted inside the container
OVNRbacPkiCaKeyPath string = OVNRbacPkiCaMountPath + "/tls.key"

// MetricsPort is the port used for metrics
MetricsPort int32 = 1981
)
21 changes: 21 additions & 0 deletions internal/controller/ovncontroller_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ func (r *OVNControllerReconciler) SetupWithManager(mgr ctrl.Manager) error {
Owns(&rbacv1.Role{}).
Owns(&rbacv1.RoleBinding{}).
Watches(&ovnv1.OVNDBCluster{}, handler.EnqueueRequestsFromMapFunc(ovnv1.OVNCRNamespaceMapFunc(crs, mgr.GetClient()))).
Watches(&ovnv1.OVNNorthd{}, handler.EnqueueRequestsFromMapFunc(ovnv1.OVNCRNamespaceMapFunc(crs, mgr.GetClient()))).
Watches(
&corev1.Secret{},
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
Expand Down Expand Up @@ -641,6 +642,26 @@ func (r *OVNControllerReconciler) reconcileNormal(ctx context.Context, instance
return ctrl.Result{}, fmt.Errorf("waiting for Topology requirements: %w", err)
}

// When TLS is enabled, RBAC is used for ovn-controller connections to the SB
// database. The RBAC permission rules are populated by ovn-northd, so we must
// wait for northd to be ready before deploying ovn-controller to avoid RBAC
// permission errors during startup.
if instance.Spec.TLS.Enabled() {
northd, err := ovnv1.GetOVNNorthd(ctx, helper, instance.Namespace)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to look up OVNNorthd: %w", err)
}
if northd == nil || northd.Status.ReadyCount == 0 {
Log.Info("OVNNorthd is not ready yet, waiting before deploying OVNController to avoid RBAC errors")
instance.Status.Conditions.Set(condition.FalseCondition(
condition.DeploymentReadyCondition,
condition.RequestedReason,
condition.SeverityInfo,
condition.DeploymentReadyRunningMessage))
return ctrl.Result{RequeueAfter: time.Duration(5) * time.Second}, nil
}
}

// Define a new DaemonSet object for OVNController
dset := daemonset.NewDaemonSet(
ovncontroller.CreateOVNDaemonSet(instance, inputHash, ovnServiceLabels, topology),
Expand Down
Loading