talos

Форк
0
/
cluster.go 
132 строки · 3.6 Кб
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4

5
// Package cluster provides functions to access, check and inspect Talos clusters.
6
package cluster
7

8
import (
9
	"context"
10
	"fmt"
11
	"io"
12
	"net/netip"
13
	"sort"
14

15
	"github.com/siderolabs/gen/maps"
16
	"github.com/siderolabs/gen/xslices"
17
	"k8s.io/client-go/kubernetes"
18
	"k8s.io/client-go/rest"
19

20
	k8s "github.com/siderolabs/talos/pkg/kubernetes"
21
	"github.com/siderolabs/talos/pkg/machinery/client"
22
	"github.com/siderolabs/talos/pkg/machinery/config/machine"
23
)
24

25
// ClientProvider builds Talos client by endpoint.
26
//
27
// Client instance should be cached and closed when Close() is called.
28
type ClientProvider interface {
29
	// Client returns Talos client instance for default (if no endpoints are given) or
30
	// specific endpoint.
31
	Client(endpoints ...string) (*client.Client, error)
32
	// Close client connections.
33
	Close() error
34
}
35

36
// K8sProvider builds Kubernetes client to access Talos cluster.
37
type K8sProvider interface {
38
	Kubeconfig(ctx context.Context) ([]byte, error)
39
	K8sRestConfig(ctx context.Context) (*rest.Config, error)
40
	K8sClient(ctx context.Context) (*kubernetes.Clientset, error)
41
	K8sHelper(ctx context.Context) (*k8s.Client, error)
42
	K8sClose() error
43
}
44

45
// CrashDumper captures Talos cluster state to the specified writer for debugging.
46
type CrashDumper interface {
47
	CrashDump(ctx context.Context, out io.Writer)
48
}
49

50
// NodeInfo describes a Talos node.
51
type NodeInfo struct {
52
	InternalIP netip.Addr
53
	IPs        []netip.Addr
54
}
55

56
// Info describes the Talos cluster.
57
type Info interface {
58
	// Nodes returns list of all node infos.
59
	Nodes() []NodeInfo
60
	// NodesByType return list of node endpoints by type.
61
	NodesByType(machine.Type) []NodeInfo
62
}
63

64
// Bootstrapper performs Talos cluster bootstrap.
65
type Bootstrapper interface {
66
	Bootstrap(ctx context.Context, out io.Writer) error
67
}
68

69
// IPsToNodeInfos converts list of IPs to a list of NodeInfos.
70
func IPsToNodeInfos(ips []string) ([]NodeInfo, error) {
71
	result := make([]NodeInfo, len(ips))
72

73
	for i, ip := range ips {
74
		info, err := IPToNodeInfo(ip)
75
		if err != nil {
76
			return nil, err
77
		}
78

79
		result[i] = *info
80
	}
81

82
	return result, nil
83
}
84

85
// IPToNodeInfo converts a node internal IP to a NodeInfo.
86
func IPToNodeInfo(ip string) (*NodeInfo, error) {
87
	parsed, err := netip.ParseAddr(ip)
88
	if err != nil {
89
		return nil, err
90
	}
91

92
	return &NodeInfo{
93
		InternalIP: parsed,
94
		IPs:        []netip.Addr{parsed},
95
	}, nil
96
}
97

98
// NodesMatch asserts that the provided expected set of nodes match the actual set of nodes.
99
//
100
// Each expectedNode IPs should have a non-empty intersection with actualNode IPs.
101
func NodesMatch(expected, actual []NodeInfo) error {
102
	actualNodes := xslices.ToMap(actual, func(n NodeInfo) (*NodeInfo, struct{}) { return &n, struct{}{} })
103

104
	for _, expectedNodeInfo := range expected {
105
		found := false
106

107
		for actualNodeInfo := range actualNodes {
108
			// expectedNodeInfo.IPs intersection with actualNodeInfo.IPs is not empty
109
			if len(maps.Intersect(xslices.ToSet(actualNodeInfo.IPs), xslices.ToSet(expectedNodeInfo.IPs))) > 0 {
110
				delete(actualNodes, actualNodeInfo)
111

112
				found = true
113

114
				break
115
			}
116
		}
117

118
		if !found {
119
			return fmt.Errorf("can't find expected node with IPs %q", expectedNodeInfo.IPs)
120
		}
121
	}
122

123
	if len(actualNodes) > 0 {
124
		unexpectedIPs := xslices.FlatMap(maps.Keys(actualNodes), func(n *NodeInfo) []netip.Addr { return n.IPs })
125

126
		sort.Slice(unexpectedIPs, func(i, j int) bool { return unexpectedIPs[i].Less(unexpectedIPs[j]) })
127

128
		return fmt.Errorf("unexpected nodes with IPs %q", unexpectedIPs)
129
	}
130

131
	return nil
132
}
133

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.