63 lines
2.1 KiB
Go
63 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"knowledge-governance/internal/qaopsorg"
|
|
)
|
|
|
|
func main() {
|
|
if err := run(os.Args[1:], os.Getenv, os.Stdout); err != nil {
|
|
fmt.Fprintln(os.Stderr, "directory import failed; check private input and governance connection (details withheld)")
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func run(args []string, getenv func(string) string, out io.Writer) error {
|
|
if len(args) != 1 || getenv("QAOPS_CONFIRM_DIRECTORY_IMPORT") != "import-governance-directory" || getenv("DOBOTAI_OPS_TENANT_KEY") == "" || getenv("DATABASE_URL") == "" {
|
|
return errors.New("explicit input, tenant, governance database and confirmation required")
|
|
}
|
|
info, err := os.Lstat(args[0])
|
|
if err != nil || !info.Mode().IsRegular() || info.Mode().Perm()&0077 != 0 || info.Size() > 16<<20 {
|
|
return errors.New("input must be a private regular JSON file")
|
|
}
|
|
file, err := os.Open(args[0])
|
|
if err != nil {
|
|
return errors.New("input unavailable")
|
|
}
|
|
defer file.Close()
|
|
decoder := json.NewDecoder(io.LimitReader(file, (16<<20)+1))
|
|
decoder.DisallowUnknownFields()
|
|
var input qaopsorg.Import
|
|
if decoder.Decode(&input) != nil || decoder.Decode(&struct{}{}) != io.EOF {
|
|
return errors.New("input invalid")
|
|
}
|
|
if !input.Complete {
|
|
return qaopsorg.ErrInvalid
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
pool, err := pgxpool.New(ctx, getenv("DATABASE_URL"))
|
|
if err != nil {
|
|
return qaopsorg.ErrUnavailable
|
|
}
|
|
defer pool.Close()
|
|
store := qaopsorg.NewStore(pool, getenv("DOBOTAI_OPS_TENANT_KEY"))
|
|
saved, err := store.ReplaceDirectory(ctx, input)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
active, err := store.GetView(ctx)
|
|
if err != nil || active.DirectoryID != saved.DirectoryID {
|
|
return qaopsorg.ErrConflict
|
|
}
|
|
return json.NewEncoder(out).Encode(map[string]any{"directory_id": active.DirectoryID, "source": active.DirectorySource, "synced_at": active.DirectorySyncedAt, "departments": len(active.View.Departments), "people": active.View.TotalPeople, "readback_verified": true})
|
|
}
|