Skip to content

Commit 506faa1

Browse files
committed
Application Credential support
Signed-off-by: Veronika Fisarova <[email protected]>
1 parent 94a5417 commit 506faa1

File tree

11 files changed

+364
-129
lines changed

11 files changed

+364
-129
lines changed

api/go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/onsi/ginkgo/v2 v2.20.1
77
github.com/onsi/gomega v1.34.1
88
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250909143828-e33d35ffd64f
9-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250730071847-837b07f8d72f
9+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250823121217-7e1cd2e3dd03
1010
k8s.io/api v0.29.15
1111
k8s.io/apimachinery v0.29.15
1212
k8s.io/client-go v0.29.15
@@ -76,3 +76,5 @@ require (
7676
// mschuppert: map to latest commit from release-4.16 tag
7777
// must consistent within modules and service operators
7878
replace github.com/openshift/api => github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094 //allow-merging
79+
80+
replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/Deydra71/keystone-operator/api v0.0.0-20251002062345-bf9333e0a92e

api/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
7474
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
7575
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250909143828-e33d35ffd64f h1:chuu4iBT5sXHYw8aPeP/pWC+S3yGo6hdy39foP7c5vs=
7676
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250909143828-e33d35ffd64f/go.mod h1:Dv8qpmBIQy3Jv/EyQnOyc0w61X8vyfxpjcIQONP5CwY=
77-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250730071847-837b07f8d72f h1:DW8aNjEtDFrWiZ6vWuOXwdRB4eBD0n+bA9foQkOEx6U=
78-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250730071847-837b07f8d72f/go.mod h1:P+7F1wiwZUxOy4myYXFyc/uBtGATDFpk3yAllXe1Vzk=
77+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250823121217-7e1cd2e3dd03 h1:9VanDdvg1APf9B1nzGElLvWr6dM5GsSayMLSV/nJZnE=
78+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250823121217-7e1cd2e3dd03/go.mod h1:Z+rmtn3qhuPZfx2EDVmloUh2MkYbvDMgcpJneRYerS0=
7979
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
8080
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
8181
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

config/rbac/role.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ rules:
1616
- patch
1717
- update
1818
- watch
19+
- apiGroups:
20+
- ""
21+
resources:
22+
- secrets
23+
verbs:
24+
- get
25+
- list
26+
- watch
1927
- apiGroups:
2028
- ""
2129
resources:
@@ -211,6 +219,14 @@ rules:
211219
- get
212220
- list
213221
- watch
222+
- apiGroups:
223+
- keystone.openstack.org
224+
resources:
225+
- keystoneapplicationcredentials
226+
verbs:
227+
- get
228+
- list
229+
- watch
214230
- apiGroups:
215231
- keystone.openstack.org
216232
resources:

controllers/barbican_controller.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ func (r *BarbicanReconciler) GetLogger(ctx context.Context) logr.Logger {
9999
//+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapis,verbs=get;list;watch;
100100
//+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneservices,verbs=get;list;watch;create;update;patch;delete;
101101
//+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneendpoints,verbs=get;list;watch;create;update;patch;delete;
102+
//+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapplicationcredentials,verbs=get;list;watch
102103
//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete;
103104
//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete;
104105
//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete;
@@ -113,6 +114,7 @@ func (r *BarbicanReconciler) GetLogger(ctx context.Context) logr.Logger {
113114

114115
// service account, role, rolebinding
115116
//+kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;patch
117+
//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
116118
//+kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles,verbs=get;list;watch;create;update;patch
117119
//+kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch
118120
//+kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid,resources=securitycontextconstraints,verbs=use
@@ -709,6 +711,18 @@ func (r *BarbicanReconciler) generateServiceConfig(
709711
"EnableSecureRBAC": instance.Spec.BarbicanAPI.EnableSecureRBAC,
710712
}
711713

714+
templateParameters["UseApplicationCredentials"] = false
715+
// Try to get Application Credential for this service (via keystone api helper)
716+
if acData, err := keystonev1.GetApplicationCredentialFromSecret(ctx, r.Client, instance.Namespace, barbican.ServiceName); err != nil {
717+
Log.Error(err, "Failed to get ApplicationCredential for service", "service", barbican.ServiceName)
718+
return err
719+
} else if acData != nil {
720+
templateParameters["UseApplicationCredentials"] = true
721+
templateParameters["ACID"] = acData.ID
722+
templateParameters["ACSecret"] = acData.Secret
723+
Log.Info("Using ApplicationCredentials auth", "service", barbican.ServiceName)
724+
}
725+
712726
// To avoid a json parsing error in kolla files, we always need to set PKCS11ClientDataPath
713727
// This gets overridden in the PKCS11 section below if needed.
714728
templateParameters["PKCS11ClientDataPath"] = barbicanv1beta1.DefaultPKCS11ClientDataPath

controllers/barbicanapi_controller.go

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,11 @@ func (r *BarbicanAPIReconciler) reconcileNormal(ctx context.Context, instance *b
617617

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

620+
// Verify Application Credentials if available
621+
if res, err := r.verifyApplicationCredentials(ctx, helper, instance, &configVars); err != nil || res.RequeueAfter > 0 {
622+
return res, err
623+
}
624+
620625
//
621626
// TLS input validation
622627
//
@@ -1007,6 +1012,42 @@ func (r *BarbicanAPIReconciler) SetupWithManager(mgr ctrl.Manager) error {
10071012
return err
10081013
}
10091014

1015+
// Application Credential secret watching function
1016+
acSecretFn := func(_ context.Context, o client.Object) []reconcile.Request {
1017+
name := o.GetName()
1018+
ns := o.GetNamespace()
1019+
result := []reconcile.Request{}
1020+
1021+
// Only handle Secret objects
1022+
if _, isSecret := o.(*corev1.Secret); !isSecret {
1023+
return nil
1024+
}
1025+
1026+
// Check if this is a barbican AC secret by name pattern (ac-barbican-secret)
1027+
expectedSecretName := keystonev1.GetACSecretName("barbican")
1028+
if name == expectedSecretName {
1029+
// get all BarbicanAPI CRs in this namespace
1030+
barbicanAPIs := &barbicanv1beta1.BarbicanAPIList{}
1031+
listOpts := []client.ListOption{
1032+
client.InNamespace(ns),
1033+
}
1034+
if err := r.Client.List(context.Background(), barbicanAPIs, listOpts...); err != nil {
1035+
return nil
1036+
}
1037+
1038+
// Enqueue reconcile for all barbican API instances
1039+
for _, cr := range barbicanAPIs.Items {
1040+
objKey := client.ObjectKey{
1041+
Namespace: ns,
1042+
Name: cr.Name,
1043+
}
1044+
result = append(result, reconcile.Request{NamespacedName: objKey})
1045+
}
1046+
}
1047+
1048+
return result
1049+
}
1050+
10101051
return ctrl.NewControllerManagedBy(mgr).
10111052
For(&barbicanv1beta1.BarbicanAPI{}).
10121053
Owns(&corev1.Service{}).
@@ -1018,9 +1059,12 @@ func (r *BarbicanAPIReconciler) SetupWithManager(mgr ctrl.Manager) error {
10181059
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
10191060
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
10201061
).
1062+
Watches(&corev1.Secret{},
1063+
handler.EnqueueRequestsFromMapFunc(acSecretFn)).
10211064
Watches(&topologyv1.Topology{},
10221065
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
1023-
builder.WithPredicates(predicate.GenerationChangedPredicate{})).
1066+
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
1067+
).
10241068
Complete(r)
10251069
}
10261070

@@ -1057,3 +1101,46 @@ func (r *BarbicanAPIReconciler) findObjectsForSrc(ctx context.Context, src clien
10571101

10581102
return requests
10591103
}
1104+
1105+
// verifyApplicationCredentials checks if ApplicationCredential secret exists and adds it to configVars
1106+
// The AC secret is created by the keystone-operator's AC controller when the AC is ready.
1107+
// If the secret exists and is valid, we use AC auth. Otherwise, we fall back to password auth.
1108+
func (r *BarbicanAPIReconciler) verifyApplicationCredentials(
1109+
ctx context.Context,
1110+
_ *helper.Helper,
1111+
instance *barbicanv1beta1.BarbicanAPI,
1112+
configVars *map[string]env.Setter,
1113+
) (ctrl.Result, error) {
1114+
log := r.GetLogger(ctx)
1115+
1116+
// Check if AC secret exists (created by keystone AC controller)
1117+
acSecretName := keystonev1.GetACSecretName(barbican.ServiceName)
1118+
secretKey := types.NamespacedName{Namespace: instance.Namespace, Name: acSecretName}
1119+
1120+
hash, res, err := secret.VerifySecret(
1121+
ctx,
1122+
secretKey,
1123+
[]string{"AC_ID", "AC_SECRET"},
1124+
r.Client,
1125+
10*time.Second,
1126+
)
1127+
1128+
// VerifySecret returns res.RequeueAfter > 0 when secret not found (not an error)
1129+
// For AC, this is optional, so we just skip it instead of requeueing
1130+
if res.RequeueAfter > 0 {
1131+
log.Info("ApplicationCredential secret not found, using password auth")
1132+
return ctrl.Result{}, nil
1133+
}
1134+
1135+
if err != nil {
1136+
// Actual error (not NotFound) - log and continue with password auth
1137+
log.Info("ApplicationCredential secret verification failed, continuing with password auth", "error", err.Error())
1138+
return ctrl.Result{}, nil
1139+
}
1140+
1141+
// AC secret exists and is valid - add to configVars for hash tracking
1142+
(*configVars)["secret-"+acSecretName] = env.SetValue(hash)
1143+
log.Info("Using ApplicationCredential authentication")
1144+
1145+
return ctrl.Result{}, nil
1146+
}

controllers/barbicankeystonelistener_controller.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import (
2727
"github.com/openstack-k8s-operators/barbican-operator/pkg/barbican"
2828
"github.com/openstack-k8s-operators/barbican-operator/pkg/barbicankeystonelistener"
2929
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
30-
31-
// keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
3230
"github.com/openstack-k8s-operators/lib-common/modules/common"
3331
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
3432
"github.com/openstack-k8s-operators/lib-common/modules/common/deployment"
@@ -730,8 +728,10 @@ func (r *BarbicanKeystoneListenerReconciler) SetupWithManager(mgr ctrl.Manager)
730728
).
731729
Watches(&topologyv1.Topology{},
732730
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
733-
builder.WithPredicates(predicate.GenerationChangedPredicate{})).
731+
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
732+
).
734733
Complete(r)
734+
735735
}
736736

