Skip to content
Open
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
2 changes: 2 additions & 0 deletions api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,5 @@ replace k8s.io/component-base => k8s.io/component-base v0.31.13 //allow-merging
replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec //allow-merging

replace k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20250627150254-e9823e99808e //allow-merging

replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/Deydra71/keystone-operator/api v0.0.0-20251105080148-59c1e577e327
63 changes: 62 additions & 1 deletion controllers/amphoracontroller_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,19 @@ func (r *OctaviaAmphoraControllerReconciler) reconcileNormal(ctx context.Context
// Handle secrets
secretsVars := make(map[string]env.Setter)

// Verify Application Credentials if available
ctrlResult, err := keystonev1.VerifyApplicationCredentialsForService(
ctx,
r.Client,
instance.Namespace,
octavia.ServiceName,
&secretsVars,
10*time.Second,
)
if (err != nil || ctrlResult != ctrl.Result{}) {
return ctrlResult, err
}

defaultFlavorID, err := amphoracontrollers.EnsureFlavors(ctx, instance, &Log, helper)
if err != nil {
Log.Info(fmt.Sprintf("Cannot define flavors: %s", err))
Expand Down Expand Up @@ -388,7 +401,7 @@ func (r *OctaviaAmphoraControllerReconciler) reconcileNormal(ctx context.Context
instance.Status.Conditions.MarkTrue(condition.ServiceConfigReadyCondition, condition.ServiceConfigReadyMessage)

// Handle service update
ctrlResult, err := r.reconcileUpdate(ctx)
ctrlResult, err = r.reconcileUpdate(ctx)
if err != nil {
return ctrlResult, err
} else if (ctrlResult != ctrl.Result{}) {
Expand Down Expand Up @@ -704,6 +717,16 @@ func (r *OctaviaAmphoraControllerReconciler) generateServiceSecrets(
templateParameters["Password"] = servicePassword
templateParameters["KeystoneInternalURL"] = keystoneInternalURL
templateParameters["KeystonePublicURL"] = keystonePublicURL

// Check for Application Credentials
if acData, err := keystonev1.GetApplicationCredentialFromSecret(ctx, helper.GetClient(), instance.Namespace, octavia.ServiceName); err != nil {
Log.Error(err, "Failed to get ApplicationCredential for service", "service", octavia.ServiceName)
return err
} else if acData != nil {
templateParameters["ApplicationCredentialID"] = acData.ID
templateParameters["ApplicationCredentialSecret"] = acData.Secret
Log.Info("Using ApplicationCredentials auth", "service", octavia.ServiceName)
}
templateParameters["ServiceRoleName"] = spec.Role
templateParameters["LbMgmtNetworkId"] = templateVars.LbMgmtNetworkID
templateParameters["LbSecurityGroupId"] = templateVars.LbSecurityGroupID
Expand Down Expand Up @@ -857,6 +880,42 @@ func (r *OctaviaAmphoraControllerReconciler) SetupWithManager(mgr ctrl.Manager)
return nil
}

// Application Credential secret watching function
acSecretFn := func(_ context.Context, o client.Object) []reconcile.Request {
name := o.GetName()
ns := o.GetNamespace()
result := []reconcile.Request{}

// Only handle Secret objects
if _, isSecret := o.(*corev1.Secret); !isSecret {
return nil
}

// Check if this is an octavia AC secret by name pattern (ac-octavia-secret)
expectedSecretName := keystonev1.GetACSecretName(octavia.ServiceName)
if name == expectedSecretName {
// get all OctaviaAmphoraController CRs in this namespace
amphoraControllers := &octaviav1.OctaviaAmphoraControllerList{}
listOpts := []client.ListOption{
client.InNamespace(ns),
}
if err := r.List(context.Background(), amphoraControllers, listOpts...); err != nil {
return nil
}

// Enqueue reconcile for all amphora controller instances
for _, cr := range amphoraControllers.Items {
objKey := client.ObjectKey{
Namespace: ns,
Name: cr.Name,
}
result = append(result, reconcile.Request{NamespacedName: objKey})
}
}

return result
}

return ctrl.NewControllerManagedBy(mgr).
For(&octaviav1.OctaviaAmphoraController{}).
Owns(&corev1.Service{}).
Expand All @@ -871,6 +930,8 @@ func (r *OctaviaAmphoraControllerReconciler) SetupWithManager(mgr ctrl.Manager)
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
).
Watches(&corev1.Secret{},
handler.EnqueueRequestsFromMapFunc(acSecretFn)).
Watches(&topologyv1.Topology{},
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
builder.WithPredicates(predicate.GenerationChangedPredicate{})).
Expand Down
66 changes: 64 additions & 2 deletions controllers/octaviaapi_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,42 @@ func (r *OctaviaAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
return err
}

// Application Credential secret watching function
acSecretFn := func(_ context.Context, o client.Object) []reconcile.Request {
name := o.GetName()
ns := o.GetNamespace()
result := []reconcile.Request{}

// Only handle Secret objects
if _, isSecret := o.(*corev1.Secret); !isSecret {
return nil
}

// Check if this is an octavia AC secret by name pattern (ac-octavia-secret)
expectedSecretName := keystonev1.GetACSecretName(octavia.ServiceName)
if name == expectedSecretName {
// get all OctaviaAPI CRs in this namespace
octaviaAPIs := &octaviav1.OctaviaAPIList{}
listOpts := []client.ListOption{
client.InNamespace(ns),
}
if err := r.List(context.Background(), octaviaAPIs, listOpts...); err != nil {
return nil
}

// Enqueue reconcile for all octavia API instances
for _, cr := range octaviaAPIs.Items {
objKey := client.ObjectKey{
Namespace: ns,
Name: cr.Name,
}
result = append(result, reconcile.Request{NamespacedName: objKey})
}
}

return result
}

return ctrl.NewControllerManagedBy(mgr).
For(&octaviav1.OctaviaAPI{}).
Owns(&keystonev1.KeystoneService{}).
Expand All @@ -316,6 +352,8 @@ func (r *OctaviaAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
).
Watches(&corev1.Secret{},
handler.EnqueueRequestsFromMapFunc(acSecretFn)).
Watches(&topologyv1.Topology{},
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
builder.WithPredicates(predicate.GenerationChangedPredicate{})).
Expand Down Expand Up @@ -650,6 +688,19 @@ func (r *OctaviaAPIReconciler) reconcileNormal(ctx context.Context, instance *oc
// Secrets
secretsVars := make(map[string]env.Setter)

// Verify Application Credentials if available
ctrlResult, err := keystonev1.VerifyApplicationCredentialsForService(
ctx,
r.Client,
instance.Namespace,
octavia.ServiceName,
&secretsVars,
10*time.Second,
)
if (err != nil || ctrlResult != ctrl.Result{}) {
return ctrlResult, err
}

//
// TLS input validation
//
Expand Down Expand Up @@ -722,7 +773,7 @@ func (r *OctaviaAPIReconciler) reconcileNormal(ctx context.Context, instance *oc
// - %-scripts secret holding scripts to e.g. bootstrap the service
// - %-config secret holding minimal octavia config required to get the service up, user can add additional files to be added to the service
//
err := r.generateServiceSecrets(ctx, instance, helper, &secretsVars)
err = r.generateServiceSecrets(ctx, instance, helper, &secretsVars)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.ServiceConfigReadyCondition,
Expand Down Expand Up @@ -794,7 +845,7 @@ func (r *OctaviaAPIReconciler) reconcileNormal(ctx context.Context, instance *oc
}

// Handle service init
ctrlResult, err := r.reconcileInit(ctx, instance, helper, serviceLabels)
ctrlResult, err = r.reconcileInit(ctx, instance, helper, serviceLabels)
if err != nil {
return ctrlResult, err
} else if (ctrlResult != ctrl.Result{}) {
Expand Down Expand Up @@ -1105,6 +1156,17 @@ func (r *OctaviaAPIReconciler) generateServiceSecrets(
templateParameters["TenantDomainName"] = instance.Spec.TenantDomainName
templateParameters["KeystoneInternalURL"] = keystoneInternalURL
templateParameters["KeystonePublicURL"] = keystonePublicURL

// Check for Application Credentials
if acData, err := keystonev1.GetApplicationCredentialFromSecret(ctx, h.GetClient(), instance.Namespace, octavia.ServiceName); err != nil {
Log.Error(err, "Failed to get ApplicationCredential for service", "service", octavia.ServiceName)
return err
} else if acData != nil {
templateParameters["ApplicationCredentialID"] = acData.ID
templateParameters["ApplicationCredentialSecret"] = acData.Secret
Log.Info("Using ApplicationCredentials auth", "service", octavia.ServiceName)
}

templateParameters["NBConnection"], err = nbCluster.GetInternalEndpoint()
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,5 @@ replace k8s.io/component-base => k8s.io/component-base v0.31.13 //allow-merging
replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec //allow-merging

replace k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20250627150254-e9823e99808e //allow-merging

replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/Deydra71/keystone-operator/api v0.0.0-20251105080148-59c1e577e327
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/Deydra71/keystone-operator/api v0.0.0-20251105080148-59c1e577e327 h1:Czf2Y2e7S4l6aXChDtdh+b5RKtIA+3HQtG9z9jZ80Lc=
github.com/Deydra71/keystone-operator/api v0.0.0-20251105080148-59c1e577e327/go.mod h1:FMFoO4MjEQ85JpdLtDHxYSZxvJ9KzHua+HdKhpl0KRI=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down Expand Up @@ -100,8 +102,6 @@ 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.20251030184102-82d2cbaafd35 h1:QFFGu93A+XCvDUxZIgfBE4gB5hEdVQAIw+E8dF1kP/E=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251030184102-82d2cbaafd35/go.mod h1:qq8BCRxTEmLRriUsQ4HeDUzqltWg32MQPDTMhgbBGK4=
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251027074845-ed8154b20ad1 h1:QohvX44nxoV2GwvvOURGXYyDuCn4SCrnwubTKJtzehY=
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251027074845-ed8154b20ad1/go.mod h1:FMFoO4MjEQ85JpdLtDHxYSZxvJ9KzHua+HdKhpl0KRI=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251027074416-ab5c045dbe00 h1:Xih6tYYqiDVllo4fDGHqTPL+M2biO5YLOUmbiTqrW/I=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251027074416-ab5c045dbe00/go.mod h1:PMoNILOdQ1Ij7DyrKgljN6RAiq8pFM2AGsUb6mcxe98=
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251027074416-ab5c045dbe00 h1:YwkGrTpeeAq9bk09u9Hp96BEZb8X3XgnMfoyxypelVM=
Expand Down
14 changes: 13 additions & 1 deletion templates/octaviaamphoracontroller/config/octavia.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@ controller_ip_port_list={{ .ControllerIPList }}
[keystone_authtoken]
www_authenticate_uri={{ .KeystonePublicURL }}
auth_url={{ .KeystoneInternalURL }}
{{ if (index . "ApplicationCredentialID") -}}
auth_type=v3applicationcredential
application_credential_id={{ .ApplicationCredentialID }}
application_credential_secret={{ .ApplicationCredentialSecret }}
{{- else -}}
auth_type=password
username={{ .ServiceUser }}
password={{ .Password }}
{{- end }}
project_name={{ .TenantName }}
project_domain_name={{ .TenantDomainName }}
user_domain_name=Default
auth_type=password
# memcache_use_advanced_pool=True
# memcached_servers=FIXMEhost1:11211
# region_name=regionOne
Expand Down Expand Up @@ -74,9 +80,15 @@ disable_local_log_storage=False
project_name={{ .TenantName }}
project_domain_name={{ .TenantDomainName }}
user_domain_name=Default
{{ if (index . "ApplicationCredentialID") -}}
auth_type=v3applicationcredential
application_credential_id={{ .ApplicationCredentialID }}
application_credential_secret={{ .ApplicationCredentialSecret }}
{{- else -}}
password={{ .Password }}
username=octavia
auth_type=password
{{- end }}
auth_url={{ .KeystoneInternalURL }}/v3
region_name=regionOne

Expand Down
14 changes: 13 additions & 1 deletion templates/octaviaapi/config/octavia.conf
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ stats_update_threads=4
[keystone_authtoken]
www_authenticate_uri={{ .KeystonePublicURL }}
auth_url={{ .KeystoneInternalURL }}
{{ if (index . "ApplicationCredentialID") -}}
auth_type=v3applicationcredential
application_credential_id={{ .ApplicationCredentialID }}
application_credential_secret={{ .ApplicationCredentialSecret }}
{{- else -}}
auth_type=password
username={{ .ServiceUser }}
password={{ .Password }}
{{- end }}
project_name={{ .TenantName }}
project_domain_name={{ .TenantDomainName }}
user_domain_name=Default
auth_type=password
# memcache_use_advanced_pool=True
# memcached_servers=FIXMEhost1:11211
# region_name=regionOne
Expand Down Expand Up @@ -76,9 +82,15 @@ disable_local_log_storage=False
project_name={{ .TenantName }}
project_domain_name={{ .TenantDomainName }}
user_domain_name=Default
{{ if (index . "ApplicationCredentialID") -}}
auth_type=v3applicationcredential
application_credential_id={{ .ApplicationCredentialID }}
application_credential_secret={{ .ApplicationCredentialSecret }}
{{- else -}}
password={{ .Password }}
username=octavia
auth_type=password
{{- end }}
auth_url={{ .KeystoneInternalURL }}/v3
region_name=regionOne

Expand Down
Loading