mirror of
https://github.com/tailscale/tailscale.git
synced 2025-07-28 23:04:10 +00:00
k8s-operator: use iota-based enums (#14323)
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
This commit is contained in:
parent
e2e5914d57
commit
91e923e842
@ -30,7 +30,6 @@ import (
|
||||
|
||||
const (
|
||||
dnsRecordsRecocilerFinalizer = "tailscale.com/dns-records-reconciler"
|
||||
annotationTSMagicDNSName = "tailscale.com/magic-dnsname"
|
||||
)
|
||||
|
||||
// dnsRecordsReconciler knows how to update dnsrecords ConfigMap with DNS
|
||||
@ -159,7 +158,7 @@ func (dnsRR *dnsRecordsReconciler) maybeProvision(ctx context.Context, headlessS
|
||||
// Ensure that headless Service is annotated with the current MagicDNS
|
||||
// name to help with records cleanup when proxy resources are deleted or
|
||||
// MagicDNS name changes.
|
||||
oldFqdn := headlessSvc.Annotations[annotationTSMagicDNSName]
|
||||
oldFqdn := AnnotationMagicDNSName.GetValue(headlessSvc)
|
||||
if oldFqdn != "" && oldFqdn != fqdn { // i.e user has changed the value of tailscale.com/tailnet-fqdn annotation
|
||||
logger.Debugf("MagicDNS name has changed, remvoving record for %s", oldFqdn)
|
||||
updateFunc := func(rec *operatorutils.Records) {
|
||||
@ -169,7 +168,7 @@ func (dnsRR *dnsRecordsReconciler) maybeProvision(ctx context.Context, headlessS
|
||||
return fmt.Errorf("error removing record for %s: %w", oldFqdn, err)
|
||||
}
|
||||
}
|
||||
mak.Set(&headlessSvc.Annotations, annotationTSMagicDNSName, fqdn)
|
||||
mak.Set(&headlessSvc.Annotations, AnnotationMagicDNSName.String(), fqdn)
|
||||
if !apiequality.Semantic.DeepEqual(oldHeadlessSvc, headlessSvc) {
|
||||
logger.Infof("provisioning DNS record for MagicDNS name: %s", fqdn) // this will be printed exactly once
|
||||
if err := dnsRR.Update(ctx, headlessSvc); err != nil {
|
||||
@ -267,7 +266,7 @@ func (h *dnsRecordsReconciler) maybeCleanup(ctx context.Context, headlessSvc *co
|
||||
logger.Debug("'dnsrecords' ConfigMap contains no records")
|
||||
return h.removeHeadlessSvcFinalizer(ctx, headlessSvc)
|
||||
}
|
||||
fqdn, _ := headlessSvc.GetAnnotations()[annotationTSMagicDNSName]
|
||||
fqdn := AnnotationMagicDNSName.GetValue(headlessSvc)
|
||||
if fqdn == "" {
|
||||
return h.removeHeadlessSvcFinalizer(ctx, headlessSvc)
|
||||
}
|
||||
@ -316,7 +315,7 @@ func (dnsRR *dnsRecordsReconciler) fqdnForDNSRecord(ctx context.Context, headles
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return svc.Annotations[AnnotationTailnetTargetFQDN], nil
|
||||
return AnnotationTailnetTargetFQDN.GetValue(svc), nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
@ -363,6 +362,5 @@ func (dnsRR *dnsRecordsReconciler) isSvcForFQDNEgressProxy(ctx context.Context,
|
||||
} else if err != nil {
|
||||
return false, err
|
||||
}
|
||||
annots := parentSvc.Annotations
|
||||
return annots != nil && annots[AnnotationTailnetTargetFQDN] != "", nil
|
||||
return AnnotationTailnetTargetFQDN.GetValue(parentSvc) != "", nil
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ func TestDNSRecordsReconciler(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "egress-fqdn",
|
||||
Namespace: "test",
|
||||
Annotations: map[string]string{"tailscale.com/tailnet-fqdn": "foo.bar.ts.net"},
|
||||
Annotations: map[string]string{AnnotationTailnetTargetFQDN.String(): "foo.bar.ts.net"},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
ExternalName: "unused",
|
||||
@ -104,7 +104,7 @@ func TestDNSRecordsReconciler(t *testing.T) {
|
||||
// 2. DNS record is updated if tailscale.com/tailnet-fqdn annotation's
|
||||
// value changes
|
||||
mustUpdate(t, fc, "test", "egress-fqdn", func(svc *corev1.Service) {
|
||||
svc.Annotations["tailscale.com/tailnet-fqdn"] = "baz.bar.ts.net"
|
||||
svc.Annotations[AnnotationTailnetTargetFQDN.String()] = "baz.bar.ts.net"
|
||||
})
|
||||
expectReconciled(t, dnsRR, "tailscale", "egress-fqdn") // dns-records-reconciler reconcile the headless Service
|
||||
wantHosts = map[string][]string{"baz.bar.ts.net": {"10.9.8.7"}}
|
||||
|
@ -32,8 +32,8 @@ func TestTailscaleEgressEndpointSlices(t *testing.T) {
|
||||
Namespace: "default",
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetFQDN: "foo.bar.ts.net",
|
||||
AnnotationProxyGroup: "foo",
|
||||
AnnotationTailnetTargetFQDN.String(): "foo.bar.ts.net",
|
||||
AnnotationProxyGroup.String(): "foo",
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -135,10 +135,10 @@ func configMapForSvc(t *testing.T, svc *corev1.Service, p uint16) *corev1.Config
|
||||
cfg := egressservices.Config{
|
||||
Ports: ports,
|
||||
}
|
||||
if fqdn := svc.Annotations[AnnotationTailnetTargetFQDN]; fqdn != "" {
|
||||
if fqdn := AnnotationTailnetTargetFQDN.GetValue(svc); fqdn != "" {
|
||||
cfg.TailnetTarget = egressservices.TailnetTarget{FQDN: fqdn}
|
||||
}
|
||||
if ip := svc.Annotations[AnnotationTailnetTargetIP]; ip != "" {
|
||||
if ip := AnnotationTailnetTargetIP.GetValue(svc); ip != "" {
|
||||
cfg.TailnetTarget = egressservices.TailnetTarget{IP: ip}
|
||||
}
|
||||
name := tailnetSvcName(svc)
|
||||
@ -149,7 +149,7 @@ func configMapForSvc(t *testing.T, svc *corev1.Service, p uint16) *corev1.Config
|
||||
}
|
||||
cm := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: pgEgressCMName(svc.Annotations[AnnotationProxyGroup]),
|
||||
Name: pgEgressCMName(AnnotationProxyGroup.GetValue(svc)),
|
||||
Namespace: "operator-ns",
|
||||
},
|
||||
BinaryData: map[string][]byte{egressservices.KeyEgressServices: bs},
|
||||
@ -164,10 +164,10 @@ func serviceStatusForPodIP(t *testing.T, svc *corev1.Service, ip string, p uint1
|
||||
ports[egressservices.PortMap{Protocol: string(port.Protocol), MatchPort: p, TargetPort: uint16(port.Port)}] = struct{}{}
|
||||
}
|
||||
svcSt := egressservices.ServiceStatus{Ports: ports}
|
||||
if fqdn := svc.Annotations[AnnotationTailnetTargetFQDN]; fqdn != "" {
|
||||
if fqdn := AnnotationTailnetTargetFQDN.GetValue(svc); fqdn != "" {
|
||||
svcSt.TailnetTarget = egressservices.TailnetTarget{FQDN: fqdn}
|
||||
}
|
||||
if ip := svc.Annotations[AnnotationTailnetTargetIP]; ip != "" {
|
||||
if ip := AnnotationTailnetTargetIP.GetValue(svc); ip != "" {
|
||||
svcSt.TailnetTarget = egressservices.TailnetTarget{IP: ip}
|
||||
}
|
||||
svcName := tailnetSvcName(svc)
|
||||
|
@ -86,7 +86,7 @@ func (esrr *egressSvcsReadinessReconciler) Reconcile(ctx context.Context, req re
|
||||
}
|
||||
pg := &tsapi.ProxyGroup{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: svc.Annotations[AnnotationProxyGroup],
|
||||
Name: AnnotationProxyGroup.GetValue(svc),
|
||||
},
|
||||
}
|
||||
err = esrr.Get(ctx, client.ObjectKeyFromObject(pg), pg)
|
||||
|
@ -43,8 +43,8 @@ func TestEgressServiceReadiness(t *testing.T) {
|
||||
Name: "my-app",
|
||||
Namespace: "dev",
|
||||
Annotations: map[string]string{
|
||||
AnnotationProxyGroup: "dev",
|
||||
AnnotationTailnetTargetFQDN: tailnetFQDN,
|
||||
AnnotationProxyGroup.String(): "dev",
|
||||
AnnotationTailnetTargetFQDN.String(): tailnetFQDN,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ func (esr *egressSvcsReconciler) maybeProvision(ctx context.Context, svc *corev1
|
||||
upToDate := svcConfigurationUpToDate(svc, l)
|
||||
provisioned := true
|
||||
if !upToDate {
|
||||
if clusterIPSvc, provisioned, err = esr.provision(ctx, svc.Annotations[AnnotationProxyGroup], svc, clusterIPSvc, l); err != nil {
|
||||
if clusterIPSvc, provisioned, err = esr.provision(ctx, AnnotationProxyGroup.GetValue(svc), svc, clusterIPSvc, l); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -403,7 +403,7 @@ func (esr *egressSvcsReconciler) maybeCleanup(ctx context.Context, svc *corev1.S
|
||||
}
|
||||
|
||||
func (esr *egressSvcsReconciler) maybeCleanupProxyGroupConfig(ctx context.Context, svc *corev1.Service, l *zap.SugaredLogger) error {
|
||||
wantsProxyGroup := svc.Annotations[AnnotationProxyGroup]
|
||||
wantsProxyGroup := AnnotationProxyGroup.GetValue(svc)
|
||||
cond := tsoperator.GetServiceCondition(svc, tsapi.EgressSvcConfigured)
|
||||
if cond == nil {
|
||||
return nil
|
||||
@ -506,7 +506,7 @@ func (esr *egressSvcsReconciler) ensureEgressSvcCfgDeleted(ctx context.Context,
|
||||
}
|
||||
|
||||
func (esr *egressSvcsReconciler) validateClusterResources(ctx context.Context, svc *corev1.Service, l *zap.SugaredLogger) (bool, error) {
|
||||
proxyGroupName := svc.Annotations[AnnotationProxyGroup]
|
||||
proxyGroupName := AnnotationProxyGroup.GetValue(svc)
|
||||
pg := &tsapi.ProxyGroup{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: proxyGroupName,
|
||||
@ -563,7 +563,7 @@ func validateEgressService(svc *corev1.Service, pg *tsapi.ProxyGroup) []string {
|
||||
violations := validateService(svc)
|
||||
|
||||
// We check that only one of these two is set in the earlier validateService function.
|
||||
if svc.Annotations[AnnotationTailnetTargetFQDN] == "" && svc.Annotations[AnnotationTailnetTargetIP] == "" {
|
||||
if AnnotationTailnetTargetFQDN.GetValue(svc) == "" && AnnotationTailnetTargetIP.GetValue(svc) == "" {
|
||||
violations = append(violations, fmt.Sprintf("egress Service for ProxyGroup must have one of %s, %s annotations set", AnnotationTailnetTargetFQDN, AnnotationTailnetTargetIP))
|
||||
}
|
||||
if len(svc.Spec.Ports) == 0 {
|
||||
@ -618,13 +618,13 @@ func unusedPort(usedPorts sets.Set[int32]) int32 {
|
||||
// Service must contain exactly one of tailscale.com/tailnet-ip,
|
||||
// tailscale.com/tailnet-fqdn annotations.
|
||||
func tailnetTargetFromSvc(svc *corev1.Service) egressservices.TailnetTarget {
|
||||
if fqdn := svc.Annotations[AnnotationTailnetTargetFQDN]; fqdn != "" {
|
||||
if fqdn := AnnotationTailnetTargetFQDN.GetValue(svc); fqdn != "" {
|
||||
return egressservices.TailnetTarget{
|
||||
FQDN: fqdn,
|
||||
}
|
||||
}
|
||||
return egressservices.TailnetTarget{
|
||||
IP: svc.Annotations[AnnotationTailnetTargetIP],
|
||||
IP: AnnotationTailnetTargetIP.GetValue(svc),
|
||||
}
|
||||
}
|
||||
|
||||
@ -642,8 +642,7 @@ func isEgressSvcForProxyGroup(obj client.Object) bool {
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
annots := s.ObjectMeta.Annotations
|
||||
return annots[AnnotationProxyGroup] != "" && (annots[AnnotationTailnetTargetFQDN] != "" || annots[AnnotationTailnetTargetIP] != "")
|
||||
return AnnotationProxyGroup.GetValue(s) != "" && (AnnotationTailnetTargetFQDN.GetValue(s) != "" || AnnotationTailnetTargetIP.GetValue(s) != "")
|
||||
}
|
||||
|
||||
// egressSvcConfig returns a ConfigMap that contains egress services configuration for the provided ProxyGroup as well
|
||||
@ -684,7 +683,7 @@ func egressSvcChildResourceLabels(svc *corev1.Service) map[string]string {
|
||||
LabelParentType: "svc",
|
||||
LabelParentName: svc.Name,
|
||||
LabelParentNamespace: svc.Namespace,
|
||||
labelProxyGroup: svc.Annotations[AnnotationProxyGroup],
|
||||
labelProxyGroup: AnnotationProxyGroup.GetValue(svc),
|
||||
labelSvcType: typeEgress,
|
||||
}
|
||||
}
|
||||
@ -743,12 +742,12 @@ func svcConfiguredReason(svc *corev1.Service, configured bool, l *zap.SugaredLog
|
||||
} else {
|
||||
r = fmt.Sprintf("ConfigurationFailed:%s", r)
|
||||
}
|
||||
r += fmt.Sprintf("ProxyGroup:%s", svc.Annotations[AnnotationProxyGroup])
|
||||
r += fmt.Sprintf("ProxyGroup:%s", AnnotationProxyGroup.GetValue(svc))
|
||||
tt := tailnetTargetFromSvc(svc)
|
||||
s := cfg{
|
||||
Ports: svc.Spec.Ports,
|
||||
TailnetTarget: tt,
|
||||
ProxyGroup: svc.Annotations[AnnotationProxyGroup],
|
||||
ProxyGroup: AnnotationProxyGroup.GetValue(svc),
|
||||
}
|
||||
r += fmt.Sprintf(":Config:%s", cfgHash(s, l))
|
||||
return r
|
||||
|
@ -69,8 +69,8 @@ func TestTailscaleEgressServices(t *testing.T) {
|
||||
Namespace: "default",
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetFQDN: tailnetTargetFQDN,
|
||||
AnnotationProxyGroup: "foo",
|
||||
AnnotationTailnetTargetFQDN.String(): tailnetTargetFQDN,
|
||||
AnnotationProxyGroup.String(): "foo",
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
|
@ -50,9 +50,6 @@ const (
|
||||
FinalizerNamePG = "tailscale.com/ingress-pg-finalizer"
|
||||
|
||||
indexIngressProxyGroup = ".metadata.annotations.ingress-proxy-group"
|
||||
// annotationHTTPEndpoint can be used to configure the Ingress to expose an HTTP endpoint to tailnet (as
|
||||
// well as the default HTTPS endpoint).
|
||||
annotationHTTPEndpoint = "tailscale.com/http-endpoint"
|
||||
|
||||
labelDomain = "tailscale.com/domain"
|
||||
)
|
||||
@ -147,7 +144,7 @@ func (r *HAIngressReconciler) maybeProvision(ctx context.Context, hostname strin
|
||||
return false, nil
|
||||
}
|
||||
// Get and validate ProxyGroup readiness
|
||||
pgName := ing.Annotations[AnnotationProxyGroup]
|
||||
pgName := ing.Annotations[AnnotationProxyGroup.String()]
|
||||
if pgName == "" {
|
||||
logger.Infof("[unexpected] no ProxyGroup annotation, skipping VIPService provisioning")
|
||||
return false, nil
|
||||
@ -305,7 +302,7 @@ func (r *HAIngressReconciler) maybeProvision(ctx context.Context, hostname strin
|
||||
|
||||
// 4. Ensure that the VIPService exists and is up to date.
|
||||
tags := r.defaultTags
|
||||
if tstr, ok := ing.Annotations[AnnotationTags]; ok {
|
||||
if tstr, ok := ing.Annotations[AnnotationTags.String()]; ok {
|
||||
tags = strings.Split(tstr, ",")
|
||||
}
|
||||
|
||||
@ -498,7 +495,7 @@ func (r *HAIngressReconciler) maybeCleanup(ctx context.Context, hostname string,
|
||||
}()
|
||||
|
||||
// 1. Check if there is a VIPService associated with this Ingress.
|
||||
pg := ing.Annotations[AnnotationProxyGroup]
|
||||
pg := ing.Annotations[AnnotationProxyGroup.String()]
|
||||
cm, cfg, err := r.proxyGroupServeConfig(ctx, pg)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error getting ProxyGroup serve config: %w", err)
|
||||
@ -610,7 +607,7 @@ func (r *HAIngressReconciler) shouldExpose(ing *networkingv1.Ingress) bool {
|
||||
isTSIngress := ing != nil &&
|
||||
ing.Spec.IngressClassName != nil &&
|
||||
*ing.Spec.IngressClassName == tailscaleIngressClassName
|
||||
pgAnnot := ing.Annotations[AnnotationProxyGroup]
|
||||
pgAnnot := ing.Annotations[AnnotationProxyGroup.String()]
|
||||
return isTSIngress && pgAnnot != ""
|
||||
}
|
||||
|
||||
@ -624,7 +621,7 @@ func (r *HAIngressReconciler) validateIngress(ctx context.Context, ing *networki
|
||||
var errs []error
|
||||
|
||||
// Validate tags if present
|
||||
if tstr, ok := ing.Annotations[AnnotationTags]; ok {
|
||||
if tstr, ok := ing.Annotations[AnnotationTags.String()]; ok {
|
||||
tags := strings.Split(tstr, ",")
|
||||
for _, tag := range tags {
|
||||
tag = strings.TrimSpace(tag)
|
||||
@ -714,7 +711,7 @@ func (r *HAIngressReconciler) cleanupVIPService(ctx context.Context, name tailcf
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error marshalling updated VIPService owner reference: %w", err)
|
||||
}
|
||||
svc.Annotations[ownerAnnotation] = string(json)
|
||||
svc.Annotations[AnnotationOwnerReferences.String()] = string(json)
|
||||
return true, r.tsClient.CreateOrUpdateVIPService(ctx, svc)
|
||||
}
|
||||
|
||||
@ -723,7 +720,7 @@ func isHTTPEndpointEnabled(ing *networkingv1.Ingress) bool {
|
||||
if ing == nil {
|
||||
return false
|
||||
}
|
||||
return ing.Annotations[annotationHTTPEndpoint] == "enabled"
|
||||
return AnnotationHTTPEndpoint.GetValue(ing) == "enabled"
|
||||
}
|
||||
|
||||
// serviceAdvertisementMode describes the desired state of a VIPService.
|
||||
@ -824,8 +821,6 @@ func (a *HAIngressReconciler) numberPodsAdvertising(ctx context.Context, pgName
|
||||
return count, nil
|
||||
}
|
||||
|
||||
const ownerAnnotation = "tailscale.com/owner-references"
|
||||
|
||||
// ownerAnnotationValue is the content of the VIPService.Annotation[ownerAnnotation] field.
|
||||
type ownerAnnotationValue struct {
|
||||
// OwnerRefs is a list of owner references that identify all operator
|
||||
@ -856,7 +851,7 @@ func (r *HAIngressReconciler) ownerAnnotations(svc *tailscale.VIPService) (map[s
|
||||
return nil, fmt.Errorf("[unexpected] unable to marshal VIPService owner annotation contents: %w, please report this", err)
|
||||
}
|
||||
return map[string]string{
|
||||
ownerAnnotation: string(json),
|
||||
AnnotationOwnerReferences.String(): string(json),
|
||||
}, nil
|
||||
}
|
||||
o, err := parseOwnerAnnotation(svc)
|
||||
@ -879,18 +874,18 @@ func (r *HAIngressReconciler) ownerAnnotations(svc *tailscale.VIPService) (map[s
|
||||
for k, v := range svc.Annotations {
|
||||
newAnnots[k] = v
|
||||
}
|
||||
newAnnots[ownerAnnotation] = string(json)
|
||||
newAnnots[AnnotationOwnerReferences.String()] = string(json)
|
||||
return newAnnots, nil
|
||||
}
|
||||
|
||||
// parseOwnerAnnotation returns nil if no valid owner found.
|
||||
func parseOwnerAnnotation(vipSvc *tailscale.VIPService) (*ownerAnnotationValue, error) {
|
||||
if vipSvc.Annotations == nil || vipSvc.Annotations[ownerAnnotation] == "" {
|
||||
if vipSvc.Annotations == nil || vipSvc.Annotations[AnnotationOwnerReferences.String()] == "" {
|
||||
return nil, nil
|
||||
}
|
||||
o := &ownerAnnotationValue{}
|
||||
if err := json.Unmarshal([]byte(vipSvc.Annotations[ownerAnnotation]), o); err != nil {
|
||||
return nil, fmt.Errorf("error parsing VIPService %s annotation %q: %w", ownerAnnotation, vipSvc.Annotations[ownerAnnotation], err)
|
||||
if err := json.Unmarshal([]byte(vipSvc.Annotations[AnnotationOwnerReferences.String()]), o); err != nil {
|
||||
return nil, fmt.Errorf("error parsing VIPService %s annotation %q: %w", AnnotationOwnerReferences.String(), vipSvc.Annotations[AnnotationOwnerReferences.String()], err)
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
@ -898,9 +893,9 @@ func parseOwnerAnnotation(vipSvc *tailscale.VIPService) (*ownerAnnotationValue,
|
||||
func ownersAreSetAndEqual(a, b *tailscale.VIPService) bool {
|
||||
return a != nil && b != nil &&
|
||||
a.Annotations != nil && b.Annotations != nil &&
|
||||
a.Annotations[ownerAnnotation] != "" &&
|
||||
b.Annotations[ownerAnnotation] != "" &&
|
||||
strings.EqualFold(a.Annotations[ownerAnnotation], b.Annotations[ownerAnnotation])
|
||||
a.Annotations[AnnotationOwnerReferences.String()] != "" &&
|
||||
b.Annotations[AnnotationOwnerReferences.String()] != "" &&
|
||||
strings.EqualFold(a.Annotations[AnnotationOwnerReferences.String()], b.Annotations[AnnotationOwnerReferences.String()])
|
||||
}
|
||||
|
||||
// ensureCertResources ensures that the TLS Secret for an HA Ingress and RBAC
|
||||
|
@ -277,7 +277,7 @@ func TestValidateIngress(t *testing.T) {
|
||||
Name: "test-ingress",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
AnnotationProxyGroup: "test-pg",
|
||||
AnnotationProxyGroup.String(): "test-pg",
|
||||
},
|
||||
},
|
||||
Spec: networkingv1.IngressSpec{
|
||||
@ -338,7 +338,7 @@ func TestValidateIngress(t *testing.T) {
|
||||
Name: baseIngress.Name,
|
||||
Namespace: baseIngress.Namespace,
|
||||
Annotations: map[string]string{
|
||||
AnnotationTags: "tag:invalid!",
|
||||
AnnotationTags.String(): "tag:invalid!",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -411,7 +411,7 @@ func TestValidateIngress(t *testing.T) {
|
||||
Name: "existing-ingress",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
AnnotationProxyGroup: "test-pg",
|
||||
AnnotationProxyGroup.String(): "test-pg",
|
||||
},
|
||||
},
|
||||
Spec: networkingv1.IngressSpec{
|
||||
@ -759,7 +759,7 @@ func TestIngressPGReconciler_MultiCluster(t *testing.T) {
|
||||
existingVIPSvc := &tailscale.VIPService{
|
||||
Name: "svc:my-svc",
|
||||
Annotations: map[string]string{
|
||||
ownerAnnotation: `{"ownerrefs":[{"operatorID":"operator-2"}]}`,
|
||||
AnnotationOwnerReferences.String(): `{"ownerrefs":[{"operatorID":"operator-2"}]}`,
|
||||
},
|
||||
}
|
||||
ft.vipServices = map[tailcfg.ServiceName]*tailscale.VIPService{
|
||||
|
@ -179,7 +179,7 @@ func (a *IngressReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
|
||||
},
|
||||
},
|
||||
}
|
||||
if opt.Bool(ing.Annotations[AnnotationFunnel]).EqualBool(true) {
|
||||
if opt.Bool(ing.Annotations[AnnotationFunnel.String()]).EqualBool(true) {
|
||||
sc.AllowFunnel = map[ipn.HostPort]bool{
|
||||
magic443: true,
|
||||
}
|
||||
@ -204,7 +204,7 @@ func (a *IngressReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
|
||||
|
||||
crl := childResourceLabels(ing.Name, ing.Namespace, "ingress")
|
||||
var tags []string
|
||||
if tstr, ok := ing.Annotations[AnnotationTags]; ok {
|
||||
if tstr, ok := ing.Annotations[AnnotationTags.String()]; ok {
|
||||
tags = strings.Split(tstr, ",")
|
||||
}
|
||||
hostname := hostnameForIngress(ing)
|
||||
@ -220,7 +220,7 @@ func (a *IngressReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
|
||||
proxyType: proxyTypeIngressResource,
|
||||
}
|
||||
|
||||
if val := ing.GetAnnotations()[AnnotationExperimentalForwardClusterTrafficViaL7IngresProxy]; val == "true" {
|
||||
if val := ing.GetAnnotations()[AnnotationExperimentalForwardClusterTrafficViaL7IngresProxy.String()]; val == "true" {
|
||||
sts.ForwardClusterTrafficViaL7IngressProxy = true
|
||||
}
|
||||
|
||||
@ -264,7 +264,7 @@ func (a *IngressReconciler) shouldExpose(ing *networkingv1.Ingress) bool {
|
||||
return ing != nil &&
|
||||
ing.Spec.IngressClassName != nil &&
|
||||
*ing.Spec.IngressClassName == tailscaleIngressClassName &&
|
||||
ing.Annotations[AnnotationProxyGroup] == ""
|
||||
ing.Annotations[AnnotationProxyGroup.String()] == ""
|
||||
}
|
||||
|
||||
// validateIngressClass attempts to validate that 'tailscale' IngressClass
|
||||
|
@ -94,7 +94,7 @@ func TestTailscaleIngress(t *testing.T) {
|
||||
// 3. Resources get created for Ingress that should allow forwarding
|
||||
// cluster traffic
|
||||
mustUpdate(t, fc, "default", "test", func(ing *networkingv1.Ingress) {
|
||||
mak.Set(&ing.ObjectMeta.Annotations, AnnotationExperimentalForwardClusterTrafficViaL7IngresProxy, "true")
|
||||
mak.Set(&ing.ObjectMeta.Annotations, AnnotationExperimentalForwardClusterTrafficViaL7IngresProxy.String(), "true")
|
||||
})
|
||||
opts.shouldEnableForwardingClusterTrafficViaIngress = true
|
||||
expectReconciled(t, ingR, "default", "test")
|
||||
@ -230,7 +230,8 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) {
|
||||
Spec: tsapi.ProxyClassSpec{StatefulSet: &tsapi.StatefulSet{
|
||||
Labels: tsapi.Labels{"foo": "bar"},
|
||||
Annotations: map[string]string{"bar.io/foo": "some-val"},
|
||||
Pod: &tsapi.Pod{Annotations: map[string]string{"foo.io/bar": "some-val"}}}},
|
||||
Pod: &tsapi.Pod{Annotations: map[string]string{"foo.io/bar": "some-val"}},
|
||||
}},
|
||||
}
|
||||
fc := fake.NewClientBuilder().
|
||||
WithScheme(tsapi.GlobalScheme).
|
||||
@ -285,7 +286,7 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) {
|
||||
// 2. Ingress is updated to specify a ProxyClass, ProxyClass is not yet
|
||||
// ready, so proxy resource configuration does not change.
|
||||
mustUpdate(t, fc, "default", "test", func(ing *networkingv1.Ingress) {
|
||||
mak.Set(&ing.ObjectMeta.Labels, LabelProxyClass, "custom-metadata")
|
||||
mak.Set(&ing.ObjectMeta.Labels, LabelAnnotationProxyClass, "custom-metadata")
|
||||
})
|
||||
expectReconciled(t, ingR, "default", "test")
|
||||
expectEqual(t, fc, expectedSTSUserspace(t, fc, opts), removeHashAnnotation, removeResourceReqs)
|
||||
@ -309,7 +310,7 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) {
|
||||
// Ingress gets reconciled and the custom ProxyClass configuration is
|
||||
// removed from the proxy resources.
|
||||
mustUpdate(t, fc, "default", "test", func(ing *networkingv1.Ingress) {
|
||||
delete(ing.ObjectMeta.Labels, LabelProxyClass)
|
||||
delete(ing.ObjectMeta.Labels, LabelAnnotationProxyClass)
|
||||
})
|
||||
expectReconciled(t, ingR, "default", "test")
|
||||
opts.proxyClass = ""
|
||||
@ -325,14 +326,15 @@ func TestTailscaleIngressWithServiceMonitor(t *testing.T) {
|
||||
Status: metav1.ConditionTrue,
|
||||
Type: string(tsapi.ProxyClassReady),
|
||||
ObservedGeneration: 1,
|
||||
}}},
|
||||
}},
|
||||
},
|
||||
}
|
||||
crd := &apiextensionsv1.CustomResourceDefinition{ObjectMeta: metav1.ObjectMeta{Name: serviceMonitorCRD}}
|
||||
|
||||
// Create fake client with ProxyClass, IngressClass, Ingress with metrics ProxyClass, and Service
|
||||
ing := ingress()
|
||||
ing.Labels = map[string]string{
|
||||
LabelProxyClass: "metrics",
|
||||
LabelAnnotationProxyClass: "metrics",
|
||||
}
|
||||
fc := fake.NewClientBuilder().
|
||||
WithScheme(tsapi.GlobalScheme).
|
||||
@ -452,7 +454,7 @@ func TestIngressLetsEncryptStaging(t *testing.T) {
|
||||
ing := ingress()
|
||||
if tt.proxyClassPerResource != "" {
|
||||
ing.Labels = map[string]string{
|
||||
LabelProxyClass: tt.proxyClassPerResource,
|
||||
LabelAnnotationProxyClass: tt.proxyClassPerResource,
|
||||
}
|
||||
}
|
||||
mustCreate(t, fc, ing)
|
||||
|
@ -753,7 +753,7 @@ func proxyClassHandlerForSvc(cl client.Client, logger *zap.SugaredLogger) handle
|
||||
return func(ctx context.Context, o client.Object) []reconcile.Request {
|
||||
svcList := new(corev1.ServiceList)
|
||||
labels := map[string]string{
|
||||
LabelProxyClass: o.GetName(),
|
||||
LabelAnnotationProxyClass: o.GetName(),
|
||||
}
|
||||
if err := cl.List(ctx, svcList, client.MatchingLabels(labels)); err != nil {
|
||||
logger.Debugf("error listing Services for ProxyClass: %v", err)
|
||||
@ -774,7 +774,7 @@ func proxyClassHandlerForIngress(cl client.Client, logger *zap.SugaredLogger) ha
|
||||
return func(ctx context.Context, o client.Object) []reconcile.Request {
|
||||
ingList := new(networkingv1.IngressList)
|
||||
labels := map[string]string{
|
||||
LabelProxyClass: o.GetName(),
|
||||
LabelAnnotationProxyClass: o.GetName(),
|
||||
}
|
||||
if err := cl.List(ctx, ingList, client.MatchingLabels(labels)); err != nil {
|
||||
logger.Debugf("error listing Ingresses for ProxyClass: %v", err)
|
||||
@ -875,7 +875,7 @@ func serviceHandlerForIngress(cl client.Client, logger *zap.SugaredLogger) handl
|
||||
}
|
||||
|
||||
func serviceHandler(_ context.Context, o client.Object) []reconcile.Request {
|
||||
if _, ok := o.GetAnnotations()[AnnotationProxyGroup]; ok {
|
||||
if _, ok := o.GetAnnotations()[AnnotationProxyGroup.String()]; ok {
|
||||
// Do not reconcile Services for ProxyGroup.
|
||||
return nil
|
||||
}
|
||||
@ -1275,7 +1275,7 @@ func indexEgressServices(o client.Object) []string {
|
||||
if !isEgressSvcForProxyGroup(o) {
|
||||
return nil
|
||||
}
|
||||
return []string{o.GetAnnotations()[AnnotationProxyGroup]}
|
||||
return []string{o.GetAnnotations()[AnnotationProxyGroup.String()]}
|
||||
}
|
||||
|
||||
// indexPGIngresses adds a local index to a cached Tailscale Ingresses meant to be exposed on a ProxyGroup. The index is
|
||||
@ -1284,7 +1284,7 @@ func indexPGIngresses(o client.Object) []string {
|
||||
if !hasProxyGroupAnnotation(o) {
|
||||
return nil
|
||||
}
|
||||
return []string{o.GetAnnotations()[AnnotationProxyGroup]}
|
||||
return []string{o.GetAnnotations()[AnnotationProxyGroup.String()]}
|
||||
}
|
||||
|
||||
// serviceHandlerForIngressPG returns a handler for Service events that ensures that if the Service
|
||||
@ -1325,7 +1325,7 @@ func serviceHandlerForIngressPG(cl client.Client, logger *zap.SugaredLogger) han
|
||||
|
||||
func hasProxyGroupAnnotation(obj client.Object) bool {
|
||||
ing := obj.(*networkingv1.Ingress)
|
||||
return ing.Annotations[AnnotationProxyGroup] != ""
|
||||
return ing.Annotations[AnnotationProxyGroup.String()] != ""
|
||||
}
|
||||
|
||||
func id(ctx context.Context, lc *local.Client) (string, error) {
|
||||
|
@ -65,7 +65,7 @@ func TestLoadBalancerClass(t *testing.T) {
|
||||
// on it being set.
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetFQDN: "invalid.example.com",
|
||||
AnnotationTailnetTargetFQDN.String(): "invalid.example.com",
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -88,7 +88,7 @@ func TestLoadBalancerClass(t *testing.T) {
|
||||
Namespace: "default",
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetFQDN: "invalid.example.com",
|
||||
AnnotationTailnetTargetFQDN.String(): "invalid.example.com",
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -242,7 +242,7 @@ func TestTailnetTargetFQDNAnnotation(t *testing.T) {
|
||||
// on it being set.
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetFQDN: tailnetTargetFQDN,
|
||||
AnnotationTailnetTargetFQDN.String(): tailnetTargetFQDN,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -276,7 +276,7 @@ func TestTailnetTargetFQDNAnnotation(t *testing.T) {
|
||||
Finalizers: []string{"tailscale.com/finalizer"},
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetFQDN: tailnetTargetFQDN,
|
||||
AnnotationTailnetTargetFQDN.String(): tailnetTargetFQDN,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -298,7 +298,7 @@ func TestTailnetTargetFQDNAnnotation(t *testing.T) {
|
||||
tailnetTargetFQDN = "bar.baz.ts.net"
|
||||
mustUpdate(t, fc, "default", "test", func(s *corev1.Service) {
|
||||
s.ObjectMeta.Annotations = map[string]string{
|
||||
AnnotationTailnetTargetFQDN: tailnetTargetFQDN,
|
||||
AnnotationTailnetTargetFQDN.String(): tailnetTargetFQDN,
|
||||
}
|
||||
})
|
||||
|
||||
@ -354,7 +354,7 @@ func TestTailnetTargetIPAnnotation(t *testing.T) {
|
||||
// on it being set.
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetIP: tailnetTargetIP,
|
||||
AnnotationTailnetTargetIP.String(): tailnetTargetIP,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -388,7 +388,7 @@ func TestTailnetTargetIPAnnotation(t *testing.T) {
|
||||
Finalizers: []string{"tailscale.com/finalizer"},
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetIP: tailnetTargetIP,
|
||||
AnnotationTailnetTargetIP.String(): tailnetTargetIP,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -410,7 +410,7 @@ func TestTailnetTargetIPAnnotation(t *testing.T) {
|
||||
tailnetTargetIP = "100.77.77.77"
|
||||
mustUpdate(t, fc, "default", "test", func(s *corev1.Service) {
|
||||
s.ObjectMeta.Annotations = map[string]string{
|
||||
AnnotationTailnetTargetIP: tailnetTargetIP,
|
||||
AnnotationTailnetTargetIP.String(): tailnetTargetIP,
|
||||
}
|
||||
})
|
||||
|
||||
@ -462,7 +462,7 @@ func TestTailnetTargetIPAnnotation_IPCouldNotBeParsed(t *testing.T) {
|
||||
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetIP: tailnetTargetIP,
|
||||
AnnotationTailnetTargetIP.String(): tailnetTargetIP,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -482,7 +482,7 @@ func TestTailnetTargetIPAnnotation_IPCouldNotBeParsed(t *testing.T) {
|
||||
Namespace: "default",
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetIP: tailnetTargetIP,
|
||||
AnnotationTailnetTargetIP.String(): tailnetTargetIP,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -533,7 +533,7 @@ func TestTailnetTargetIPAnnotation_InvalidIP(t *testing.T) {
|
||||
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetIP: tailnetTargetIP,
|
||||
AnnotationTailnetTargetIP.String(): tailnetTargetIP,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -553,7 +553,7 @@ func TestTailnetTargetIPAnnotation_InvalidIP(t *testing.T) {
|
||||
Namespace: "default",
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationTailnetTargetIP: tailnetTargetIP,
|
||||
AnnotationTailnetTargetIP.String(): tailnetTargetIP,
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -1132,7 +1132,9 @@ func TestProxyClassForService(t *testing.T) {
|
||||
StatefulSet: &tsapi.StatefulSet{
|
||||
Labels: tsapi.Labels{"foo": "bar"},
|
||||
Annotations: map[string]string{"bar.io/foo": "some-val"},
|
||||
Pod: &tsapi.Pod{Annotations: map[string]string{"foo.io/bar": "some-val"}}}},
|
||||
Pod: &tsapi.Pod{Annotations: map[string]string{"foo.io/bar": "some-val"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
fc := fake.NewClientBuilder().
|
||||
WithScheme(tsapi.GlobalScheme).
|
||||
@ -1194,7 +1196,7 @@ func TestProxyClassForService(t *testing.T) {
|
||||
// pointing at the 'custom-metadata' ProxyClass. The ProxyClass is not
|
||||
// yet ready, so no changes are actually applied to the proxy resources.
|
||||
mustUpdate(t, fc, "default", "test", func(svc *corev1.Service) {
|
||||
mak.Set(&svc.Labels, LabelProxyClass, "custom-metadata")
|
||||
mak.Set(&svc.Labels, LabelAnnotationProxyClass, "custom-metadata")
|
||||
})
|
||||
expectReconciled(t, sr, "default", "test")
|
||||
expectEqual(t, fc, expectedSTS(t, fc, opts), removeHashAnnotation, removeResourceReqs)
|
||||
@ -1220,7 +1222,7 @@ func TestProxyClassForService(t *testing.T) {
|
||||
// configuration from the ProxyClass is removed from the cluster
|
||||
// resources.
|
||||
mustUpdate(t, fc, "default", "test", func(svc *corev1.Service) {
|
||||
delete(svc.Labels, LabelProxyClass)
|
||||
delete(svc.Labels, LabelAnnotationProxyClass)
|
||||
})
|
||||
opts.proxyClass = ""
|
||||
expectReconciled(t, sr, "default", "test")
|
||||
@ -1667,7 +1669,7 @@ func Test_externalNameService(t *testing.T) {
|
||||
// on it being set.
|
||||
UID: types.UID("1234-UID"),
|
||||
Annotations: map[string]string{
|
||||
AnnotationExpose: "true",
|
||||
AnnotationExpose.String(): "true",
|
||||
},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
@ -1711,14 +1713,15 @@ func Test_metricsResourceCreation(t *testing.T) {
|
||||
Status: metav1.ConditionTrue,
|
||||
Type: string(tsapi.ProxyClassReady),
|
||||
ObservedGeneration: 1,
|
||||
}}},
|
||||
}},
|
||||
},
|
||||
}
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "default",
|
||||
UID: types.UID("1234-UID"),
|
||||
Labels: map[string]string{LabelProxyClass: "metrics"},
|
||||
Labels: map[string]string{LabelAnnotationProxyClass: "metrics"},
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
ClusterIP: "10.20.30.40",
|
||||
|
@ -327,11 +327,11 @@ func (r *ProxyGroupReconciler) maybeProvision(ctx context.Context, pg *tsapi.Pro
|
||||
// TODO(irbekrm): remove this in 1.84.
|
||||
hash := cfgHash
|
||||
if capver >= 110 {
|
||||
hash = s.Spec.Template.GetAnnotations()[podAnnotationLastSetConfigFileHash]
|
||||
hash = PodAnnotationLastSetConfigFileHash.GetValue(s)
|
||||
}
|
||||
s.Spec = ss.Spec
|
||||
if hash != "" && pg.Spec.Type == tsapi.ProxyGroupTypeEgress {
|
||||
mak.Set(&s.Spec.Template.Annotations, podAnnotationLastSetConfigFileHash, hash)
|
||||
mak.Set(&s.Spec.Template.Annotations, PodAnnotationLastSetConfigFileHash.String(), hash)
|
||||
}
|
||||
|
||||
s.ObjectMeta.Labels = ss.ObjectMeta.Labels
|
||||
|
@ -617,7 +617,7 @@ func expectProxyGroupResources(t *testing.T, fc client.WithWatch, pg *tsapi.Prox
|
||||
}
|
||||
statefulSet.Annotations = defaultProxyClassAnnotations
|
||||
if cfgHash != "" {
|
||||
mak.Set(&statefulSet.Spec.Template.Annotations, podAnnotationLastSetConfigFileHash, cfgHash)
|
||||
mak.Set(&statefulSet.Spec.Template.Annotations, PodAnnotationLastSetConfigFileHash.String(), cfgHash)
|
||||
}
|
||||
|
||||
if shouldExist {
|
||||
|
@ -161,7 +161,7 @@ func Test_applyProxyClassToStatefulSet(t *testing.T) {
|
||||
LabelParentName: "foo",
|
||||
}
|
||||
annots := map[string]string{
|
||||
podAnnotationLastSetClusterIP: "1.2.3.4",
|
||||
PodAnnotationLastSetClusterIP.String(): "1.2.3.4",
|
||||
}
|
||||
env := []corev1.EnvVar{{Name: "TS_HOSTNAME", Value: "nginx"}}
|
||||
userspaceProxySS.Labels = labels
|
||||
@ -341,28 +341,28 @@ func Test_mergeStatefulSetLabelsOrAnnots(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "no custom annots specified and none present in current annots, return current annots",
|
||||
current: map[string]string{podAnnotationLastSetClusterIP: "1.2.3.4"},
|
||||
want: map[string]string{podAnnotationLastSetClusterIP: "1.2.3.4"},
|
||||
current: map[string]string{PodAnnotationLastSetClusterIP.String(): "1.2.3.4"},
|
||||
want: map[string]string{PodAnnotationLastSetClusterIP.String(): "1.2.3.4"},
|
||||
managed: tailscaleManagedAnnotations,
|
||||
},
|
||||
{
|
||||
name: "no custom annots specified, but some present in current annots, return tailscale managed annots only from the current annots",
|
||||
current: map[string]string{"foo": "bar", "something.io/foo": "bar", podAnnotationLastSetClusterIP: "1.2.3.4"},
|
||||
want: map[string]string{podAnnotationLastSetClusterIP: "1.2.3.4"},
|
||||
current: map[string]string{"foo": "bar", "something.io/foo": "bar", PodAnnotationLastSetClusterIP.String(): "1.2.3.4"},
|
||||
want: map[string]string{PodAnnotationLastSetClusterIP.String(): "1.2.3.4"},
|
||||
managed: tailscaleManagedAnnotations,
|
||||
},
|
||||
{
|
||||
name: "custom annots specified, current annots only contain tailscale managed annots, return a union of both",
|
||||
current: map[string]string{podAnnotationLastSetClusterIP: "1.2.3.4"},
|
||||
current: map[string]string{PodAnnotationLastSetClusterIP.String(): "1.2.3.4"},
|
||||
custom: map[string]string{"foo": "bar", "something.io/foo": "bar"},
|
||||
want: map[string]string{"foo": "bar", "something.io/foo": "bar", podAnnotationLastSetClusterIP: "1.2.3.4"},
|
||||
want: map[string]string{"foo": "bar", "something.io/foo": "bar", PodAnnotationLastSetClusterIP.String(): "1.2.3.4"},
|
||||
managed: tailscaleManagedAnnotations,
|
||||
},
|
||||
{
|
||||
name: "custom annots specified, current annots contain tailscale managed annots and custom annots, some of which are not present in the new custom annots, return a union of managed annots and the desired custom annots",
|
||||
current: map[string]string{"foo": "bar", "something.io/foo": "bar", podAnnotationLastSetClusterIP: "1.2.3.4"},
|
||||
current: map[string]string{"foo": "bar", "something.io/foo": "bar", PodAnnotationLastSetClusterIP.String(): "1.2.3.4"},
|
||||
custom: map[string]string{"something.io/foo": "bar"},
|
||||
want: map[string]string{"something.io/foo": "bar", podAnnotationLastSetClusterIP: "1.2.3.4"},
|
||||
want: map[string]string{"something.io/foo": "bar", PodAnnotationLastSetClusterIP.String(): "1.2.3.4"},
|
||||
managed: tailscaleManagedAnnotations,
|
||||
},
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ func childResourceLabels(name, ns, typ string) map[string]string {
|
||||
|
||||
func (a *ServiceReconciler) isTailscaleService(svc *corev1.Service) bool {
|
||||
targetIP := tailnetTargetAnnotation(svc)
|
||||
targetFQDN := svc.Annotations[AnnotationTailnetTargetFQDN]
|
||||
targetFQDN := AnnotationTailnetTargetFQDN.GetValue(svc)
|
||||
return a.shouldExpose(svc) || targetIP != "" || targetFQDN != ""
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ func (a *ServiceReconciler) Reconcile(ctx context.Context, req reconcile.Request
|
||||
return reconcile.Result{}, fmt.Errorf("failed to get svc: %w", err)
|
||||
}
|
||||
|
||||
if _, ok := svc.Annotations[AnnotationProxyGroup]; ok {
|
||||
if AnnotationProxyGroup.GetValue(svc) != "" {
|
||||
return reconcile.Result{}, nil // this reconciler should not look at Services for ProxyGroup
|
||||
}
|
||||
|
||||
@ -257,7 +257,7 @@ func (a *ServiceReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
|
||||
}
|
||||
crl := childResourceLabels(svc.Name, svc.Namespace, "svc")
|
||||
var tags []string
|
||||
if tstr, ok := svc.Annotations[AnnotationTags]; ok {
|
||||
if tstr := AnnotationTags.GetValue(svc); tstr != "" {
|
||||
tags = strings.Split(tstr, ",")
|
||||
}
|
||||
|
||||
@ -287,8 +287,9 @@ func (a *ServiceReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
|
||||
sts.TailnetTargetIP = ip
|
||||
a.managedEgressProxies.Add(svc.UID)
|
||||
gaugeEgressProxies.Set(int64(a.managedEgressProxies.Len()))
|
||||
} else if fqdn := svc.Annotations[AnnotationTailnetTargetFQDN]; fqdn != "" {
|
||||
fqdn := svc.Annotations[AnnotationTailnetTargetFQDN]
|
||||
} else if fqdn := AnnotationTailnetTargetFQDN.GetValue(svc); fqdn != "" {
|
||||
// NOTE (TOM): Do we need this? fqdn should already be set...
|
||||
fqdn := AnnotationTailnetTargetFQDN.GetValue(svc)
|
||||
if !strings.HasSuffix(fqdn, ".") {
|
||||
fqdn = fqdn + "."
|
||||
}
|
||||
@ -367,15 +368,15 @@ func (a *ServiceReconciler) maybeProvision(ctx context.Context, logger *zap.Suga
|
||||
|
||||
func validateService(svc *corev1.Service) []string {
|
||||
violations := make([]string, 0)
|
||||
if svc.Annotations[AnnotationTailnetTargetFQDN] != "" && svc.Annotations[AnnotationTailnetTargetIP] != "" {
|
||||
if AnnotationTailnetTargetFQDN.GetValue(svc) != "" && AnnotationTailnetTargetIP.GetValue(svc) != "" {
|
||||
violations = append(violations, fmt.Sprintf("only one of annotations %s and %s can be set", AnnotationTailnetTargetIP, AnnotationTailnetTargetFQDN))
|
||||
}
|
||||
if fqdn := svc.Annotations[AnnotationTailnetTargetFQDN]; fqdn != "" {
|
||||
if fqdn := AnnotationTailnetTargetFQDN.GetValue(svc); fqdn != "" {
|
||||
if !isMagicDNSName(fqdn) {
|
||||
violations = append(violations, fmt.Sprintf("invalid value of annotation %s: %q does not appear to be a valid MagicDNS name", AnnotationTailnetTargetFQDN, fqdn))
|
||||
}
|
||||
}
|
||||
if ipStr := svc.Annotations[AnnotationTailnetTargetIP]; ipStr != "" {
|
||||
if ipStr := AnnotationTailnetTargetIP.GetValue(svc); ipStr != "" {
|
||||
ip, err := netip.ParseAddr(ipStr)
|
||||
if err != nil {
|
||||
violations = append(violations, fmt.Sprintf("invalid value of annotation %s: %q could not be parsed as a valid IP Address, error: %s", AnnotationTailnetTargetIP, ipStr, err))
|
||||
@ -386,7 +387,7 @@ func validateService(svc *corev1.Service) []string {
|
||||
|
||||
svcName := nameForService(svc)
|
||||
if err := dnsname.ValidLabel(svcName); err != nil {
|
||||
if _, ok := svc.Annotations[AnnotationHostname]; ok {
|
||||
if AnnotationHostname.GetValue(svc) != "" {
|
||||
violations = append(violations, fmt.Sprintf("invalid Tailscale hostname specified %q: %s", svcName, err))
|
||||
} else {
|
||||
violations = append(violations, fmt.Sprintf("invalid Tailscale hostname %q, use %q annotation to override: %s", svcName, AnnotationHostname, err))
|
||||
@ -420,7 +421,7 @@ func isTailscaleLoadBalancerService(svc *corev1.Service, isDefaultLoadBalancer b
|
||||
// hasExposeAnnotation reports whether Service has the tailscale.com/expose
|
||||
// annotation set
|
||||
func hasExposeAnnotation(svc *corev1.Service) bool {
|
||||
return svc != nil && svc.Annotations[AnnotationExpose] == "true"
|
||||
return svc != nil && AnnotationExpose.GetValue(svc) == "true"
|
||||
}
|
||||
|
||||
// tailnetTargetAnnotation returns the value of tailscale.com/tailnet-ip
|
||||
@ -431,19 +432,24 @@ func tailnetTargetAnnotation(svc *corev1.Service) string {
|
||||
if svc == nil {
|
||||
return ""
|
||||
}
|
||||
if ip := svc.Annotations[AnnotationTailnetTargetIP]; ip != "" {
|
||||
if ip := AnnotationTailnetTargetIP.GetValue(svc); ip != "" {
|
||||
return ip
|
||||
}
|
||||
return svc.Annotations[annotationTailnetTargetIPOld]
|
||||
|
||||
return AnnotationTailnetTargetIPOld.GetValue(svc)
|
||||
}
|
||||
|
||||
// proxyClassForObject returns the proxy class for the given object. If the
|
||||
// object does not have a proxy class label, it returns the default proxy class
|
||||
func proxyClassForObject(o client.Object, proxyDefaultClass string) string {
|
||||
proxyClass, exists := o.GetLabels()[LabelProxyClass]
|
||||
proxyClass, exists := o.GetLabels()[LabelAnnotationProxyClass]
|
||||
if !exists {
|
||||
proxyClass = proxyDefaultClass
|
||||
proxyClass, exists = o.GetAnnotations()[LabelAnnotationProxyClass]
|
||||
if !exists {
|
||||
proxyClass = proxyDefaultClass
|
||||
}
|
||||
}
|
||||
|
||||
return proxyClass
|
||||
}
|
||||
|
||||
|
@ -826,7 +826,7 @@ func (c *fakeTSClient) Deleted() []string {
|
||||
// that we don't have to change the annotation in each test case after any
|
||||
// change to the configfile contents).
|
||||
func removeHashAnnotation(sts *appsv1.StatefulSet) {
|
||||
delete(sts.Spec.Template.Annotations, podAnnotationLastSetConfigFileHash)
|
||||
delete(sts.Spec.Template.Annotations, PodAnnotationLastSetConfigFileHash.String())
|
||||
if len(sts.Spec.Template.Annotations) == 0 {
|
||||
sts.Spec.Template.Annotations = nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user