-
Notifications
You must be signed in to change notification settings - Fork 453
/
cluster.go
132 lines (106 loc) · 3.6 KB
/
cluster.go
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Package cluster provides functions to access, check and inspect Talos clusters.
package cluster
import (
"context"
"fmt"
"io"
"net/netip"
"sort"
"github.com/siderolabs/gen/maps"
"github.com/siderolabs/gen/xslices"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
k8s "github.com/siderolabs/talos/pkg/kubernetes"
"github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
)
// ClientProvider builds Talos client by endpoint.
//
// Client instance should be cached and closed when Close() is called.
type ClientProvider interface {
// Client returns Talos client instance for default (if no endpoints are given) or
// specific endpoint.
Client(endpoints ...string) (*client.Client, error)
// Close client connections.
Close() error
}
// K8sProvider builds Kubernetes client to access Talos cluster.
type K8sProvider interface {
Kubeconfig(ctx context.Context) ([]byte, error)
K8sRestConfig(ctx context.Context) (*rest.Config, error)
K8sClient(ctx context.Context) (*kubernetes.Clientset, error)
K8sHelper(ctx context.Context) (*k8s.Client, error)
K8sClose() error
}
// CrashDumper captures Talos cluster state to the specified writer for debugging.
type CrashDumper interface {
CrashDump(ctx context.Context, out io.Writer)
}
// NodeInfo describes a Talos node.
type NodeInfo struct {
InternalIP netip.Addr
IPs []netip.Addr
}
// Info describes the Talos cluster.
type Info interface {
// Nodes returns list of all node infos.
Nodes() []NodeInfo
// NodesByType return list of node endpoints by type.
NodesByType(machine.Type) []NodeInfo
}
// Bootstrapper performs Talos cluster bootstrap.
type Bootstrapper interface {
Bootstrap(ctx context.Context, out io.Writer) error
}
// IPsToNodeInfos converts list of IPs to a list of NodeInfos.
func IPsToNodeInfos(ips []string) ([]NodeInfo, error) {
result := make([]NodeInfo, len(ips))
for i, ip := range ips {
info, err := IPToNodeInfo(ip)
if err != nil {
return nil, err
}
result[i] = *info
}
return result, nil
}
// IPToNodeInfo converts a node internal IP to a NodeInfo.
func IPToNodeInfo(ip string) (*NodeInfo, error) {
parsed, err := netip.ParseAddr(ip)
if err != nil {
return nil, err
}
return &NodeInfo{
InternalIP: parsed,
IPs: []netip.Addr{parsed},
}, nil
}
// NodesMatch asserts that the provided expected set of nodes match the actual set of nodes.
//
// Each expectedNode IPs should have a non-empty intersection with actualNode IPs.
func NodesMatch(expected, actual []NodeInfo) error {
actualNodes := xslices.ToMap(actual, func(n NodeInfo) (*NodeInfo, struct{}) { return &n, struct{}{} })
for _, expectedNodeInfo := range expected {
found := false
for actualNodeInfo := range actualNodes {
// expectedNodeInfo.IPs intersection with actualNodeInfo.IPs is not empty
if len(maps.Intersect(xslices.ToSet(actualNodeInfo.IPs), xslices.ToSet(expectedNodeInfo.IPs))) > 0 {
delete(actualNodes, actualNodeInfo)
found = true
break
}
}
if !found {
return fmt.Errorf("can't find expected node with IPs %q", expectedNodeInfo.IPs)
}
}
if len(actualNodes) > 0 {
unexpectedIPs := xslices.FlatMap(maps.Keys(actualNodes), func(n *NodeInfo) []netip.Addr { return n.IPs })
sort.Slice(unexpectedIPs, func(i, j int) bool { return unexpectedIPs[i].Less(unexpectedIPs[j]) })
return fmt.Errorf("unexpected nodes with IPs %q", unexpectedIPs)
}
return nil
}