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
8 changes: 8 additions & 0 deletions api/bases/cinder.openstack.org_cinderapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ spec:
spec:
description: CinderAPISpec defines the desired state of CinderAPI
properties:
auth:
description: Auth - Parameters related to authentication
properties:
applicationCredentialSecret:
description: ApplicationCredentialSecret - Secret containing Application
Credential ID and Secret
type: string
type: object
containerImage:
description: ContainerImage - Cinder Container Image URL (will be
set to environmental default if empty)
Expand Down
8 changes: 8 additions & 0 deletions api/bases/cinder.openstack.org_cinders.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ spec:
description: CinderAPI - Spec definition for the API service of this
Cinder deployment
properties:
auth:
description: Auth - Parameters related to authentication
properties:
applicationCredentialSecret:
description: ApplicationCredentialSecret - Secret containing
Application Credential ID and Secret
type: string
type: object
containerImage:
description: ContainerImage - Cinder Container Image URL (will
be set to environmental default if empty)
Expand Down
2 changes: 2 additions & 0 deletions api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,5 @@ replace k8s.io/component-base => k8s.io/component-base v0.31.14 //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-20251211085602-3e1a3e022c81
6 changes: 3 additions & 3 deletions api/v1beta1/cinder_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ import (
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
common_webhook "github.com/openstack-k8s-operators/lib-common/modules/common/webhook"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
common_webhook "github.com/openstack-k8s-operators/lib-common/modules/common/webhook"
)

