key-cape/src/cmd/keycape-to-keycloak/main.go

76 lines
2 KiB
Go
Raw Normal View History

// keycape-to-keycloak migrates a KeyCape canonical snapshot to a Keycloak
// realm export format. Part of the NetKingdom IAM migration contract.
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
"github.com/rs/zerolog"
"gopkg.in/yaml.v3"
"keycape/internal/migration/lldapexport"
"keycape/internal/migration/tokeycloak"
"keycape/internal/server/telemetry"
)
func main() {
inputFile := flag.String("input", "", "Path to canonical-export.yaml (required)")
outputFile := flag.String("output", "keycloak-realm.json", "Path to write Keycloak realm import JSON")
realmName := flag.String("realm", "netkingdom", "Keycloak realm name")
issuer := flag.String("issuer", "", "OIDC issuer URL")
flag.Parse()
if *inputFile == "" {
fmt.Fprintln(os.Stderr, "keycape-to-keycloak: -input is required")
flag.Usage()
os.Exit(1)
}
data, err := os.ReadFile(*inputFile)
if err != nil {
fmt.Fprintf(os.Stderr, "keycape-to-keycloak: read %q: %v\n", *inputFile, err)
os.Exit(1)
}
var export lldapexport.ExportResult
if err := yaml.Unmarshal(data, &export); err != nil {
fmt.Fprintf(os.Stderr, "keycape-to-keycloak: parse YAML: %v\n", err)
os.Exit(1)
}
log := zerolog.New(os.Stderr).With().Timestamp().Logger()
em := telemetry.NewLogEmitter(log)
tr := tokeycloak.New(tokeycloak.Config{
RealmName: *realmName,
Issuer: *issuer,
}, em)
realm, err := tr.Transform(&export)
if err != nil {
fmt.Fprintf(os.Stderr, "keycape-to-keycloak: transform: %v\n", err)
os.Exit(1)
}
// Print validation report to stderr.
report := tr.ValidationReport(&export, realm)
for _, issue := range report {
fmt.Fprintf(os.Stderr, "WARNING: %s\n", issue)
}
out, err := json.MarshalIndent(realm, "", " ")
if err != nil {
fmt.Fprintf(os.Stderr, "keycape-to-keycloak: marshal JSON: %v\n", err)
os.Exit(1)
}
if err := os.WriteFile(*outputFile, out, 0o644); err != nil {
fmt.Fprintf(os.Stderr, "keycape-to-keycloak: write %q: %v\n", *outputFile, err)
os.Exit(1)
}
fmt.Printf("keycape-to-keycloak: wrote %s (%d bytes)\n", *outputFile, len(out))
}