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
package compose
import (
"context"
"errors"
"fmt"
"slices"
"strings"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apisv1alpha2 "github.com/kcp-dev/sdk/apis/apis/v1alpha2"
"github.com/johnandersen777/socialweb-computer-kcp/api/kcpgvr"
"github.com/johnandersen777/socialweb-computer-kcp/internal/controllers/runtime/kube"
)
const RootBindTimeout = 3 * time.Minute
var RootExports = []string{ExportApplications, ExportPolicy, ExportExposures, ExportPDS, ExportEvents, ExportHostProcesses}
var APIBindingGVR = kcpgvr.APIBindings
func BindingReady(b *apisv1alpha2.APIBinding) bool {
if b == nil {
return false
}
for _, c := range b.Status.Conditions {
if c.Type == "Ready" && c.Status == "True" {
return true
}
}
return false
}
func unbound(items []apisv1alpha2.APIBinding, exports []string) []string {
ready := map[string]bool{}
for i := range items {
if ref := items[i].Spec.Reference.Export; ref != nil && BindingReady(&items[i]) {
ready[ref.Name] = true
}
}
return slices.DeleteFunc(slices.Clone(exports), func(e string) bool { return ready[e] })
}
func AwaitBound(ctx context.Context, bindings kube.Resource, timeout time.Duration, exports ...string) error {
seen, err := kube.AwaitList(ctx, bindings, metav1.ListOptions{}, timeout, func(items []apisv1alpha2.APIBinding) (bool, error) {
return len(unbound(items, exports)) == 0, nil
})
if errors.Is(err, kube.ErrAwaitTimeout) {
return fmt.Errorf("compose: no Ready APIBinding for the exports %s within %s", strings.Join(unbound(seen, exports), ", "), timeout)
}
return err
}