737737
func (r *BarbicanKeystoneListenerReconciler) findObjectsForSrc(ctx context.Context, src client.Object) []reconcile.Request {

controllers/barbicanworker_controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,8 @@ func (r *BarbicanWorkerReconciler) SetupWithManager(mgr ctrl.Manager) error {
752752
).
753753
Watches(&topologyv1.Topology{},
754754
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
755-
builder.WithPredicates(predicate.GenerationChangedPredicate{})).
755+
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
756+
).
756757
Complete(r)
757758
}
758759

go.mod

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
11
module github.com/openstack-k8s-operators/barbican-operator
22

3-
go 1.21
3+
go 1.24
4+
5+
toolchain go1.24.6
46

57
require (
68
github.com/go-logr/logr v1.4.3
79
github.com/google/uuid v1.6.0
810
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7
9-
github.com/onsi/ginkgo/v2 v2.20.1
10-
github.com/onsi/gomega v1.34.1
11+
github.com/onsi/ginkgo/v2 v2.25.3
12+
github.com/onsi/gomega v1.38.2
1113
github.com/openstack-k8s-operators/barbican-operator/api v0.0.0-00010101000000-000000000000
12-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250909143828-e33d35ffd64f
13-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20250818180001-057253e3d233
14-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250730071847-837b07f8d72f
15-
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20250730071847-837b07f8d72f
16-
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20250730071847-837b07f8d72f
17-
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20250819151523-e1c898c710cb
14+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250922061840-2c06b5a7d10a
15+
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20250802061907-896a24e4fc36
16+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250922082314-c83d83092a04
17+
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20250922082314-c83d83092a04
18+
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20250922082314-c83d83092a04
19+
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20250908160950-4fa28a6f127d
1820
go.uber.org/zap v1.27.0
1921
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
20-
k8s.io/api v0.29.15
21-
k8s.io/apimachinery v0.29.15
22-
k8s.io/client-go v0.29.15
23-
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
24-
sigs.k8s.io/controller-runtime v0.17.6
22+
k8s.io/api v0.31.13
23+
k8s.io/apimachinery v0.31.13
24+
k8s.io/client-go v0.31.13
25+
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
26+
sigs.k8s.io/controller-runtime v0.19.7
2527
)
2628

