Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: only run periodic func on active instance in primary cluster or local mount #150

Merged
merged 1 commit into from
Jul 5, 2023
Merged
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
122 changes: 66 additions & 56 deletions backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/hashicorp/vault-plugin-secrets-azure/api"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/locksutil"
"github.com/hashicorp/vault/sdk/logical"
)
Expand Down Expand Up @@ -86,78 +87,87 @@ func backend() *azureSecretBackend {
}

func (b *azureSecretBackend) periodicFunc(ctx context.Context, sys *logical.Request) error {
b.Logger().Debug("starting periodic func")
if !b.updatePassword {
b.Logger().Debug("periodic func", "rotate-root", "no rotate-root update")
return nil
}
// Root rotation through the periodic func writes to storage. Only run this on the
// active instance in the primary cluster or local mounts. The periodic func doesn't
// run on perf standbys or DR secondaries, but we still protect against this here.
replicationState := b.System().ReplicationState()
if (b.System().LocalMount() || !replicationState.HasState(consts.ReplicationPerformanceSecondary)) &&
!replicationState.HasState(consts.ReplicationDRSecondary) &&
!replicationState.HasState(consts.ReplicationPerformanceStandby) {

b.Logger().Debug("starting periodic func")
if !b.updatePassword {
b.Logger().Debug("periodic func", "rotate-root", "no rotate-root update")
return nil
}

config, err := b.getConfig(ctx, sys.Storage)
if err != nil {
return err
}
config, err := b.getConfig(ctx, sys.Storage)
if err != nil {
return err
}

// Config can be nil if deleted or when the engine is enabled
// but not yet configured.
if config == nil {
return nil
}
// Config can be nil if deleted or when the engine is enabled
// but not yet configured.
if config == nil {
return nil
}

// Password should be at least a minute old before we process it
if config.NewClientSecret == "" || (time.Since(config.NewClientSecretCreated) < time.Minute) {
return nil
}
// Password should be at least a minute old before we process it
if config.NewClientSecret == "" || (time.Since(config.NewClientSecretCreated) < time.Minute) {
return nil
}

b.Logger().Debug("periodic func", "rotate-root", "new password detected, swapping in storage")
client, err := b.getClient(ctx, sys.Storage)
if err != nil {
return err
}
b.Logger().Debug("periodic func", "rotate-root", "new password detected, swapping in storage")
client, err := b.getClient(ctx, sys.Storage)
if err != nil {
return err
}

apps, err := client.provider.ListApplications(ctx, fmt.Sprintf("appId eq '%s'", config.ClientID))
if err != nil {
return err
}
apps, err := client.provider.ListApplications(ctx, fmt.Sprintf("appId eq '%s'", config.ClientID))
if err != nil {
return err
}

if len(apps) == 0 {
return fmt.Errorf("no application found")
}
if len(apps) > 1 {
return fmt.Errorf("multiple applications found - double check your client_id")
}
if len(apps) == 0 {
return fmt.Errorf("no application found")
}
if len(apps) > 1 {
return fmt.Errorf("multiple applications found - double check your client_id")
}

app := apps[0]
app := apps[0]

credsToDelete := []string{}
for _, cred := range app.PasswordCredentials {
if *cred.KeyID != config.NewClientSecretKeyID {
credsToDelete = append(credsToDelete, *cred.KeyID)
credsToDelete := []string{}
for _, cred := range app.PasswordCredentials {
if *cred.KeyID != config.NewClientSecretKeyID {
credsToDelete = append(credsToDelete, *cred.KeyID)
}
}
}

if len(credsToDelete) != 0 {
b.Logger().Debug("periodic func", "rotate-root", "removing old passwords from Azure")
err = removeApplicationPasswords(ctx, client.provider, *app.ID, credsToDelete...)
if len(credsToDelete) != 0 {
b.Logger().Debug("periodic func", "rotate-root", "removing old passwords from Azure")
err = removeApplicationPasswords(ctx, client.provider, *app.ID, credsToDelete...)
if err != nil {
return err
}
}

b.Logger().Debug("periodic func", "rotate-root", "updating config with new password")
config.ClientSecret = config.NewClientSecret
config.ClientSecretKeyID = config.NewClientSecretKeyID
config.RootPasswordExpirationDate = config.NewClientSecretExpirationDate
config.NewClientSecret = ""
config.NewClientSecretKeyID = ""
config.NewClientSecretCreated = time.Time{}

err = b.saveConfig(ctx, config, sys.Storage)
if err != nil {
return err
}
}

b.Logger().Debug("periodic func", "rotate-root", "updating config with new password")
config.ClientSecret = config.NewClientSecret
config.ClientSecretKeyID = config.NewClientSecretKeyID
config.RootPasswordExpirationDate = config.NewClientSecretExpirationDate
config.NewClientSecret = ""
config.NewClientSecretKeyID = ""
config.NewClientSecretCreated = time.Time{}

err = b.saveConfig(ctx, config, sys.Storage)
if err != nil {
return err
b.updatePassword = false
}

b.updatePassword = false

return nil
}

Expand Down