istio

Форк
0
233 строки · 7.2 Кб
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package ambient
16

17
import (
18
	"fmt"
19
	"net/netip"
20
	"strings"
21

22
	v1 "k8s.io/api/core/v1"
23

24
	"istio.io/istio/pilot/pkg/model"
25
	"istio.io/istio/pkg/config/labels"
26
	"istio.io/istio/pkg/workloadapi"
27
)
28

29
// name format: <cluster>/<group>/<kind>/<namespace>/<name></section-name>
30
func (a *index) generatePodUID(p *v1.Pod) string {
31
	return a.ClusterID.String() + "//" + "Pod/" + p.Namespace + "/" + p.Name
32
}
33

34
// name format: <cluster>/<group>/<kind>/<namespace>/<name></section-name>
35
// if the WorkloadEntry is inlined in the ServiceEntry, we may need section name. caller should use generateServiceEntryUID
36
func (a *index) generateWorkloadEntryUID(wkEntryNamespace, wkEntryName string) string {
37
	return a.ClusterID.String() + "/networking.istio.io/WorkloadEntry/" + wkEntryNamespace + "/" + wkEntryName
38
}
39

40
// name format: <cluster>/<group>/<kind>/<namespace>/<name></section-name>
41
// section name should be the WE address, which needs to be stable across SE updates (it is assumed WE addresses are unique)
42
func (a *index) generateServiceEntryUID(svcEntryNamespace, svcEntryName, addr string) string {
43
	return a.ClusterID.String() + "/networking.istio.io/ServiceEntry/" + svcEntryNamespace + "/" + svcEntryName + "/" + addr
44
}
45

46
func workloadToAddressInfo(w *workloadapi.Workload) model.AddressInfo {
47
	return model.AddressInfo{
48
		Address: &workloadapi.Address{
49
			Type: &workloadapi.Address_Workload{
50
				Workload: w,
51
			},
52
		},
53
	}
54
}
55

56
func modelWorkloadToAddressInfo(w model.WorkloadInfo) model.AddressInfo {
57
	return workloadToAddressInfo(w.Workload)
58
}
59

60
func serviceToAddressInfo(s *workloadapi.Service) model.AddressInfo {
61
	return model.AddressInfo{
62
		Address: &workloadapi.Address{
63
			Type: &workloadapi.Address_Service{
64
				Service: s,
65
			},
66
		},
67
	}
68
}
69

70
func mustByteIPToString(b []byte) string {
71
	ip, _ := netip.AddrFromSlice(b) // Address only comes from objects we create, so it must be valid
72
	return ip.String()
73
}
74

75
func byteIPToAddr(b []byte) netip.Addr {
76
	ip, _ := netip.AddrFromSlice(b) // Address only comes from objects we create, so it must be valid
77
	return ip
78
}
79

80
func (a index) getWaypointAddress(w *Waypoint) *workloadapi.GatewayAddress {
81
	// probably overly cautious... I don't think the ambient index impl counts something with zero addresses as waypoint
82
	if w != nil && len(w.Addresses) >= 1 {
83
		return &workloadapi.GatewayAddress{
84
			Destination: &workloadapi.GatewayAddress_Address{
85
				// probably use from Cidr instead?
86
				Address: a.toNetworkAddressFromIP(w.Addresses[0]),
87
			},
88
			// TODO: look up the HBONE port instead of hardcoding it
89
			HboneMtlsPort: 15008,
90
		}
91
	}
92
	return nil
93
}
94

95
func (a *index) toNetworkAddress(vip string) (*workloadapi.NetworkAddress, error) {
96
	ip, err := netip.ParseAddr(vip)
97
	if err != nil {
98
		return nil, fmt.Errorf("parse %v: %v", vip, err)
99
	}
100
	return &workloadapi.NetworkAddress{
101
		Network: a.Network(vip, make(labels.Instance, 0)).String(),
102
		Address: ip.AsSlice(),
103
	}, nil
104
}
105

106
func (a *index) toNetworkAddressFromIP(ip netip.Addr) *workloadapi.NetworkAddress {
107
	return &workloadapi.NetworkAddress{
108
		Network: a.Network(ip.String(), make(labels.Instance, 0)).String(),
109
		Address: ip.AsSlice(),
110
	}
111
}
112

113
func (a *index) toNetworkAddressFromCidr(vip string) (*workloadapi.NetworkAddress, error) {
114
	ip, err := parseCidrOrIP(vip)
115
	if err != nil {
116
		return nil, err
117
	}
118
	return &workloadapi.NetworkAddress{
119
		Network: a.Network(vip, make(labels.Instance, 0)).String(),
120
		Address: ip.AsSlice(),
121
	}, nil
122
}
123