2729
require (
30+
github.com/Masterminds/semver/v3 v3.4.0 // indirect
2831
github.com/beorn7/perks v1.0.1 // indirect
29-
github.com/cespare/xxhash/v2 v2.2.0 // indirect
32+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
3033
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3134
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
3235
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
3336
github.com/fsnotify/fsnotify v1.7.0 // indirect
37+
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
3438
github.com/go-logr/zapr v1.3.0 // indirect
3539
github.com/go-openapi/jsonpointer v0.21.0 // indirect
3640
github.com/go-openapi/jsonreference v0.21.0 // indirect
@@ -40,9 +44,9 @@ require (
4044
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
4145
github.com/golang/protobuf v1.5.4 // indirect
4246
github.com/google/gnostic-models v0.6.8 // indirect
43-
github.com/google/go-cmp v0.6.0 // indirect
47+
github.com/google/go-cmp v0.7.0 // indirect
4448
github.com/google/gofuzz v1.2.0 // indirect
45-
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
49+
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
4650
github.com/gophercloud/gophercloud v1.14.1 // indirect
4751
github.com/imdario/mergo v0.3.16 // indirect
4852
github.com/josharian/intern v1.0.0 // indirect
@@ -52,32 +56,33 @@ require (
5256
github.com/modern-go/reflect2 v1.0.2 // indirect
5357
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
5458
github.com/openshift/api v3.9.0+incompatible // indirect
55-
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20250730071847-837b07f8d72f // indirect
59+
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20250922082314-c83d83092a04 // indirect
5660
github.com/pkg/errors v0.9.1 // indirect
57-
github.com/prometheus/client_golang v1.19.0 // indirect
58-
github.com/prometheus/client_model v0.6.0 // indirect
59-
github.com/prometheus/common v0.51.1 // indirect
60-
github.com/prometheus/procfs v0.13.0 // indirect
61+
github.com/prometheus/client_golang v1.19.1 // indirect
62+
github.com/prometheus/client_model v0.6.1 // indirect
63+
github.com/prometheus/common v0.55.0 // indirect
64+
github.com/prometheus/procfs v0.15.1 // indirect
6165
github.com/rabbitmq/cluster-operator/v2 v2.9.0 // indirect
6266
github.com/spf13/pflag v1.0.5 // indirect
67+
github.com/x448/float16 v0.8.4 // indirect
68+
go.uber.org/automaxprocs v1.6.0 // indirect
6369
go.uber.org/multierr v1.11.0 // indirect
64-
golang.org/x/mod v0.20.0 // indirect
65-
golang.org/x/net v0.28.0 // indirect
66-
golang.org/x/oauth2 v0.18.0 // indirect
67-
golang.org/x/sys v0.23.0 // indirect
68-
golang.org/x/term v0.23.0 // indirect
69-
golang.org/x/text v0.17.0 // indirect
70+
go.yaml.in/yaml/v3 v3.0.4 // indirect
71+
golang.org/x/mod v0.27.0 // indirect
72+
golang.org/x/net v0.43.0 // indirect
73+
golang.org/x/oauth2 v0.21.0 // indirect
74+
golang.org/x/sys v0.35.0 // indirect
75+
golang.org/x/term v0.34.0 // indirect
76+
golang.org/x/text v0.28.0 // indirect
7077
golang.org/x/time v0.5.0 // indirect
71-
golang.org/x/tools v0.24.0 // indirect
78+
golang.org/x/tools v0.36.0 // indirect
7279
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
73-
google.golang.org/appengine v1.6.8 // indirect
74-
google.golang.org/protobuf v1.34.1 // indirect
80+
google.golang.org/protobuf v1.36.7 // indirect
7581
gopkg.in/inf.v0 v0.9.1 // indirect
7682
gopkg.in/yaml.v2 v2.4.0 // indirect
7783
gopkg.in/yaml.v3 v3.0.1 // indirect
78-
k8s.io/apiextensions-apiserver v0.29.15 // indirect
79-
k8s.io/component-base v0.29.15 // indirect
80-
k8s.io/klog/v2 v2.120.1 // indirect
84+
k8s.io/apiextensions-apiserver v0.31.13 // indirect
85+
k8s.io/klog/v2 v2.130.1 // indirect
8186
k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect
8287
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
8388
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
@@ -92,3 +97,5 @@ replace github.com/openshift/api => github.com/openshift/api v0.0.0-202408300231
9297

9398
// custom RabbitmqClusterSpecCore for OpenStackControlplane (v2.6.0_patches_tag)
9499
replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250717122149-12f70b7f3d8d //allow-merging
100+
101+
replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/Deydra71/keystone-operator/api v0.0.0-20251002062345-bf9333e0a92e

0 commit comments

Comments
 (0)