Skip to content

Commit 5d68e31

Browse files
committed
Application Credential support
1 parent 530dcac commit 5d68e31

File tree

9 files changed

+102
-5
lines changed

9 files changed

+102
-5
lines changed

api/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,5 @@ replace k8s.io/component-base => k8s.io/component-base v0.31.13 //allow-merging
105105
replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec //allow-merging
106106

107107
replace k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20250627150254-e9823e99808e //allow-merging
108+
109+
replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/Deydra71/keystone-operator/api v0.0.0-20251014080018-27792b7a40a5

config/rbac/role.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ rules:
102102
- keystone.openstack.org
103103
resources:
104104
- keystoneapis
105+
- keystoneapplicationcredentials
105106
verbs:
106107
- get
107108
- list

controllers/swift_common.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ import (
2222
"fmt"
2323
"time"
2424

25+
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2526
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
27+
"github.com/openstack-k8s-operators/lib-common/modules/common/env"
2628
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
2729
"github.com/openstack-k8s-operators/lib-common/modules/common/secret"
28-
"k8s.io/apimachinery/pkg/types"
2930

30-
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
31-
"github.com/openstack-k8s-operators/lib-common/modules/common/env"
3231
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32+
"k8s.io/apimachinery/pkg/types"
3333
ctrl "sigs.k8s.io/controller-runtime"
3434
"sigs.k8s.io/controller-runtime/pkg/client"
3535
"sigs.k8s.io/controller-runtime/pkg/log"

controllers/swift_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ func (r *SwiftReconciler) GetLogger(ctx context.Context) logr.Logger {
5959
//+kubebuilder:rbac:groups=swift.openstack.org,resources=swifts,verbs=get;list;watch;create;update;patch;delete
6060
//+kubebuilder:rbac:groups=swift.openstack.org,resources=swifts/status,verbs=get;update;patch
6161
//+kubebuilder:rbac:groups=swift.openstack.org,resources=swifts/finalizers,verbs=update;patch
62+
//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
63+
//+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapplicationcredentials,verbs=get;list;watch
6264

6365
// service account, role, rolebinding
6466
// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;patch

controllers/swiftproxy_controller.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,19 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
512512
return ctrlResult, err
513513
}
514514

515+
// Check for Application Credentials
516+
ctrlResult, err = keystonev1.VerifyApplicationCredentialsForService(
517+
ctx,
518+
r.Client,
519+
instance.Namespace,
520+
"swift",
521+
&envVars,
522+
10*time.Second,
523+
)
524+
if (err != nil || ctrlResult != ctrl.Result{}) {
525+
return ctrlResult, err
526+
}
527+
515528
// Get the service password and pass it to the template
516529
sps, _, err := secret.GetSecret(ctx, helper, instance.Spec.Secret, instance.Namespace)
517530
if err != nil {
@@ -578,6 +591,20 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
578591
return ctrl.Result{}, err
579592
}
580593

594+
// Get Application Credential data if available
595+
useAC := false
596+
acID := ""
597+
acSecret := ""
598+
// Try to get Application Credential for this service (via keystone api helper)
599+
if acData, err := keystonev1.GetApplicationCredentialFromSecret(ctx, r.Client, instance.Namespace, swift.ServiceName); err != nil {
600+
Log.Error(err, "Failed to get ApplicationCredential for service", "service", swift.ServiceName)
601+
} else if acData != nil {
602+
useAC = true
603+
acID = acData.ID
604+
acSecret = acData.Secret
605+
Log.Info("Using ApplicationCredentials auth", "service", swift.ServiceName)
606+
}
607+
581608
// Create a Secret populated with content from templates/
582609
tpl := swiftproxy.SecretTemplates(
583610
instance,
@@ -591,6 +618,9 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request)
591618
os.GetRegion(),
592619
transportURLString,
593620
instance.Spec.APITimeout,
621+
useAC,
622+
acID,
623+
acSecret,
594624
)
595625
err = secret.EnsureSecrets(ctx, helper, instance, tpl, &envVars)
596626
if err != nil {
@@ -846,6 +876,42 @@ func (r *SwiftProxyReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
846876
return nil
847877
}
848878

879+
// Application Credential secret watching function
880+
acSecretFn := func(_ context.Context, o client.Object) []reconcile.Request {
881+
name := o.GetName()
882+
ns := o.GetNamespace()
883+
result := []reconcile.Request{}
884+
885+
// Only handle Secret objects
886+
if _, isSecret := o.(*corev1.Secret); !isSecret {
887+
return nil
888+
}
889+
890+
// Check if this is a swift AC secret by name pattern (ac-swift-secret)
891+
expectedSecretName := keystonev1.GetACSecretName("swift")
892+
if name == expectedSecretName {
893+
// get all SwiftProxy CRs in this namespace
894+
swiftProxies := &swiftv1beta1.SwiftProxyList{}
895+
listOpts := []client.ListOption{
896+
client.InNamespace(ns),
897+
}
898+
if err := r.List(context.Background(), swiftProxies, listOpts...); err != nil {
899+
return nil
900+
}
901+
902+
// Enqueue reconcile for all swift proxy instances
903+
for _, cr := range swiftProxies.Items {
904+
objKey := client.ObjectKey{
905+
Namespace: ns,
906+
Name: cr.Name,
907+
}
908+
result = append(result, reconcile.Request{NamespacedName: objKey})
909+
}
910+
}
911+
912+
return result
913+
}
914+
849915
return ctrl.NewControllerManagedBy(mgr).
850916
For(&swiftv1beta1.SwiftProxy{}).
851917
Owns(&corev1.Secret{}).
@@ -859,6 +925,8 @@ func (r *SwiftProxyReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma
859925
handler.EnqueueRequestsFromMapFunc(r.findObjectsForSrc),
860926
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
861927
).
928+
Watches(&corev1.Secret{},
929+
handler.EnqueueRequestsFromMapFunc(acSecretFn)).
862930
Watches(&memcachedv1.Memcached{},
863931
handler.EnqueueRequestsFromMapFunc(memcachedFn)).
864932
Watches(&topologyv1.Topology{},

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,5 @@ replace k8s.io/component-base => k8s.io/component-base v0.31.13 //allow-merging
116116
replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec //allow-merging
117117

118118
replace k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20250627150254-e9823e99808e //allow-merging
119+
120+
replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/Deydra71/keystone-operator/api v0.0.0-20251014080018-27792b7a40a5

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/Deydra71/keystone-operator/api v0.0.0-20251014080018-27792b7a40a5 h1:qpFuqb7xf9rgua2qwOIJYhB9+ePHB0FfQ/mIufzw7Nc=
2+
github.com/Deydra71/keystone-operator/api v0.0.0-20251014080018-27792b7a40a5/go.mod h1:braI3juap0JIy6XOvu0AHqVGkfn2/dbw5BBRv84oSAw=
13
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
24
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
35
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -102,8 +104,6 @@ github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20251007134031
102104
github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20251007134031-f8d7a8958555/go.mod h1:DtYNaat+pImzGhh+RgfLeSmUEqw6J/TqytTYbvxVg7E=
103105
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251007170607-63860ee1375c h1:7Qv0lv6QXwouUPryiZeiVbAIeCv8qYFH3sf80w+V0DE=
104106
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251007170607-63860ee1375c/go.mod h1:Zkxq8zl7w7NRYGxfobFKHu/+MNA+65Lc6ZqtZ8yTogw=
105-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251007150354-bb6ae13a35cf h1:t3fxcJvKqG54QCbwmiPy5BbN/6bIHiJZArrlxeGyU1c=
106-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251007150354-bb6ae13a35cf/go.mod h1:braI3juap0JIy6XOvu0AHqVGkfn2/dbw5BBRv84oSAw=
107107
github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20251007102731-b786c86bffe7 h1:JcQRAHidrzir4FWiUb+y6L8kHA4bDEvZIiSShOj/lGU=
108108
github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20251007102731-b786c86bffe7/go.mod h1:tXxVkkk8HlATwTmDA5RTP3b+c8apfuMM15mZ2wW5iNs=
109109
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251007102731-b786c86bffe7 h1:mlz/n5Fc5Ypbx5odAvKqlhZBNKEo9BdNtCwTo0mHusk=

pkg/swiftproxy/templates.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ func SecretTemplates(
4040
keystoneRegion string,
4141
transportURL string,
4242
apiTimeout int,
43+
useApplicationCredentials bool,
44+
applicationCredentialID string,
45+
applicationCredentialSecret string,
4346
) []util.Template {
4447
templateParameters := make(map[string]any)
4548
templateParameters["ServiceUser"] = instance.Spec.ServiceUser
@@ -54,6 +57,13 @@ func SecretTemplates(
5457
templateParameters["TransportURL"] = transportURL
5558
templateParameters["APITimeout"] = apiTimeout
5659

60+
// Application Credential parameters
61+
templateParameters["UseApplicationCredentials"] = useApplicationCredentials
62+
if useApplicationCredentials {
63+
templateParameters["ApplicationCredentialID"] = applicationCredentialID
64+
templateParameters["ApplicationCredentialSecret"] = applicationCredentialSecret
65+
}
66+
5767
// MTLS params
5868
if mc.Status.MTLSCert != "" {
5969
templateParameters["MemcachedAuthCert"] = fmt.Sprint(memcachedv1.CertMountPath())

templates/swiftproxy/config/00-proxy-server.conf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,18 @@ project_reader_roles = SwiftProjectReader
8080
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
8181
www_authenticate_uri = {{ .KeystonePublicURL }}
8282
auth_url = {{ .KeystonePublicURL }}
83+
{{ if .UseApplicationCredentials -}}
84+
auth_type = v3applicationcredential
85+
application_credential_id = {{ .ApplicationCredentialID }}
86+
application_credential_secret = {{ .ApplicationCredentialSecret }}
87+
{{- else -}}
8388
auth_plugin=password
8489
project_domain_id = default
8590
user_domain_id = default
8691
project_name = service
8792
username = {{ .ServiceUser }}
8893
password = {{ .ServicePassword }}
94+
{{- end }}
8995
delay_auth_decision = True
9096

9197
[filter:s3api]
@@ -108,8 +114,14 @@ use = egg:swift#encryption
108114
[filter:ceilometer]
109115
paste.filter_factory = ceilometermiddleware.swift:filter_factory
110116
auth_url = {{ .KeystonePublicURL }}
117+
{{ if .UseApplicationCredentials -}}
118+
auth_type = v3applicationcredential
119+
application_credential_id = {{ .ApplicationCredentialID }}
120+
application_credential_secret = {{ .ApplicationCredentialSecret }}
121+
{{- else -}}
111122
password = {{ .ServicePassword }}
112123
username = {{ .ServiceUser }}
124+
{{- end }}
113125
region_name = {{ .KeystoneRegion }}
114126
url = {{ .TransportURL }}
115127
project_name = service

0 commit comments

Comments
 (0)