fix: bound OpenBao initialization tools
This commit is contained in:
parent
0cf8fa7557
commit
b7b9068f9c
|
|
@ -36,9 +36,14 @@ type operationalSecrets struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var decryptRecovery = func(identityPath, bundlePath string) ([]byte, error) {
|
var decryptRecovery = func(identityPath, bundlePath string) ([]byte, error) {
|
||||||
cmd := exec.Command("age", "-d", "-i", identityPath, bundlePath)
|
ctx, cancel := context.WithTimeout(context.Background(), commandTimeout)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.CommandContext(ctx, "age", "-d", "-i", identityPath, bundlePath)
|
||||||
output, err := cmd.Output()
|
output, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||||
|
return nil, fmt.Errorf("decrypt OpenBao recovery material timed out after %s", commandTimeout)
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("decrypt OpenBao recovery material: %w", err)
|
return nil, fmt.Errorf("decrypt OpenBao recovery material: %w", err)
|
||||||
}
|
}
|
||||||
return output, nil
|
return output, nil
|
||||||
|
|
@ -70,18 +75,22 @@ func EnsureRecoveryIdentity(identityPath string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Initialize(kubeconfig, recipient, identityPath, bundlePath, ageKeyPath, operationalSecretsPath string) (map[string]map[string]string, error) {
|
func Initialize(kubeconfig, recipient, identityPath, bundlePath, ageKeyPath, operationalSecretsPath string) (map[string]map[string]string, error) {
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: validate recovery recipient")
|
||||||
if err := validateRecoveryRecipient(recipient, bundlePath); err != nil {
|
if err := validateRecoveryRecipient(recipient, bundlePath); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: wait for pod")
|
||||||
if err := waitForPod(kubeconfig); err != nil {
|
if err := waitForPod(kubeconfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: read status")
|
||||||
current, err := getStatus(kubeconfig)
|
current, err := getStatus(kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var material RecoveryMaterial
|
var material RecoveryMaterial
|
||||||
if !current.Initialized {
|
if !current.Initialized {
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: initialize")
|
||||||
output, err := execInPod(kubeconfig, nil, "bao", "operator", "init", "-format=json")
|
output, err := execInPod(kubeconfig, nil, "bao", "operator", "init", "-format=json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("initialize OpenBao: %w", err)
|
return nil, fmt.Errorf("initialize OpenBao: %w", err)
|
||||||
|
|
@ -94,12 +103,14 @@ func Initialize(kubeconfig, recipient, identityPath, bundlePath, ageKeyPath, ope
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: decrypt recovery material")
|
||||||
material, err = ReadRecoveryMaterial(identityPath, bundlePath)
|
material, err = ReadRecoveryMaterial(identityPath, bundlePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if current.Sealed {
|
if current.Sealed {
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: unseal")
|
||||||
if err := unseal(kubeconfig, material); err != nil {
|
if err := unseal(kubeconfig, material); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -108,13 +119,16 @@ func Initialize(kubeconfig, recipient, identityPath, bundlePath, ageKeyPath, ope
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create OpenBao Kubernetes token reviewer token: %w", err)
|
return nil, fmt.Errorf("create OpenBao Kubernetes token reviewer token: %w", err)
|
||||||
}
|
}
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: configure Kubernetes auth")
|
||||||
if err := configureKubernetesAuth(kubeconfig, material.RootToken, string(bytes.TrimSpace(reviewerToken))); err != nil {
|
if err := configureKubernetesAuth(kubeconfig, material.RootToken, string(bytes.TrimSpace(reviewerToken))); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: seed operational secrets")
|
||||||
secrets, err := seedOperationalSecrets(kubeconfig, material.RootToken, ageKeyPath, operationalSecretsPath)
|
secrets, err := seedOperationalSecrets(kubeconfig, material.RootToken, ageKeyPath, operationalSecretsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
fmt.Fprintln(os.Stderr, "OpenBao: refresh External Secrets")
|
||||||
if err := refreshExternalSecrets(kubeconfig); err != nil {
|
if err := refreshExternalSecrets(kubeconfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -122,10 +136,15 @@ func Initialize(kubeconfig, recipient, identityPath, bundlePath, ageKeyPath, ope
|
||||||
}
|
}
|
||||||
|
|
||||||
func seedOperationalSecrets(kubeconfig, rootToken, ageKeyPath, path string) (map[string]map[string]string, error) {
|
func seedOperationalSecrets(kubeconfig, rootToken, ageKeyPath, path string) (map[string]map[string]string, error) {
|
||||||
cmd := exec.Command("sops", "--decrypt", "--output-type", "yaml", path)
|
ctx, cancel := context.WithTimeout(context.Background(), commandTimeout)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.CommandContext(ctx, "sops", "--decrypt", "--output-type", "yaml", path)
|
||||||
cmd.Env = append(os.Environ(), "SOPS_AGE_KEY_FILE="+ageKeyPath)
|
cmd.Env = append(os.Environ(), "SOPS_AGE_KEY_FILE="+ageKeyPath)
|
||||||
plaintext, err := cmd.Output()
|
plaintext, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||||
|
return nil, fmt.Errorf("decrypt operational SOPS secrets timed out after %s", commandTimeout)
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("decrypt operational SOPS secrets: %w", err)
|
return nil, fmt.Errorf("decrypt operational SOPS secrets: %w", err)
|
||||||
}
|
}
|
||||||
var document operationalSecrets
|
var document operationalSecrets
|
||||||
|
|
@ -162,9 +181,14 @@ func validateRecoveryRecipient(recipient, bundlePath string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer os.Remove(probePath)
|
defer os.Remove(probePath)
|
||||||
cmd := exec.Command("age", "-r", recipient, "-o", probePath)
|
ctx, cancel := context.WithTimeout(context.Background(), commandTimeout)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.CommandContext(ctx, "age", "-r", recipient, "-o", probePath)
|
||||||
cmd.Stdin = bytes.NewReader(nil)
|
cmd.Stdin = bytes.NewReader(nil)
|
||||||
if output, err := cmd.CombinedOutput(); err != nil {
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||||
|
return fmt.Errorf("validate OpenBao recovery recipient timed out after %s", commandTimeout)
|
||||||
|
}
|
||||||
return fmt.Errorf("validate OpenBao recovery recipient: %w: %s", err, bytes.TrimSpace(output))
|
return fmt.Errorf("validate OpenBao recovery recipient: %w: %s", err, bytes.TrimSpace(output))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue