-
Notifications
You must be signed in to change notification settings - Fork 104
/
services.go
94 lines (78 loc) · 3.69 KB
/
services.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
// Copyright 2019-2022 The Liqo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package forge
import (
corev1 "k8s.io/api/core/v1"
corev1apply "k8s.io/client-go/applyconfigurations/core/v1"
"k8s.io/utils/pointer"
liqoconst "github.com/liqotech/liqo/pkg/consts"
)
// nodePortUnset -> the value representing an unset NodePort.
const nodePortUnset = 0
// RemoteService forges the apply patch for the reflected service, given the local one.
func RemoteService(local *corev1.Service, targetNamespace string) *corev1apply.ServiceApplyConfiguration {
return corev1apply.Service(local.GetName(), targetNamespace).
WithLabels(local.GetLabels()).WithLabels(ReflectionLabels()).
WithAnnotations(local.GetAnnotations()).
WithSpec(RemoteServiceSpec(local.Spec.DeepCopy(), getForceRemoteNodePort(local)))
}
// RemoteServiceSpec forges the apply patch for the specs of the reflected service, given the local ones.
// It expects the local object to be a deepcopy, as it is mutated.
func RemoteServiceSpec(local *corev1.ServiceSpec, forceRemoteNodePort bool) *corev1apply.ServiceSpecApplyConfiguration {
remote := corev1apply.ServiceSpec().
WithType(local.Type).WithSelector(local.Selector).
WithPorts(RemoteServicePorts(local.Ports, forceRemoteNodePort)...).
WithExternalName(local.ExternalName)
// The additional fields are set manually instead of using the "With" functions,
// to avoid issues if not set in the local object and thus nil. This requires the
// local object to be a deepcopy to avoid mutating the original from the cache.
remote.AllocateLoadBalancerNodePorts = local.AllocateLoadBalancerNodePorts
remote.ExternalTrafficPolicy = &local.ExternalTrafficPolicy
remote.InternalTrafficPolicy = local.InternalTrafficPolicy
remote.IPFamilyPolicy = local.IPFamilyPolicy
remote.LoadBalancerClass = local.LoadBalancerClass
remote.LoadBalancerSourceRanges = local.LoadBalancerSourceRanges
remote.PublishNotReadyAddresses = &local.PublishNotReadyAddresses
remote.SessionAffinity = &local.SessionAffinity
if local.ClusterIP == corev1.ClusterIPNone {
remote.ClusterIP = pointer.String(corev1.ClusterIPNone)
}
return remote
}
// RemoteServicePorts forges the apply patch for the ports of the reflected service, given the local ones.
func RemoteServicePorts(locals []corev1.ServicePort, forceRemoteNodePort bool) []*corev1apply.ServicePortApplyConfiguration {
var remotes []*corev1apply.ServicePortApplyConfiguration
for _, local := range locals {
remote := corev1apply.ServicePort().WithName(local.Name).WithPort(local.Port).
WithTargetPort(local.TargetPort).WithProtocol(local.Protocol)
if local.NodePort == nodePortUnset {
// Ensure the nodeport is unset in case it is removed, to allow
// switching from a NodePort to a ClusterIP service.
remote.WithNodePort(nodePortUnset)
}
if forceRemoteNodePort {
remote.WithNodePort(local.NodePort)
}
if local.AppProtocol != nil {
// Need to check to avoid dereferencing a nil pointer.
remote.WithAppProtocol(*local.AppProtocol)
}
remotes = append(remotes, remote)
}
return remotes
}
func getForceRemoteNodePort(local *corev1.Service) bool {
val, ok := local.Annotations[liqoconst.ForceRemoteNodePortAnnotationKey]
return ok && val == "true"
}