package componentcore import ( "context" "errors" "net/http" "strings" "time" atidentity "github.com/bluesky-social/indigo/atproto/identity" commonv1 "github.com/johnandersen777/socialweb-computer-kcp/api/common/v1alpha1" "github.com/johnandersen777/socialweb-computer-kcp/api/v1alpha1" atpds "github.com/johnandersen777/socialweb-computer-kcp/internal/atproto/pds" reporemote "github.com/johnandersen777/socialweb-computer-kcp/internal/atprotorepo/remote" "github.com/johnandersen777/socialweb-computer-kcp/internal/component" "github.com/johnandersen777/socialweb-computer-kcp/internal/controllers/atprotorecord" "github.com/johnandersen777/socialweb-computer-kcp/internal/controllers/repos" "github.com/johnandersen777/socialweb-computer-kcp/internal/credentials" ) const networkReadTimeout = 30 * time.Second func (c *Core) repoOptions() repos.Options { cfg := c.cfg external := &http.Client{Timeout: networkReadTimeout} return repos.Options{ Bus: c.handlers, Log: cfg.Log, Dynamic: atprotorecord.DynamicFactory(cfg.DynamicFactory), Network: reporemote.NewNetwork(reporemote.NetworkConfig{Directory: atidentity.DefaultDirectory(), HTTP: external}), Pds: func(workspace, name string) (*atpds.Server, bool) { svc, ok := c.registry.Service(workspace, pdsKind, name) if !ok { return nil, false } srv := pdsServer(svc) return srv, srv != nil }, AwaitPds: func(ctx context.Context, workspace, name string) (*atpds.Server, bool) { svc, ok := c.runtime.Await(ctx, component.Key{Workspace: workspace, Kind: pdsKind, Name: name}, func(svc component.Service) bool { return pdsServer(svc) != nil }) if !ok { return nil, false } srv := pdsServer(svc) return srv, srv != nil }, Secrets: func(ctx context.Context, workspace string, ref commonv1.SecretRef) (map[string]any, error) { resolver, err := c.credentialResolver(workspace) if err != nil { return nil, err } credential, err := resolver.Resolve(ctx, credentialRef(ref)) if err != nil { return nil, err } return credential.Data, nil }, } } const pdsKind = "Pds" func pdsServer(svc component.Service) *atpds.Server { server, ok := svc.(interface{ Server() *atpds.Server }) if !ok { return nil } return server.Server() } func (c *Core) credentialResolver(workspace string) (*credentials.Resolver, error) { if c.store == nil { return nil, errors.New("componentcore: no kcp store for the credential resolver") } return credentials.NewKCPResolver(c.store, workspace, c.cfg.CredentialClient, c.cfg.CredentialServer) } func credentialRef(ref commonv1.SecretRef) component.CredentialRef { return component.CredentialRef{Server: vaultServerIn(ref.Vault), Mount: strings.Trim(strings.TrimSpace(ref.Mount), "/"), Path: strings.Trim(strings.TrimSpace(ref.Path), "/")} } func vaultServerIn(r *commonv1.ObjectRef) string { server := v1alpha1.VaultServer(r, "") if server == "" || strings.EqualFold(strings.TrimSpace(r.Kind), v1alpha1.KindRemoteOpenBao) { return server } if ws := strings.TrimSpace(r.Workspace); ws != "" { return ws + "/" + server } return server }