mirror of
https://github.com/paralus/paralus.git
synced 2026-02-14 17:49:51 +00:00
At a time of restarting Kratos pod, we noticed to update the Kratos config we need modify something in IdP UI to trigger the synchronizer. Instead this change will run synchronizer initially so it will update Kratos config with database IdP entries if any.
107 lines
2.8 KiB
Go
107 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/cloudflare/cfssl/log"
|
|
"github.com/uptrace/bun"
|
|
"github.com/uptrace/bun/dialect/pgdialect"
|
|
"github.com/uptrace/bun/driver/pgdriver"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
type Provider struct {
|
|
Id string `bun:"name"`
|
|
Provider string `bun:"provider_name,notnull"`
|
|
MapperURL string `bun:"mapper_url" yaml:"mapper_url"`
|
|
ClientId string `bun:"client_id,notnull" yaml:"client_id"`
|
|
ClientSecret string `bun:"client_secret,notnull" yaml:"client_secret"`
|
|
Scope []string `bun:"scopes,array,notnull"`
|
|
IssuerURL string `bun:"issuer_url,notnull" yaml:"issuer_url"`
|
|
AuthURL string `bun:"auth_url" yaml:"auth_url,omitempty"`
|
|
TokenURL string `bun:"token_url" yaml:"token_url,omitempty"`
|
|
RequestedClaims map[string]interface{} `bun:"type:jsonb" yaml:"requested_claims,omitempty"`
|
|
}
|
|
|
|
type Config struct {
|
|
Selfservice struct {
|
|
Methods struct {
|
|
Oidc struct {
|
|
Config struct {
|
|
Providers []Provider
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var ProvidersDB []Provider
|
|
|
|
func sync(ctx context.Context, db *bun.DB, path string) error {
|
|
err := db.NewSelect().Model(&ProvidersDB).ModelTableExpr("authsrv_oidc_provider AS provider").Where("trash = 'f'").Scan(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to fetch providers from DB: %s", err)
|
|
}
|
|
|
|
var c Config
|
|
c.Selfservice.Methods.Oidc.Config.Providers = ProvidersDB
|
|
d, err := yaml.Marshal(&c)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal: %s", err)
|
|
}
|
|
err = os.WriteFile(path, d, 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to write data: %s", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
dsn := "postgres://"
|
|
outputPath := "/etc/kratos/providers.yaml"
|
|
ctx := context.Background()
|
|
channel := "provider:changed"
|
|
|
|
if len(os.Getenv("DSN")) != 0 {
|
|
dsn = os.Getenv("DSN")
|
|
}
|
|
|
|
if len(os.Getenv("KRATOS_PROVIDER_CFG")) != 0 {
|
|
outputPath = os.Getenv("KRATOS_PROVIDER_CFG")
|
|
}
|
|
|
|
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
|
|
db := bun.NewDB(sqldb, pgdialect.New())
|
|
|
|
// synchronize first
|
|
err := sync(ctx, db, outputPath)
|
|
if err != nil {
|
|
log.Errorf("sync failed: %s", err)
|
|
} else {
|
|
log.Info("Synchronized successfully")
|
|
}
|
|
|
|
ln := pgdriver.NewListener(db)
|
|
listen:
|
|
if err := ln.Listen(ctx, channel); err != nil {
|
|
log.Errorf("error listening for notifications on channel %q: %s", channel, err)
|
|
time.Sleep(2 * time.Second)
|
|
goto listen
|
|
}
|
|
|
|
log.Infof("Started listening for notification on channel %q", channel)
|
|
for range ln.Channel() {
|
|
log.Info("A notification received")
|
|
if err := sync(ctx, db, outputPath); err != nil {
|
|
log.Errorf("sync failed: %s", err)
|
|
} else {
|
|
log.Info("Synchronized successfully")
|
|
}
|
|
}
|
|
|
|
}
|