...
1 package topology
2
3 import (
4 "context"
5 "errors"
6 "strconv"
7
8 v1 "k8s.io/api/core/v1"
9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10 "k8s.io/apimachinery/pkg/types"
11 "sigs.k8s.io/controller-runtime/pkg/client"
12 "sigs.k8s.io/controller-runtime/pkg/predicate"
13
14 "edge-infra.dev/pkg/edge/api/graph/model"
15 linkerd "edge-infra.dev/pkg/edge/linkerd"
16 )
17
18 const (
19
20 Name string = "topology-info"
21
22 Namespace string = "kube-public"
23
24 downlinkRateKey string = "downlink_rate_limit"
25 uplinkRateKey string = "uplink_rate_limit"
26 gatewayEnabledKey string = "egress_gateway_enabled"
27 gatewayRateLimitEnabledKey string = "gateway_rate_limiting_enabled"
28 thickPosKey string = "thick_pos"
29 linkerdIdentityCertDurationKey string = "linkerd_identity_issuer_cert_duration"
30 linkerdIdentityCertRenewBeforeKey string = "linkerd_identity_issuer_cert_renew_before"
31 )
32
33
34 var (
35
36 ErrInvalidCertificateDurationOrRenewBefore = errors.New("linkerd identity: certificate duration and renew before must be positive")
37
38 ErrInvalidCertificateRenewBefore = errors.New("linkerd identity: duration must be greater than the certificate renew before")
39 )
40
41
42 type Info struct {
43
44 DownlinkRateLimit uint64
45
46 UplinkRateLimit uint64
47
48 EgressGatewayEnabled bool
49
50 GatewayRateLimitingEnabled bool
51
52
53
54 ThickPOS bool
55
56
57 LinkerdIdentityCertDuration int
58
59
60
61 LinkerdIdentityCertRenewBefore int
62 }
63
64
65 func New() *Info {
66 return &Info{
67 DownlinkRateLimit: defaultRateLimit,
68 UplinkRateLimit: defaultRateLimit,
69 EgressGatewayEnabled: false,
70 GatewayRateLimitingEnabled: false,
71 ThickPOS: false,
72 LinkerdIdentityCertDuration: int(linkerd.DefaultThinPosIdentityIssuerCertificateDurationHours),
73 LinkerdIdentityCertRenewBefore: int(linkerd.DefaultThinPosIdentityIssuerCertificateRenewBeforeHours),
74 }
75 }
76
77
78 func (i *Info) FromClient(ctx context.Context, c client.Client) (*Info, error) {
79 cm := &v1.ConfigMap{}
80 if err := c.Get(ctx, configMapKey(), cm); err != nil {
81 return New(), err
82 }
83 return i.FromConfigMap(cm), nil
84 }
85
86
87 func (i *Info) FromConfigMap(cm *v1.ConfigMap) *Info {
88 i.DownlinkRateLimit = convertRateLimitToBits(cm.Data[downlinkRateKey])
89 i.UplinkRateLimit = convertRateLimitToBits(cm.Data[uplinkRateKey])
90
91 if egressGatewayEnabled, err := strconv.ParseBool(cm.Data[gatewayEnabledKey]); err == nil {
92 i.EgressGatewayEnabled = egressGatewayEnabled
93 }
94
95 if gatewayRateLimitingEnabled, err := strconv.ParseBool(cm.Data[gatewayRateLimitEnabledKey]); err == nil {
96 i.GatewayRateLimitingEnabled = gatewayRateLimitingEnabled
97 }
98
99 if thickPOS, err := strconv.ParseBool(cm.Data[thickPosKey]); err == nil {
100 i.ThickPOS = thickPOS
101 }
102
103 if linkerdIdentityCertDuration, err := strconv.Atoi(cm.Data[linkerdIdentityCertDurationKey]); err == nil {
104 i.LinkerdIdentityCertDuration = i.defaultCertDuration(linkerdIdentityCertDuration)
105 }
106
107 if linkerdIdentityCertRenewBefore, err := strconv.Atoi(cm.Data[linkerdIdentityCertRenewBeforeKey]); err == nil {
108 i.LinkerdIdentityCertRenewBefore = i.defaultCertRenewBefore(linkerdIdentityCertRenewBefore)
109 }
110 return i
111 }
112
113
114 func (i *Info) defaultCertDuration(certDuration int) int {
115 if certDuration >= 24 {
116 return certDuration
117 }
118
119 if i.ThickPOS {
120 return int(linkerd.DefaultThickPosIdentityIssuerCertificateDurationHours)
121 }
122 return int(linkerd.DefaultThinPosIdentityIssuerCertificateDurationHours)
123 }
124
125
126 func (i *Info) defaultCertRenewBefore(certRenewBefore int) int {
127 if certRenewBefore >= 18 {
128 return certRenewBefore
129 }
130
131 if i.ThickPOS {
132 return int(linkerd.DefaultThickPosIdentityIssuerCertificateRenewBeforeHours)
133 }
134 return int(linkerd.DefaultThinPosIdentityIssuerCertificateRenewBeforeHours)
135 }
136
137
138 func (i *Info) FromGraphQLModel(cfg model.ClusterConfig) *Info {
139
140 linkerdIdentityIssuerCertDuration := cfg.MaximumLanOutageHours
141 linkerdIdentityIssuerCertRenewBefore := linkerdIdentityIssuerCertDuration * 3 / 4
142
143 tpInfo := &Info{
144 ThickPOS: cfg.ThickPos,
145 GatewayRateLimitingEnabled: cfg.GatewayRateLimitingEnabled,
146 EgressGatewayEnabled: cfg.EgressGatewayEnabled,
147 LinkerdIdentityCertDuration: linkerdIdentityIssuerCertDuration,
148 LinkerdIdentityCertRenewBefore: linkerdIdentityIssuerCertRenewBefore,
149 DownlinkRateLimit: convertRateLimitToBits(cfg.DownlinkRateLimit),
150 UplinkRateLimit: convertRateLimitToBits(cfg.UplinkRateLimit),
151 }
152 return tpInfo
153 }
154
155
156 func (i *Info) ToConfigMap() *v1.ConfigMap {
157 return &v1.ConfigMap{
158 TypeMeta: typemeta(),
159 ObjectMeta: metadata(),
160 Data: map[string]string{
161 downlinkRateKey: convertBitsToMbits(i.DownlinkRateLimit),
162 uplinkRateKey: convertBitsToMbits(i.UplinkRateLimit),
163 gatewayEnabledKey: strconv.FormatBool(i.EgressGatewayEnabled),
164 thickPosKey: strconv.FormatBool(i.ThickPOS),
165 gatewayRateLimitEnabledKey: strconv.FormatBool(i.GatewayRateLimitingEnabled),
166 linkerdIdentityCertDurationKey: strconv.Itoa(i.LinkerdIdentityCertDuration),
167 linkerdIdentityCertRenewBeforeKey: strconv.Itoa(i.LinkerdIdentityCertRenewBefore),
168 },
169 }
170 }
171
172
173 func PredicateFilter() predicate.Funcs {
174 return predicate.NewPredicateFuncs(func(object client.Object) bool {
175 return object.GetNamespace() == Namespace && object.GetName() == Name
176 })
177 }
178
179
180 func newTopologyInfoConfigMap() v1.ConfigMap {
181 return v1.ConfigMap{
182 TypeMeta: typemeta(),
183 ObjectMeta: metadata(),
184 }
185 }
186
187
188 func typemeta() metav1.TypeMeta {
189 return metav1.TypeMeta{
190 Kind: "ConfigMap",
191 APIVersion: v1.SchemeGroupVersion.String(),
192 }
193 }
194
195
196 func metadata() metav1.ObjectMeta {
197 return metav1.ObjectMeta{
198 Name: Name,
199 Namespace: Namespace,
200 }
201 }
202
203
204 func configMapKey() types.NamespacedName {
205 return types.NamespacedName{
206 Name: Name,
207 Namespace: Namespace,
208 }
209 }
210
View as plain text