supabase-cli/pkg/vault/batch.go

61 lines
1.4 KiB
Go

package vault
import (
"context"
"fmt"
"os"
"github.com/go-errors/errors"
"github.com/jackc/pgx/v4"
"github.com/supabase/cli/pkg/config"
"github.com/supabase/cli/pkg/pgxv5"
)
const (
CREATE_VAULT_KV = "SELECT vault.create_secret($1, $2)"
READ_VAULT_KV = "SELECT id, name FROM vault.secrets WHERE name = ANY($1)"
UPDATE_VAULT_KV = "SELECT vault.update_secret($1, $2)"
)
type VaultTable struct {
Id string
Name string
}
func UpsertVaultSecrets(ctx context.Context, secrets map[string]config.Secret, conn *pgx.Conn) error {
var keys []string
toInsert := map[string]string{}
for k, v := range secrets {
if len(v.SHA256) > 0 {
keys = append(keys, k)
toInsert[k] = v.Value
}
}
if len(keys) == 0 {
return nil
}
fmt.Fprintln(os.Stderr, "Updating vault secrets...")
rows, err := conn.Query(ctx, READ_VAULT_KV, keys)
if err != nil {
return errors.Errorf("failed to read vault: %w", err)
}
toUpdate, err := pgxv5.CollectRows[VaultTable](rows)
if err != nil {
return err
}
batch := pgx.Batch{}
for _, r := range toUpdate {
secret := secrets[r.Name]
batch.Queue(UPDATE_VAULT_KV, r.Id, secret.Value)
delete(toInsert, r.Name)
}
// Remaining secrets should be created
for k, v := range toInsert {
batch.Queue(CREATE_VAULT_KV, v, k)
}
if err := conn.SendBatch(ctx, &batch).Close(); err != nil {
return errors.Errorf("failed to update vault: %w", err)
}
return nil
}