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-20251103091514-244e15fe5d63
12 changes: 12 additions & 0 deletions controllers/barbican_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,18 @@ func (r *BarbicanReconciler) generateServiceConfig(
"EnableSecureRBAC": instance.Spec.BarbicanAPI.EnableSecureRBAC,
}

templateParameters["UseApplicationCredentials"] = false
// Try to get Application Credential for this service (via keystone api helper)
if acData, err := keystonev1.GetApplicationCredentialFromSecret(ctx, r.Client, instance.Namespace, barbican.ServiceName); err != nil {
Log.Error(err, "Failed to get ApplicationCredential for service", "service", barbican.ServiceName)
return err
} else if acData != nil {
templateParameters["UseApplicationCredentials"] = true
templateParameters["ACID"] = acData.ID
templateParameters["ACSecret"] = acData.Secret
Log.Info("Using ApplicationCredentials auth", "service", barbican.ServiceName)
}

// To avoid a json parsing error in kolla files, we always need to set PKCS11ClientDataPath
// This gets overridden in the PKCS11 section below if needed.
templateParameters["PKCS11ClientDataPath"] = barbicanv1beta1.DefaultPKCS11ClientDataPath
Expand Down
54 changes: 53 additions & 1 deletion controllers/barbicanapi_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,19 @@ func (r *BarbicanAPIReconciler) reconcileNormal(ctx context.Context, instance *b

Log.Info(fmt.Sprintf("[API] Got secrets '%s'", instance.Name))

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

//
// TLS input validation
//
Expand Down Expand Up @@ -1026,6 +1039,42 @@ func (r *BarbicanAPIReconciler) SetupWithManager(mgr ctrl.Manager) error {
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 a barbican AC secret by name pattern (ac-barbican-secret)
expectedSecretName := keystonev1.GetACSecretName("barbican")
if name == expectedSecretName {
// get all BarbicanAPI CRs in this namespace
barbicanAPIs := &barbicanv1beta1.BarbicanAPIList{}
listOpts := []client.ListOption{
client.InNamespace(ns),
}
if err := r.List(context.Background(), barbicanAPIs, listOpts...); err != nil {
return nil
}

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

return result
}

return ctrl.NewControllerManagedBy(mgr).
For(&barbicanv1beta1.BarbicanAPI{}).
Owns(&corev1.Service{}).
Expand All @@ -1037,9 +1086,12 @@ func (r *BarbicanAPIReconciler) SetupWithManager(mgr ctrl.Manager) error {
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{})).
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
).
Complete(r)
}

Expand Down
6 changes: 3 additions & 3 deletions controllers/barbicankeystonelistener_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ import (
"github.com/openstack-k8s-operators/barbican-operator/pkg/barbican"
"github.com/openstack-k8s-operators/barbican-operator/pkg/barbicankeystonelistener"
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"

// keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
"github.com/openstack-k8s-operators/lib-common/modules/common"
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
"github.com/openstack-k8s-operators/lib-common/modules/common/deployment"
Expand Down Expand Up @@ -750,8 +748,10 @@ func (r *BarbicanKeystoneListenerReconciler) SetupWithManager(mgr ctrl.Manager)
).
Watches(&topologyv1.Topology{},
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
builder.WithPredicates(predicate.GenerationChangedPredicate{})).
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
).
Complete(r)

}

func (r *BarbicanKeystoneListenerReconciler) findObjectsForSrc(ctx context.Context, src client.Object) []reconcile.Request {
Expand Down
3 changes: 2 additions & 1 deletion controllers/barbicanworker_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,8 @@ func (r *BarbicanWorkerReconciler) SetupWithManager(mgr ctrl.Manager) error {
).
Watches(&topologyv1.Topology{},
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
builder.WithPredicates(predicate.GenerationChangedPredicate{})).
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
).
Complete(r)
}

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,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-20251103091514-244e15fe5d63
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-20251103091514-244e15fe5d63 h1:ug2YPMQJ/+0ifOjFyaPx1YtX0zsVnL02pB2ngacYviw=
github.com/Deydra71/keystone-operator/api v0.0.0-20251103091514-244e15fe5d63/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.20251021145236-2b84ec9fd9bb h1:wToXqX7AS1JV3Kna7RcJfkRart8rSGun2biKNfyY6Zg=
Expand Down
8 changes: 7 additions & 1 deletion templates/barbican/config/00-default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@ connection={{ .DatabaseConnection }}
[keystone_authtoken]
auth_version = v3
auth_url={{ .KeystoneAuthURL }}
auth_type=password
auth_type = {{ if .UseApplicationCredentials }}v3applicationcredential{{ else }}password{{ end }}

{{ if .UseApplicationCredentials -}}
application_credential_id = {{ .ACID }}
application_credential_secret = {{ .ACSecret }}
{{- else -}}
username={{ .ServiceUser }}
user_domain_name=Default
password = {{ .ServicePassword }}
project_name=service
project_domain_name=Default
interface = internal
{{- end }}
{{- end }}

[oslo_messaging_notifications]
driver=messagingv2
Expand Down
117 changes: 117 additions & 0 deletions tests/functional/barbican_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import (
controllers "github.com/openstack-k8s-operators/barbican-operator/controllers"
"github.com/openstack-k8s-operators/barbican-operator/pkg/barbican"
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
mariadb_test "github.com/openstack-k8s-operators/mariadb-operator/api/test/helpers"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
)
Expand Down Expand Up @@ -1589,6 +1591,121 @@ var _ = Describe("Barbican controller", func() {
})
})

When("An ApplicationCredential is created for Barbican", func() {
var (
acName string
acSecretName string
servicePasswordSecret string
passwordSelector string
)
BeforeEach(func() {
servicePasswordSecret = "ac-test-osp-secret" //nolint:gosec // G101
passwordSelector = "BarbicanPassword"

DeferCleanup(k8sClient.Delete, ctx,
CreateBarbicanMessageBusSecret(
barbicanTest.Instance.Namespace,
barbicanTest.RabbitmqSecretName,
),
)
DeferCleanup(k8sClient.Delete, ctx,
CreateBarbicanSecret(
barbicanTest.Instance.Namespace, servicePasswordSecret))

spec := GetDefaultBarbicanSpec()
spec["secret"] = servicePasswordSecret
spec["simpleCryptoBackendSecret"] = servicePasswordSecret
DeferCleanup(th.DeleteInstance,
CreateBarbican(barbicanTest.Instance, spec))
DeferCleanup(
mariadb.DeleteDBService,
mariadb.CreateDBService(
barbicanTest.Instance.Namespace,
GetBarbican(barbicanTest.Instance).Spec.DatabaseInstance,
corev1.ServiceSpec{
Ports: []corev1.ServicePort{{Port: 3306}}}))

DeferCleanup(keystone.DeleteKeystoneAPI,
keystone.CreateKeystoneAPI(barbicanTest.Instance.Namespace),
)

acName = fmt.Sprintf("ac-%s", barbican.ServiceName)
acSecretName = acName + "-secret"
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: barbicanTest.Instance.Namespace,
Name: acSecretName,
},
Data: map[string][]byte{
"AC_ID": []byte("test-ac-id"),
"AC_SECRET": []byte("test-ac-secret"),
},
}
DeferCleanup(k8sClient.Delete, ctx, secret)
Expect(k8sClient.Create(ctx, secret)).To(Succeed())

ac := &keystonev1.KeystoneApplicationCredential{
ObjectMeta: metav1.ObjectMeta{
Namespace: barbicanTest.Instance.Namespace,
Name: acName,
},
Spec: keystonev1.KeystoneApplicationCredentialSpec{
UserName: barbican.ServiceName,
Secret: servicePasswordSecret,
PasswordSelector: passwordSelector,
Roles: []string{"admin", "member"},
AccessRules: []keystonev1.ACRule{{Service: "identity", Method: "POST", Path: "/auth/tokens"}},
ExpirationDays: 30,
GracePeriodDays: 5,
},
}
DeferCleanup(k8sClient.Delete, ctx, ac)
Expect(k8sClient.Create(ctx, ac)).To(Succeed())

fetched := &keystonev1.KeystoneApplicationCredential{}
key := types.NamespacedName{Namespace: ac.Namespace, Name: ac.Name}
Expect(k8sClient.Get(ctx, key, fetched)).To(Succeed())

fetched.Status.SecretName = acSecretName
now := metav1.Now()
readyCond := condition.Condition{
Type: condition.ReadyCondition,
Status: corev1.ConditionTrue,
Reason: condition.ReadyReason,
Message: condition.ReadyMessage,
LastTransitionTime: now,
}
fetched.Status.Conditions = condition.Conditions{readyCond}
Expect(k8sClient.Status().Update(ctx, fetched)).To(Succeed())

infra.SimulateTransportURLReady(barbicanTest.BarbicanTransportURL)
mariadb.SimulateMariaDBAccountCompleted(barbicanTest.BarbicanDatabaseAccount)
mariadb.SimulateMariaDBDatabaseCompleted(barbicanTest.BarbicanDatabaseName)

th.SimulateJobSuccess(barbicanTest.BarbicanDBSync)

keystone.SimulateKeystoneEndpointReady(barbicanTest.BarbicanKeystoneEndpoint)
})

It("should render ApplicationCredential auth in 00-default.conf", func() {
keystone.SimulateKeystoneEndpointReady(barbicanTest.BarbicanKeystoneEndpoint)

Eventually(func(g Gomega) {
cfgSecret := th.GetSecret(barbicanTest.BarbicanAPIConfigSecret)
g.Expect(cfgSecret).NotTo(BeNil())

conf := string(cfgSecret.Data["00-default.conf"])

g.Expect(conf).To(ContainSubstring(
"application_credential_id = test-ac-id"),
)
g.Expect(conf).To(ContainSubstring(
"application_credential_secret = test-ac-secret"),
)
}, timeout, interval).Should(Succeed())
})
})

// Run MariaDBAccount suite tests. these are pre-packaged ginkgo tests
// that exercise standard account create / update patterns that should be
// common to all controllers that ensure MariaDBAccount CRs.
Expand Down
Loading