Skip to content

Commit 65ba095

Browse files
author
George Harley
committed
Prevent duplicate Vault logins when reconciliations commence
* Vault logins are only made from the renewToken thread * renewToken notifies main thread when first login attempt has been made by means of a buffered channel that is passed into it as an argument * token lifecycle management only commences if the first Vault login attempt succeeds * small delay added between Vault login attempts if there are problems renewing a token (e.g. if Vault server cannot be reached because of a temporary problem on the network)
1 parent a99cac2 commit 65ba095

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

internal/vault_reader.go

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package internal
33
import (
44
"errors"
55
"fmt"
6+
rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/api/v1beta1"
67
"os"
78
"sync"
8-
9-
rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/api/v1beta1"
9+
"time"
1010

1111
ctrl "sigs.k8s.io/controller-runtime"
1212

@@ -41,13 +41,19 @@ type VaultClient struct {
4141
Reader SecretReader
4242
}
4343

44-
var ReadServiceAccountTokenFunc = ReadServiceAccountToken
45-
var ReadVaultClientSecretFunc = ReadVaultClientSecret
46-
var LoginToVaultFunc = LoginToVault
44+
// Created - and exported from package - for testing purposes
45+
var (
46+
ReadServiceAccountTokenFunc = ReadServiceAccountToken
47+
ReadVaultClientSecretFunc = ReadVaultClientSecret
48+
LoginToVaultFunc = LoginToVault
49+
FirstLoginAttemptResultCh = make(chan error, 1)
50+
)
4751

48-
var createSecretStoreClientOnce sync.Once
49-
var SecretClient SecretStoreClient
50-
var SecretClientCreationError error
52+
var (
53+
createSecretStoreClientOnce sync.Once
54+
SecretClient SecretStoreClient
55+
SecretClientCreationError error
56+
)
5157

5258
func GetSecretStoreClient(vaultSpec *rabbitmqv1beta1.VaultSpec) (SecretStoreClient, error) {
5359
createSecretStoreClientOnce.Do(InitializeClient(vaultSpec))
@@ -64,7 +70,8 @@ func InitializeClient(vaultSpec *rabbitmqv1beta1.VaultSpec) func() {
6470
return
6571
}
6672

67-
_, err = login(vaultClient, vaultSpec)
73+
go renewToken(vaultClient, vaultSpec, FirstLoginAttemptResultCh)
74+
err = <-FirstLoginAttemptResultCh
6875
if err != nil {
6976
SecretClientCreationError = fmt.Errorf("unable to login to Vault: %w", err)
7077
return
@@ -73,8 +80,6 @@ func InitializeClient(vaultSpec *rabbitmqv1beta1.VaultSpec) func() {
7380
SecretClient = VaultClient{
7481
Reader: &VaultSecretReader{client: vaultClient},
7582
}
76-
77-
go renewToken(vaultClient, vaultSpec)
7883
}
7984
}
8085

@@ -187,19 +192,34 @@ func login(vaultClient *vault.Client, vaultSpec *rabbitmqv1beta1.VaultSpec) (*va
187192
return vaultSecret, nil
188193
}
189194

190-
func renewToken(client *vault.Client, vaultSpec *rabbitmqv1beta1.VaultSpec) {
195+
func renewToken(client *vault.Client, vaultSpec *rabbitmqv1beta1.VaultSpec, initialLoginErrorCh chan<- error) {
191196
logger := ctrl.LoggerFrom(nil)
197+
sentFirstLoginAttemptErr := false
192198

193199
for {
194200
vaultLoginResp, err := login(client, vaultSpec)
195201
if err != nil {
196202
logger.Error(err, "unable to authenticate to Vault server")
197203
}
198204

205+
if !sentFirstLoginAttemptErr {
206+
initialLoginErrorCh <- err
207+
sentFirstLoginAttemptErr = true
208+
if err != nil {
209+
// Initial login attempt failed so fail fast and don't try to manage (non-existent) token lifecycle
210+
logger.Info("Lifecycle management of Vault token will not be carried out")
211+
return
212+
}
213+
logger.Info("Initiating lifecycle management of Vault token")
214+
}
215+
199216
err = manageTokenLifecycle(client, vaultLoginResp)
200217
if err != nil {
201218
logger.Error(err, "unable to start managing the Vault token lifecycle")
202219
}
220+
221+
// Reduce load on Vault server in a problem situation where repeated login attempts may be made
222+
time.Sleep(2 * time.Second)
203223
}
204224
}
205225

internal/vault_reader_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ var _ = Describe("VaultReader", func() {
289289

290290
Describe("Initialize secret store client", func() {
291291
var (
292-
vaultSpec *rabbitmqv1beta1.VaultSpec
293-
getSecretStoreClientTester func(vaultSpec *rabbitmqv1beta1.VaultSpec)(internal.SecretStoreClient, error)
292+
vaultSpec *rabbitmqv1beta1.VaultSpec
293+
getSecretStoreClientTester func(vaultSpec *rabbitmqv1beta1.VaultSpec) (internal.SecretStoreClient, error)
294294
)
295295

296296
When("vault spec has no role value", func() {
@@ -319,6 +319,7 @@ var _ = Describe("VaultReader", func() {
319319

320320
When("service account token is not in the expected place", func() {
321321
BeforeEach(func() {
322+
internal.FirstLoginAttemptResultCh = make(chan error, 1)
322323
internal.SecretClient = nil
323324
internal.SecretClientCreationError = nil
324325
vaultSpec = &rabbitmqv1beta1.VaultSpec{
@@ -346,6 +347,7 @@ var _ = Describe("VaultReader", func() {
346347

347348
When("unable to log into vault to obtain client secret", func() {
348349
BeforeEach(func() {
350+
internal.FirstLoginAttemptResultCh = make(chan error, 1)
349351
internal.SecretClient = nil
350352
internal.SecretClientCreationError = nil
351353
vaultSpec = &rabbitmqv1beta1.VaultSpec{
@@ -384,6 +386,7 @@ var _ = Describe("VaultReader", func() {
384386

385387
When("client secret obtained from vault", func() {
386388
BeforeEach(func() {
389+
internal.FirstLoginAttemptResultCh = make(chan error, 1)
387390
internal.SecretClient = nil
388391
internal.SecretClientCreationError = nil
389392
vaultSpec = &rabbitmqv1beta1.VaultSpec{

0 commit comments

Comments
 (0)