1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package atprotorecordwatch
import (
"cmp"
"context"
"errors"
"fmt"
"strings"
apierrors "k8s.io/apimachinery/pkg/api/errors"
commonv1 "github.com/johnandersen777/socialweb-computer-kcp/api/common/v1alpha1"
"github.com/johnandersen777/socialweb-computer-kcp/api/v1alpha1"
"github.com/johnandersen777/socialweb-computer-kcp/internal/controllers/atprotorecord"
"github.com/johnandersen777/socialweb-computer-kcp/internal/eventstream"
"github.com/johnandersen777/socialweb-computer-kcp/internal/kit/binding"
)
type transientError struct {
err error
}
func (e transientError) Error() string { return e.err.Error() }
func (e transientError) Unwrap() error { return e.err }
func readFailed(err error) error {
if apierrors.IsNotFound(err) || apierrors.IsForbidden(err) {
return err
}
return transientError{err: err}
}
func (c *Controller) repo(ctx context.Context, workspace string, spec v1alpha1.AtprotoRecordWatchSpec) (eventstream.WatchRepo, []string, error) {
if spec.RepoRef == nil {
did, err := eventstream.SpecRepo(spec)
return eventstream.WatchRepo{DID: did}, nil, err
}
ref := *spec.RepoRef
name := strings.TrimSpace(ref.Name)
if name == "" {
return eventstream.WatchRepo{}, nil, errors.New("spec.repoRef needs a name")
}
if !strings.EqualFold(strings.TrimSpace(ref.Kind), RepoKind) {
return eventstream.WatchRepo{}, nil, fmt.Errorf("spec.repoRef must name an %s, not %q", RepoKind, ref.Kind)
}
repoWorkspace := cmp.Or(strings.TrimSpace(ref.Workspace), workspace)
keys := []string{binding.Key(repoWorkspace, RepoKind, name)}
if c.repos == nil {
return eventstream.WatchRepo{}, keys, errors.New("no reader for AtprotoRepo objects is configured")
}
repo, err := c.repos.AtprotoRepo(ctx, repoWorkspace, name)
if err != nil {
return eventstream.WatchRepo{}, keys, readFailed(fmt.Errorf("reading AtprotoRepo %s: %w", name, err))
}
out := eventstream.WatchRepo{DID: strings.TrimSpace(repo.Status.DID),
Ref: &commonv1.ObjectRef{Workspace: repoWorkspace, Group: v1alpha1.GroupName, Kind: RepoKind, Name: name}}
backend := repo.Spec.BackendRef
backendName := strings.TrimSpace(backend.Name)
if backendName == "" {
if out.DID != "" {
return out, keys, nil
}
return eventstream.WatchRepo{}, keys, fmt.Errorf("AtprotoRepo %s names no backendRef", name)
}
backendWorkspace := backend.InWorkspace(repoWorkspace)
kind := strings.TrimSpace(backend.Kind)
keys = append(keys, binding.Key(backendWorkspace, kind, backendName))
if out.DID != "" {
return out, keys, nil
}
switch kind {
case LocalRepoKind:
local, err := c.repos.LocalRepo(ctx, backendWorkspace, backendName)
if err != nil {
return eventstream.WatchRepo{}, keys, readFailed(fmt.Errorf("reading LocalRepo %s: %w", backendName, err))
}
out.DID = strings.TrimSpace(local.Spec.DID)
case RemoteRepoKind:
remote, err := c.repos.RemoteRepo(ctx, backendWorkspace, backendName)
if err != nil {
return eventstream.WatchRepo{}, keys, readFailed(fmt.Errorf("reading RemoteRepo %s: %w", backendName, err))
}
out.DID = strings.TrimSpace(remote.Spec.DID)
default:
return eventstream.WatchRepo{}, keys, fmt.Errorf("AtprotoRepo %s backendRef kind %q is neither LocalRepo nor RemoteRepo", name, backend.Kind)
}
return out, keys, nil
}
func matchKeys(workspace string, spec v1alpha1.AtprotoRecordWatchSpec) []string {
var out []string
for _, match := range spec.Match {
if match.ValueFrom != nil && strings.TrimSpace(match.ValueFrom.Name) != "" {
out = append(out, atprotorecord.ReferenceKey(workspace, *match.ValueFrom))
}
}
return out
}