Skip to content

Commit

Permalink
Merge pull request #409 from booxter/ml2drivers
Browse files Browse the repository at this point in the history
Untangle service from ovn requirement
  • Loading branch information
openshift-merge-bot[bot] authored Oct 2, 2024
2 parents 85910cc + 35accc2 commit cc9057f
Show file tree
Hide file tree
Showing 14 changed files with 1,451 additions and 1,246 deletions.
8 changes: 8 additions & 0 deletions api/bases/neutron.openstack.org_neutronapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2052,6 +2052,14 @@ spec:
default: memcached
description: Memcached instance name.
type: string
ml2MechanismDrivers:
default:
- ovn
description: Ml2MechanismDrivers - list of ml2 drivers to enable.
Using {"ovn"} if not set.
items:
type: string
type: array
networkAttachments:
description: NetworkAttachments is a list of NetworkAttachment resource
names to expose the services to the given network
Expand Down
15 changes: 15 additions & 0 deletions api/v1beta1/neutronapi_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ type NeutronAPISpecCore struct {
// PreserveJobs - do not delete jobs after they finished e.g. to check logs
PreserveJobs bool `json:"preserveJobs"`

// +kubebuilder:validation:Optional
// Ml2MechanismDrivers - list of ml2 drivers to enable. Using {"ovn"} if not set.
// +kubebuilder:default={"ovn"}
Ml2MechanismDrivers []string `json:"ml2MechanismDrivers"`

// +kubebuilder:validation:Optional
// CustomServiceConfig - customize the service config using this parameter to change service defaults,
// or overwrite rendered information using raw OpenStack config format. The content gets added to
Expand Down Expand Up @@ -266,6 +271,16 @@ func (instance NeutronAPI) RbacResourceName() string {
return "neutron-" + instance.Name
}

func (instance NeutronAPI) IsOVNEnabled() bool {
for _, driver := range instance.Spec.Ml2MechanismDrivers {
// TODO: use const
if driver == "ovn" {
return true
}
}
return false
}

// SetupDefaults - initializes any CRD field defaults based on environment variables (the defaulting mechanism itself is implemented via webhooks)
func SetupDefaults() {
// Acquire environmental defaults and initialize Neutron defaults with them
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

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

8 changes: 8 additions & 0 deletions config/crd/bases/neutron.openstack.org_neutronapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2052,6 +2052,14 @@ spec:
default: memcached
description: Memcached instance name.
type: string
ml2MechanismDrivers:
default:
- ovn
description: Ml2MechanismDrivers - list of ml2 drivers to enable.
Using {"ovn"} if not set.
items:
type: string
type: array
networkAttachments:
description: NetworkAttachments is a list of NetworkAttachment resource
names to expose the services to the given network
Expand Down
15 changes: 15 additions & 0 deletions config/samples/neutron_v1beta1_neutronapi_openvswitch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: neutron.openstack.org/v1beta1
kind: NeutronAPI
metadata:
name: neutron
namespace: openstack
spec:
serviceUser: neutron
databaseInstance: openstack
databaseAccount: neutron
rabbitMqClusterName: rabbitmq
memcachedInstance: memcached
preserveJobs: false
secret: neutron-secret
ml2MechanismDrivers:
- openvswitch
104 changes: 71 additions & 33 deletions controllers/neutronapi_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package controllers
import (
"context"
"fmt"
"strings"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -921,6 +922,12 @@ func (r *NeutronAPIReconciler) reconcileNormal(ctx context.Context, instance *ne
return ctrl.Result{}, err
}

err = r.reconcileExternalOVNSecrets(ctx, helper, instance, &secretVars)
if err != nil {
Log.Error(err, "Failed to reconcile external OVN Secrets")
return ctrl.Result{}, err
}

//
// TODO check when/if Init, Update, or Upgrade should/could be skipped
//
Expand Down Expand Up @@ -1111,12 +1118,19 @@ func getDhcpAgentSecretName(instance *neutronv1beta1.NeutronAPI) string {
return getExternalSecretName(instance, "dhcp-agent")
}

func (r *NeutronAPIReconciler) reconcileExternalMetadataAgentSecret(
func (r *NeutronAPIReconciler) reconcileExternalOVNMetadataAgentSecret(
ctx context.Context,
h *helper.Helper,
instance *neutronv1beta1.NeutronAPI,
envVars *map[string]env.Setter,
) error {
if !instance.IsOVNEnabled() {
err := r.deleteExternalSecret(ctx, h, instance, getMetadataAgentSecretName(instance))
if err != nil {
return fmt.Errorf("failed to delete Neutron Metadata Agent external Secret: %w", err)
}
return nil
}
sbCluster, err := ovnclient.GetDBClusterByType(ctx, h, instance.Namespace, map[string]string{}, ovnclient.SBDBType)
if err != nil {
err = r.deleteExternalSecret(ctx, h, instance, getMetadataAgentSecretName(instance))
Expand All @@ -1135,7 +1149,7 @@ func (r *NeutronAPIReconciler) reconcileExternalMetadataAgentSecret(
return nil
}

err = r.ensureExternalMetadataAgentSecret(ctx, h, instance, sbEndpoint, envVars)
err = r.ensureExternalOVNMetadataAgentSecret(ctx, h, instance, sbEndpoint, envVars)
if err != nil {
return fmt.Errorf("failed to ensure Neutron Metadata Agent external Secret: %w", err)
}
Expand All @@ -1148,6 +1162,13 @@ func (r *NeutronAPIReconciler) reconcileExternalOVNAgentSecret(
instance *neutronv1beta1.NeutronAPI,
envVars *map[string]env.Setter,
) error {
if !instance.IsOVNEnabled() {
err := r.deleteExternalSecret(ctx, h, instance, getOVNAgentSecretName(instance))
if err != nil {
return fmt.Errorf("failed to delete Neutron OVN Agent external Secret: %w", err)
}
return nil
}
nbCluster, err := ovnclient.GetDBClusterByType(ctx, h, instance.Namespace, map[string]string{}, ovnclient.NBDBType)
if err != nil {
err = r.deleteExternalSecret(ctx, h, instance, getOVNAgentSecretName(instance))
Expand Down Expand Up @@ -1258,6 +1279,7 @@ func (r *NeutronAPIReconciler) reconcileExternalDhcpAgentSecret(
}

// TODO(ihar) - is there any hashing mechanism for EDP config? do we trigger deploy somehow?
// NOTE(ihar): Add config reconciliation code for any other services here or below
func (r *NeutronAPIReconciler) reconcileExternalSecrets(
ctx context.Context,
h *helper.Helper,
Expand All @@ -1266,27 +1288,38 @@ func (r *NeutronAPIReconciler) reconcileExternalSecrets(
) error {
Log := r.GetLogger(ctx)
// Generate one Secret per external service
err := r.reconcileExternalMetadataAgentSecret(ctx, h, instance, envVars)
if err != nil {
return fmt.Errorf("failed to reconcile Neutron Metadata Agent external Secret: %w", err)
}
err = r.reconcileExternalOVNAgentSecret(ctx, h, instance, envVars)
if err != nil {
return fmt.Errorf("failed to reconcile Neutron OVN Agent external Secret: %w", err)
}
err = r.reconcileExternalSriovAgentSecret(ctx, h, instance, envVars)
err := r.reconcileExternalSriovAgentSecret(ctx, h, instance, envVars)
if err != nil {
return fmt.Errorf("failed to reconcile Neutron SR-IOV Agent external Secret: %w", err)
}
err = r.reconcileExternalDhcpAgentSecret(ctx, h, instance, envVars)
if err != nil {
return fmt.Errorf("failed to reconcile Neutron DHCP Agent external Secret: %w", err)
}
// NOTE(ihar): Add config reconciliation code for any other services here
Log.Info(fmt.Sprintf("Reconciled external secrets for %s", instance.Name))
return nil
}

func (r *NeutronAPIReconciler) reconcileExternalOVNSecrets(
ctx context.Context,
h *helper.Helper,
instance *neutronv1beta1.NeutronAPI,
envVars *map[string]env.Setter,
) error {
Log := r.GetLogger(ctx)
// Generate one Secret per external service
err := r.reconcileExternalOVNMetadataAgentSecret(ctx, h, instance, envVars)
if err != nil {
return fmt.Errorf("failed to reconcile Neutron Metadata Agent external Secret: %w", err)
}
err = r.reconcileExternalOVNAgentSecret(ctx, h, instance, envVars)
if err != nil {
return fmt.Errorf("failed to reconcile Neutron OVN Agent external Secret: %w", err)
}
Log.Info(fmt.Sprintf("Reconciled external OVN secrets for %s", instance.Name))
return nil
}

// TODO(ihar) this function could live in lib-common
func (r *NeutronAPIReconciler) deleteExternalSecret(
ctx context.Context,
Expand Down Expand Up @@ -1346,7 +1379,7 @@ func (r *NeutronAPIReconciler) ensureExternalSecret(
return nil
}

func (r *NeutronAPIReconciler) ensureExternalMetadataAgentSecret(
func (r *NeutronAPIReconciler) ensureExternalOVNMetadataAgentSecret(
ctx context.Context,
h *helper.Helper,
instance *neutronv1beta1.NeutronAPI,
Expand Down Expand Up @@ -1431,23 +1464,6 @@ func (r *NeutronAPIReconciler) generateServiceSecrets(
// Create/update secrets from templates
cmLabels := labels.GetLabels(instance, labels.GetGroupLabel(neutronapi.ServiceName), map[string]string{})

nbCluster, err := ovnclient.GetDBClusterByType(ctx, h, instance.Namespace, map[string]string{}, ovnclient.NBDBType)
if err != nil {
return err
}
nbEndpoint, err := nbCluster.GetInternalEndpoint()
if err != nil {
return err
}

sbCluster, err := ovnclient.GetDBClusterByType(ctx, h, instance.Namespace, map[string]string{}, ovnclient.SBDBType)
if err != nil {
return err
}
sbEndpoint, err := sbCluster.GetInternalEndpoint()
if err != nil {
return err
}
var tlsCfg *tls.Service
if instance.Spec.TLS.Ca.CaBundleSecretName != "" {
tlsCfg = &tls.Service{}
Expand Down Expand Up @@ -1513,11 +1529,33 @@ func (r *NeutronAPIReconciler) generateServiceSecrets(
templateParameters["DbUser"] = databaseAccount.Spec.UserName
templateParameters["DbPassword"] = string(dbSecret.Data[mariadbv1.DatabasePasswordSelector])
templateParameters["Db"] = neutronapi.Database
// TODO: add join func to template library?
templateParameters["Ml2MechanismDrivers"] = strings.Join(instance.Spec.Ml2MechanismDrivers, ",")

// OVN
templateParameters["NBConnection"] = nbEndpoint
templateParameters["SBConnection"] = sbEndpoint
templateParameters["OVNDB_TLS"] = instance.Spec.TLS.Ovn.Enabled()
templateParameters["IsOVN"] = instance.IsOVNEnabled()
if instance.IsOVNEnabled() {
nbCluster, err := ovnclient.GetDBClusterByType(ctx, h, instance.Namespace, map[string]string{}, ovnclient.NBDBType)
if err != nil {
return err
}
nbEndpoint, err := nbCluster.GetInternalEndpoint()
if err != nil {
return err
}

sbCluster, err := ovnclient.GetDBClusterByType(ctx, h, instance.Namespace, map[string]string{}, ovnclient.SBDBType)
if err != nil {
return err
}
sbEndpoint, err := sbCluster.GetInternalEndpoint()
if err != nil {
return err
}
templateParameters["NBConnection"] = nbEndpoint
templateParameters["SBConnection"] = sbEndpoint
templateParameters["OVNDB_TLS"] = instance.Spec.TLS.Ovn.Enabled()
}

// create httpd vhost template parameters
httpdVhostConfig := map[string]interface{}{}
Expand Down
2 changes: 1 addition & 1 deletion pkg/neutronapi/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func Deployment(
}
}

if instance.Spec.TLS.Ovn.Enabled() {
if instance.IsOVNEnabled() && instance.Spec.TLS.Ovn.Enabled() {
svc := tls.Service{
SecretName: *instance.Spec.TLS.Ovn.SecretName,
CaMount: ptr.To("/var/lib/config-data/tls/certs/ovndbca.crt"),
Expand Down
8 changes: 7 additions & 1 deletion templates/neutronapi/config/01-neutron.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ bind_host = localhost
bind_port = 9697
transport_url={{ .TransportURL }}
core_plugin = neutron.plugins.ml2.plugin.Ml2Plugin
{{ if .IsOVN }}
service_plugins = qos,ovn-router,trunk,segments,port_forwarding,log
{{ else }}
service_plugins = qos,trunk,segments,port_forwarding,log
{{ end }}
dns_domain = openstackgate.local
dhcp_agent_notification = false
api_workers = 2
Expand All @@ -16,7 +20,7 @@ connection=mysql+pymysql://{{ .DbUser }}:{{ .DbPassword }}@{{ .DbHost }}/{{ .Db
mysql_wsrep_sync_wait = 1

[ml2]
mechanism_drivers = ovn
mechanism_drivers = {{ .Ml2MechanismDrivers }}
type_drivers = local,flat,vlan,geneve,vxlan
tenant_network_types = geneve,vxlan,vlan,flat
extension_drivers = qos,port_security,dns_domain_ports
Expand All @@ -31,6 +35,7 @@ network_vlan_ranges = datacentre
[ml2_type_vxlan]
vni_ranges = 1:65536

{{ if .IsOVN }}
[ovn]
ovn_nb_connection = {{ .NBConnection }}
ovn_sb_connection = {{ .SBConnection }}
Expand All @@ -44,6 +49,7 @@ ovn_sb_private_key = /etc/pki/tls/private/ovndb.key
ovn_sb_certificate = /etc/pki/tls/certs/ovndb.crt
ovn_sb_ca_cert = /etc/pki/tls/certs/ovndbca.crt
{{- end }}
{{- end }}

[keystone_authtoken]
www_authenticate_uri = {{ .KeystonePublicURL }}
Expand Down
Loading

0 comments on commit cc9057f

Please sign in to comment.