124
// parseCidrOrIP parses an IP or a CIDR of a exactly 1 IP (e.g. /32).
125
// This is to support ServiceEntry which supports CIDRs, but we don't currently support more than 1 IP
126
func parseCidrOrIP(ip string) (netip.Addr, error) {
127
	if strings.Contains(ip, "/") {
128
		prefix, err := netip.ParsePrefix(ip)
129
		if err != nil {
130
			return netip.Addr{}, err
131
		}
132
		if !prefix.IsSingleIP() {
133
			return netip.Addr{}, fmt.Errorf("only single IP CIDR is allowed")
134
		}
135
		return prefix.Addr(), nil
136
	}
137
	return netip.ParseAddr(ip)
138
}
139

140
func AppendNonNil[T any](data []T, i *T) []T {
141
	if i != nil {
142
		data = append(data, *i)
143
	}
144
	return data
145
}
146

147
func IsPodRunning(pod *v1.Pod) bool {
148
	return pod.Status.Phase == v1.PodRunning
149
}
150

151
func IsPodPending(pod *v1.Pod) bool {
152
	return pod.Status.Phase == v1.PodPending
153
}
154

155
// IsPodReady is copied from kubernetes/pkg/api/v1/pod/utils.go
156
func IsPodReady(pod *v1.Pod) bool {
157
	return IsPodReadyConditionTrue(pod.Status)
158
}
159

160
// IsPodReadyConditionTrue returns true if a pod is ready; false otherwise.
161
func IsPodReadyConditionTrue(status v1.PodStatus) bool {
162
	condition := GetPodReadyCondition(status)
163
	return condition != nil && condition.Status == v1.ConditionTrue
164
}
165

166
func GetPodReadyCondition(status v1.PodStatus) *v1.PodCondition {
167
	_, condition := GetPodCondition(&status, v1.PodReady)
168
	return condition
169
}
170

171
func GetPodCondition(status *v1.PodStatus, conditionType v1.PodConditionType) (int, *v1.PodCondition) {
172
	if status == nil {
173
		return -1, nil
174
	}
175
	return GetPodConditionFromList(status.Conditions, conditionType)
176
}
177

178
// GetPodConditionFromList extracts the provided condition from the given list of condition and
179
// returns the index of the condition and the condition. Returns -1 and nil if the condition is not present.
180
func GetPodConditionFromList(conditions []v1.PodCondition, conditionType v1.PodConditionType) (int, *v1.PodCondition) {
181
	if conditions == nil {
182
		return -1, nil
183
	}
184
	for i := range conditions {
185
		if conditions[i].Type == conditionType {
186
			return i, &conditions[i]
187
		}
188
	}
189
	return -1, nil
190
}
191

192
func FindPortName(pod *v1.Pod, name string) (int32, bool) {
193
	for _, container := range pod.Spec.Containers {
194
		for _, port := range container.Ports {
195
			if port.Name == name && port.Protocol == v1.ProtocolTCP {
196
				return port.ContainerPort, true
197
			}
198
		}
199
	}
200
	return 0, false
201
}
202

203
func namespacedHostname(namespace, hostname string) string {
204
	return namespace + "/" + hostname
205
}
206

207
func networkAddressFromWorkload(wl model.WorkloadInfo) []networkAddress {
208
	networkAddrs := make([]networkAddress, 0, len(wl.Addresses))
209
	for _, addr := range wl.Addresses {
210
		// mustByteIPToString is ok since this is from our IP constructed
211
		networkAddrs = append(networkAddrs, networkAddress{network: wl.Network, ip: mustByteIPToString(addr)})
212
	}
213
	return networkAddrs
214
}
215

216
func networkAddressFromService(s model.ServiceInfo) []networkAddress {
217
	networkAddrs := make([]networkAddress, 0, len(s.Addresses))
218
	for _, addr := range s.Addresses {
219
		// mustByteIPToString is ok since this is from our IP constructed
220
		networkAddrs = append(networkAddrs, networkAddress{network: addr.Network, ip: mustByteIPToString(addr.Address)})
221
	}
222
	return networkAddrs
223
}
224

225
// internal object used for indexing in ambientindex maps
226
type networkAddress struct {
227
	network string
228
	ip      string
229
}
230

231
func (n *networkAddress) String() string {
232
	return n.network + "/" + n.ip
233
}
234

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

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

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

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