// CinderDefaults -
Expand Down Expand Up @@ -198,7 +198,7 @@ func (spec *CinderSpec) ValidateCreate(
func (spec *CinderSpecCore) ValidateCreate(
basePath *field.Path,
namespace string,
) ([]string, field.ErrorList){
) ([]string, field.ErrorList) {
var allErrs field.ErrorList
var allWarns admission.Warnings

Expand Down Expand Up @@ -486,7 +486,7 @@ func (spec *CinderSpec) ValidateCinderBackup(basePath *field.Path) ([]string, fi
return allWarns, allErrs
}

func (spec *CinderSpecCore) ValidateCinderBackup(basePath *field.Path)([]string, field.ErrorList) {
func (spec *CinderSpecCore) ValidateCinderBackup(basePath *field.Path) ([]string, field.ErrorList) {
var allErrs field.ErrorList
var allWarns []string

Expand Down
13 changes: 13 additions & 0 deletions api/v1beta1/cinderapi_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ type CinderAPITemplateCore struct {
// +operator-sdk:csv:customresourcedefinitions:type=spec
// TLS - Parameters related to the TLS
TLS tls.API `json:"tls,omitempty"`

// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
// Auth - Parameters related to authentication
Auth AuthSpec `json:"auth,omitempty"`
}

// CinderAPITemplate defines the input parameters for the Cinder API service
Expand All @@ -61,6 +66,14 @@ type APIOverrideSpec struct {
Service map[service.Endpoint]service.RoutedOverrideSpec `json:"service,omitempty"`
}

// AuthSpec defines authentication parameters
type AuthSpec struct {
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
// ApplicationCredentialSecret - Secret containing Application Credential ID and Secret
ApplicationCredentialSecret string `json:"applicationCredentialSecret,omitempty"`
}

// CinderAPISpec defines the desired state of CinderAPI
type CinderAPISpec struct {
// Common input parameters for all Cinder services
Expand Down
16 changes: 16 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/cinder.openstack.org_cinderapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ spec:
spec:
description: CinderAPISpec defines the desired state of CinderAPI
properties:
auth:
description: Auth - Parameters related to authentication
properties:
applicationCredentialSecret:
description: ApplicationCredentialSecret - Secret containing Application
Credential ID and Secret
type: string
type: object
containerImage:
description: ContainerImage - Cinder Container Image URL (will be
set to environmental default if empty)
Expand Down
8 changes: 8 additions & 0 deletions config/crd/bases/cinder.openstack.org_cinders.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ spec:
description: CinderAPI - Spec definition for the API service of this
Cinder deployment
properties:
auth:
description: Auth - Parameters related to authentication
properties:
applicationCredentialSecret:
description: ApplicationCredentialSecret - Secret containing
Application Credential ID and Secret
type: string
type: object
containerImage:
description: ContainerImage - Cinder Container Image URL (will
be set to environmental default if empty)
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,5 @@ replace k8s.io/component-base => k8s.io/component-base v0.31.14 //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-20251211085602-3e1a3e022c81
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-20251211085602-3e1a3e022c81 h1:plax+NFgJJL1SrERyXAnf3jOHRhLTtBlJ2oc7d84EoU=
github.com/Deydra71/keystone-operator/api v0.0.0-20251211085602-3e1a3e022c81/go.mod h1:b98Jl8eyUw8V07l9YiuQnoMlnWC748oV8IhXH15NCC4=
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/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
Expand Down Expand Up @@ -120,8 +122,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.20260108154501-11e5091cddf1 h1:zAbZVtpldi1TU/CO9aU2ZByzcsi+N3aIv6snpSjBVLY=
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260108154501-11e5091cddf1/go.mod h1:ZXwFlspJCdZEUjMbmaf61t5AMB4u2vMyAMMoe/vJroE=
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260109123729-8c46aa6cb459 h1:5p1EssFXwriFNoxDZsO8a4r0GnruIVD/d7dNBzcglR8=
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260109123729-8c46aa6cb459/go.mod h1:djqR/hwPpIld/siGG6JTa3YuI6QGMf4e7aphVRBhlAk=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35 h1:pF3mJ3nwq6r4qwom+rEWZNquZpcQW/iftHlJ1KPIDsk=
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:kycZyoe7OZdW1HUghr2nI3N7wSJtNahXf6b/ypD14f4=
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35 h1:IdcI8DFvW8rXtchONSzbDmhhRp1YyO2YaBJDBXr44Gk=
Expand Down
57 changes: 22 additions & 35 deletions internal/controller/cinder_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/handler"
Expand Down Expand Up @@ -251,6 +250,7 @@ const (
tlsAPIInternalField = ".spec.tls.api.internal.secretName"
tlsAPIPublicField = ".spec.tls.api.public.secretName"
topologyField = ".spec.topologyRef.Name"
authAppCredSecretField = ".spec.auth.applicationCredentialSecret" // #nosec G101
)

var (
Expand All @@ -265,6 +265,7 @@ var (
tlsAPIInternalField,
tlsAPIPublicField,
topologyField,
authAppCredSecretField,
}
)

Expand Down Expand Up @@ -368,43 +369,9 @@ func (r *CinderReconciler) SetupWithManager(mgr ctrl.Manager) error {
handler.EnqueueRequestsFromMapFunc(transportURLSecretFn)).
Watches(&memcachedv1.Memcached{},
handler.EnqueueRequestsFromMapFunc(memcachedFn)).
Watches(&keystonev1.KeystoneAPI{},
handler.EnqueueRequestsFromMapFunc(r.findObjectForSrc),
builder.WithPredicates(keystonev1.KeystoneAPIStatusChangedPredicate)).
Complete(r)
}

func (r *CinderReconciler) findObjectForSrc(ctx context.Context, src client.Object) []reconcile.Request {
requests := []reconcile.Request{}

Log := r.GetLogger(ctx)

crList := &cinderv1beta1.CinderList{}
listOps := &client.ListOptions{
Namespace: src.GetNamespace(),
}
err := r.List(ctx, crList, listOps)
if err != nil {
Log.Error(err, fmt.Sprintf("listing %s for namespace: %s", crList.GroupVersionKind().Kind, src.GetNamespace()))
return requests
}

for _, item := range crList.Items {
Log.Info(fmt.Sprintf("input source %s changed, reconcile: %s - %s", src.GetName(), item.GetName(), item.GetNamespace()))

requests = append(requests,
reconcile.Request{
NamespacedName: types.NamespacedName{
Name: item.GetName(),
Namespace: item.GetNamespace(),
},
},
)
}

return requests
}

func (r *CinderReconciler) reconcileDelete(ctx context.Context, instance *cinderv1beta1.Cinder, helper *helper.Helper) (ctrl.Result, error) {
Log := r.GetLogger(ctx)

Expand Down Expand Up @@ -1125,6 +1092,26 @@ func (r *CinderReconciler) generateServiceConfigs(
}
templateParameters["VHosts"] = httpdVhostConfig

// Retrieve Application Credential data from CinderAPI Auth section if specified
Log := r.GetLogger(ctx)
if instance.Spec.CinderAPI.Auth.ApplicationCredentialSecret != "" {
acSecret := &corev1.Secret{}
key := types.NamespacedName{Namespace: instance.Namespace, Name: instance.Spec.CinderAPI.Auth.ApplicationCredentialSecret}
if err := h.GetClient().Get(ctx, key, acSecret); err != nil {
if !k8s_errors.IsNotFound(err) {
Log.Error(err, "Failed to get ApplicationCredential secret", "secret", key)
}
} else {
acID, okID := acSecret.Data[keystonev1.ACIDSecretKey]
acSecretData, okSecret := acSecret.Data[keystonev1.ACSecretSecretKey]
if okID && len(acID) > 0 && okSecret && len(acSecretData) > 0 {
templateParameters["ApplicationCredentialID"] = string(acID)
templateParameters["ApplicationCredentialSecret"] = string(acSecretData)
Log.Info("Using ApplicationCredentials auth from CinderAPI spec", "secret", instance.Spec.CinderAPI.Auth.ApplicationCredentialSecret)
}
}
}

var notificationInstanceURLSecret *corev1.Secret
if instance.Status.NotificationsURLSecret != nil {
// Get a notificationInstanceURLSecret only if rabbitMQ referenced in
Expand Down
22 changes: 22 additions & 0 deletions internal/controller/cinderapi_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,18 @@ func (r *CinderAPIReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Man
return err
}

// index authAppCredSecretField
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &cinderv1beta1.CinderAPI{}, authAppCredSecretField, func(rawObj client.Object) []string {
// Extract the application credential secret name from the spec, if one is provided
cr := rawObj.(*cinderv1beta1.CinderAPI)
if cr.Spec.Auth.ApplicationCredentialSecret == "" {
return nil
}
return []string{cr.Spec.Auth.ApplicationCredentialSecret}
}); err != nil {
return err
}

return ctrl.NewControllerManagedBy(mgr).
For(&cinderv1beta1.CinderAPI{}).
Owns(&keystonev1.KeystoneService{}).
Expand Down Expand Up @@ -899,6 +911,16 @@ func (r *CinderAPIReconciler) reconcileNormal(ctx context.Context, instance *cin
// normal reconcile tasks
//

// Verify Application Credential secret if specified
if instance.Spec.Auth.ApplicationCredentialSecret != "" {
acSecret := types.NamespacedName{Namespace: instance.Namespace, Name: instance.Spec.Auth.ApplicationCredentialSecret}
acHash, _, err := secret.VerifySecret(ctx, acSecret, []string{keystonev1.ACIDSecretKey, keystonev1.ACSecretSecretKey}, helper.GetClient(), 0)
if err == nil && acHash != "" {
// AC secret exists and is valid - add to configVars for hash tracking
configVars[instance.Spec.Auth.ApplicationCredentialSecret] = env.SetValue(acHash)
}
}

//
// create hash over all the different input resources to identify if any those changed
// and a restart/recreate is required.
Expand Down
28 changes: 23 additions & 5 deletions templates/cinder/config/00-global-defaults.conf
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,18 @@ auth_url = {{ .KeystoneInternalURL }}
memcached_servers = {{ .MemcachedServers }}
memcache_pool_dead_retry = 10
memcache_pool_conn_get_timeout = 2
{{ if (index . "ApplicationCredentialID") -}}
auth_type = v3applicationcredential
application_credential_id = {{ .ApplicationCredentialID }}
application_credential_secret = {{ .ApplicationCredentialSecret }}
{{ else -}}
auth_type = password
username = {{ .ServiceUser }}
password = {{ .ServicePassword }}
project_domain_name = Default
user_domain_name = Default
project_name = service
username = {{ .ServiceUser }}
password = {{ .ServicePassword }}
{{ end -}}
service_token_roles_required = true
interface = internal
{{if (index . "MemcachedAuthCert")}}
Expand All @@ -93,20 +99,32 @@ memcache_tls_enabled = true

[nova]
interface = internal
auth_type = password
auth_url = {{ .KeystoneInternalURL }}
{{ if (index . "ApplicationCredentialID") -}}
auth_type = v3applicationcredential
application_credential_id = {{ .ApplicationCredentialID }}
application_credential_secret = {{ .ApplicationCredentialSecret }}
{{ else -}}
auth_type = password
username = {{ .ServiceUser }}
password = {{ .ServicePassword }}
user_domain_name = Default
project_name = service
project_domain_name = Default
{{ end -}}

[service_user]
send_service_user_token = True
auth_url = {{ .KeystoneInternalURL }}
{{ if (index . "ApplicationCredentialID") -}}
auth_type = v3applicationcredential
application_credential_id = {{ .ApplicationCredentialID }}
application_credential_secret = {{ .ApplicationCredentialSecret }}
{{ else -}}
auth_type = password
username = {{ .ServiceUser }}
password = {{ .ServicePassword }}
project_domain_name = Default
user_domain_name = Default
project_name = service
username = {{ .ServiceUser }}
password = {{ .ServicePassword }}
{{ end -}}
Loading
Loading