Repository: hashicorp/vault
File: builtin/logical/database/path_rotate_credentials.go (Go)

Code before:
		}

		input := &setStaticAccountInput{
			RoleName: name,
			Role:     role,
		}
		if walID, ok := item.Value.(string); ok {
			input.WALID = walID
		}
		resp, err := b.setStaticAccount(ctx, req.Storage, input)
		// if err is not nil, we need to attempt to update the priority and place
		// this item back on the queue. The err should still be returned at the end
		// of this method.
		if err != nil {
			b.logger.Error("unable to rotate credentials in rotate-role", "rotationID", name, "err", err)
			// Update the priority to re-try this rotation and re-add the item to
			// the queue
			item.Priority = time.Now().Add(10 * time.Second).Unix()

			// Preserve the WALID if it was returned
			if resp != nil && resp.WALID != "" {
				item.Value = resp.WALID
			}
		} else {
			nextRotationTime := role.StaticAccount.NextRotationTimeFromInput(resp.RotationTime).Unix()
			ttl := nextRotationTime - time.Now().Unix()
			b.Logger().Info("rotated credential in rotate-role", "rotationID", name, "TTL", ttl)
			item.Priority = nextRotationTime
			// Clear any stored WAL ID as we must have successfully deleted our WAL to get here.
			item.Value = ""
			modified = true
		}

		// Add their rotation to the queue
		if err := b.pushItem(item); err != nil {
			return nil, err
		}

		if err != nil {
			return nil, fmt.Errorf("unable to finish rotating credentials; retries will "+
				"continue in the background but it is also safe to retry manually: %w", err)
		}

		return nil, nil
	}
}

const pathRotateCredentialsUpdateHelpSyn = `
Request to rotate the root credentials for a certain database connection.
`


Review comment (security):
Should we use the helper method that rounds down and ensures non-negative values?
```suggestion
			ttl := role.StaticAccount.CredentialTTL().Seconds()
```

Code after:
		}

		input := &setStaticAccountInput{
			RoleName: name,
			Role:     role,
		}
		if walID, ok := item.Value.(string); ok {
			input.WALID = walID
		}
		resp, err := b.setStaticAccount(ctx, req.Storage, input)
		// if err is not nil, we need to attempt to update the priority and place
		// this item back on the queue. The err should still be returned at the end
		// of this method.
		if err != nil {
			b.logger.Error("unable to rotate credentials in rotate-role on user request", "path", req.Path, "error", err.Error())
			// Update the priority to re-try this rotation and re-add the item to
			// the queue
			item.Priority = time.Now().Add(10 * time.Second).Unix()

			// Preserve the WALID if it was returned
			if resp != nil && resp.WALID != "" {
				item.Value = resp.WALID
			}
		} else {
			item.Priority = role.StaticAccount.NextRotationTimeFromInput(resp.RotationTime).Unix()
			ttl := role.StaticAccount.CredentialTTL().Seconds()
			b.Logger().Info("rotated credential in rotate-role on user request", "path", req.Path, "TTL", ttl)
			// Clear any stored WAL ID as we must have successfully deleted our WAL to get here.
			item.Value = ""
			modified = true
		}

		// Add their rotation to the queue
		if err := b.pushItem(item); err != nil {
			return nil, err
		}

		if err != nil {
			return nil, fmt.Errorf("unable to finish rotating credentials; retries will "+
				"continue in the background but it is also safe to retry manually: %w", err)
		}

		return nil, nil
	}
}

const pathRotateCredentialsUpdateHelpSyn = `
Request to rotate the root credentials for a certain database connection.
`

const pathRotateCredentialsUpdateHelpDesc = `