Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -1165,7 +1165,7 @@ License URL: https://cs.opensource.google/go/x/time/+/v0.15.0:LICENSE
Module: gomodules.xyz/jsonpatch/v2
Version: v2.5.0
License: Apache-2.0
License URL: https://github.com/gomodules/jsonpatch/blob/v2.5.0/LICENSE
License URL: https://github.com/gomodules/jsonpatch/blob/v2.5.0/v2/LICENSE

----------
Module: google.golang.org/api
Expand Down
45 changes: 45 additions & 0 deletions cli/cmd/install_openbao.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
package cmd

import (
"bufio"
"context"
"errors"
"fmt"
"io"
"os"
"os/exec"
"os/signal"
"path/filepath"
"strings"
"syscall"
"time"

Expand All @@ -29,19 +33,30 @@ type InstallOpenBaoCmd struct {
// InstallOpenBaoOpts holds the CLI flags for the OpenBao installer.
type InstallOpenBaoOpts struct {
*GlobalOptions
Namespace string
SecretsEngineName string
BaoUsername string
DRBackupPath string
Replicas int
StorageSize string
Timeout time.Duration
AgeKeyFile string
Yes bool
}

func (c *InstallOpenBaoCmd) RunE(_ *cobra.Command, _ []string) error {
if err := validateOpenBaoPrereqs(); err != nil {
return err
}

// If --age-key-file is provided, set SOPS_AGE_KEY_FILE so ResolveAgeKey
// picks it up. Otherwise, fall back to the normal auto-discovery chain.
if c.Opts.AgeKeyFile != "" {
if err := os.Setenv("SOPS_AGE_KEY_FILE", c.Opts.AgeKeyFile); err != nil {
return fmt.Errorf("setting SOPS_AGE_KEY_FILE: %w", err)
Comment on lines +52 to +56
}
}

configDir, err := os.UserConfigDir()
if err != nil {
return fmt.Errorf("determining user config directory: %w", err)
Expand All @@ -54,6 +69,7 @@ func (c *InstallOpenBaoCmd) RunE(_ *cobra.Command, _ []string) error {
}

cfg := installer.OpenBaoInstallerConfig{
Namespace: c.Opts.Namespace,
SecretsEngineName: c.Opts.SecretsEngineName,
Username: c.Opts.BaoUsername,
DRBackupPath: c.Opts.DRBackupPath,
Expand All @@ -69,6 +85,32 @@ func (c *InstallOpenBaoCmd) RunE(_ *cobra.Command, _ []string) error {
return fmt.Errorf("initializing openbao installer: %w", err)
}

inst.ConfirmFunc = func() error {
if c.Opts.Yes {
return nil
}

fmt.Printf("\nWARNING: No DR backup found at: %s\n", c.Opts.DRBackupPath)
fmt.Println("This will perform a FRESH OpenBao initialization:")
fmt.Println(" - Existing Vault CR will be deleted")
fmt.Println(" - All OpenBao pods will be terminated")
fmt.Println(" - Persistent volume claims (data) will be deleted")
fmt.Println(" - Existing unseal keys will be removed")
fmt.Println("")
fmt.Println("If you intended to restore from a backup, verify --dr-backup-path is correct.")
fmt.Print("\nType 'yes' to continue: ")

reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil && !errors.Is(err, io.EOF) {
return fmt.Errorf("failed to read confirmation: %w", err)
}
if strings.TrimSpace(strings.ToLower(input)) != "yes" {
return fmt.Errorf("aborted: type 'yes' to continue or pass --yes")
}
return nil
}

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

Expand Down Expand Up @@ -100,12 +142,15 @@ func AddInstallOpenBaoCmd(install *cobra.Command, opts *GlobalOptions) {
},
Opts: &InstallOpenBaoOpts{GlobalOptions: opts},
}
openbao.cmd.Flags().StringVarP(&openbao.Opts.Namespace, "namespace", "n", installer.DefaultOpenBaoNamespace, "Kubernetes namespace for OpenBao deployment")
openbao.cmd.Flags().StringVar(&openbao.Opts.SecretsEngineName, "secrets-engine", "cs-secrets-engine", "Name of the KV-v2 secrets engine to provision")
openbao.cmd.Flags().StringVar(&openbao.Opts.BaoUsername, "bao-user", "admin", "Username for the userpass auth method (ignored on restore, uses DR backup value)")
openbao.cmd.Flags().StringVar(&openbao.Opts.DRBackupPath, "dr-backup-path", "", "Path for SOPS-encrypted DR backup file (required)")
openbao.cmd.Flags().IntVar(&openbao.Opts.Replicas, "replicas", 1, "Number of OpenBao replicas (1 for single-node, odd number >= 3 for HA)")
openbao.cmd.Flags().StringVar(&openbao.Opts.StorageSize, "storage-size", "10Gi", "PVC storage size for each OpenBao replica")
openbao.cmd.Flags().DurationVar(&openbao.Opts.Timeout, "timeout", 5*time.Minute, "Timeout for waiting on initialization")
openbao.cmd.Flags().StringVarP(&openbao.Opts.AgeKeyFile, "age-key-file", "k", "", "Path to age private key file for SOPS encryption/decryption (auto-detected if not set)")
openbao.cmd.Flags().BoolVarP(&openbao.Opts.Yes, "yes", "y", false, "Auto-approve fresh initialization when no DR backup is found")

util.MarkFlagRequired(openbao.cmd, "dr-backup-path")

Expand Down
3 changes: 3 additions & 0 deletions docs/oms_install_openbao.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@ $ oms install openbao --dr-backup-path ./backups/cluster-1.enc.json --timeout 10
### Options

```
-k, --age-key-file string Path to age private key file for SOPS encryption/decryption (auto-detected if not set)
--bao-user string Username for the userpass auth method (ignored on restore, uses DR backup value) (default "admin")
--dr-backup-path string Path for SOPS-encrypted DR backup file (required)
-h, --help help for openbao
-n, --namespace string Kubernetes namespace for OpenBao deployment (default "vault")
--replicas int Number of OpenBao replicas (1 for single-node, odd number >= 3 for HA) (default 1)
--secrets-engine string Name of the KV-v2 secrets engine to provision (default "cs-secrets-engine")
--storage-size string PVC storage size for each OpenBao replica (default "10Gi")
--timeout duration Timeout for waiting on initialization (default 5m0s)
-y, --yes Auto-approve fresh initialization when no DR backup is found
```

### SEE ALSO
Expand Down
2 changes: 1 addition & 1 deletion internal/installer/manifests/openbao/vault-cr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ spec:
value: "http://$(POD_NAME).{{ .Namespace }}.svc.cluster.local:8200"
unsealConfig:
options:
preFlightChecks: false
preFlightChecks: true
storeRootToken: false
kubernetes:
secretNamespace: {{ .Namespace }}
Expand Down
Loading
Loading