Skip to content

Commit f2b6bc3

Browse files
authored
Refactors Accessor Logic for MCPServer Fields Into Specific Package (#1877)
* refactors accessor logic into specific package Signed-off-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> * lint Signed-off-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> --------- Signed-off-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com>
1 parent c36b870 commit f2b6bc3

File tree

2 files changed

+447
-0
lines changed

2 files changed

+447
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Package accessors provides accessor functions for the ToolHive operator
2+
package accessors
3+
4+
import (
5+
"maps"
6+
7+
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
8+
)
9+
10+
// MCPServerFieldAccessor provides accessor methods for handling labels and annotations
11+
type MCPServerFieldAccessor interface {
12+
// GetProxyDeploymentLabelsAndAnnotations returns labels and annotations for the deployment
13+
GetProxyDeploymentLabelsAndAnnotations(mcpServer *mcpv1alpha1.MCPServer) (labels, annotations map[string]string)
14+
15+
// GetProxyDeploymentTemplateLabelsAndAnnotations returns labels and annotations for the deployment pod template
16+
GetProxyDeploymentTemplateLabelsAndAnnotations(mcpServer *mcpv1alpha1.MCPServer) (labels, annotations map[string]string)
17+
}
18+
19+
// mcpServerFieldAccessor implements MCPServerFieldAccessor
20+
type mcpServerFieldAccessor struct{}
21+
22+
// NewMCPServerFieldAccessor creates a new MCPServerFieldAccessor instance
23+
func NewMCPServerFieldAccessor() MCPServerFieldAccessor {
24+
return &mcpServerFieldAccessor{}
25+
}
26+
27+
// GetProxyDeploymentLabelsAndAnnotations returns labels and annotations for the deployment
28+
func (*mcpServerFieldAccessor) GetProxyDeploymentLabelsAndAnnotations(
29+
mcpServer *mcpv1alpha1.MCPServer,
30+
) (map[string]string, map[string]string) {
31+
baseAnnotations := make(map[string]string)
32+
baseLabels := make(map[string]string)
33+
34+
if mcpServer.Spec.ResourceOverrides == nil ||
35+
mcpServer.Spec.ResourceOverrides.ProxyDeployment == nil {
36+
return baseLabels, baseAnnotations
37+
}
38+
39+
deploymentLabels := baseLabels
40+
deploymentAnnotations := baseAnnotations
41+
42+
if mcpServer.Spec.ResourceOverrides.ProxyDeployment.Labels != nil {
43+
deploymentLabels = mergeLabels(baseLabels, mcpServer.Spec.ResourceOverrides.ProxyDeployment.Labels)
44+
}
45+
if mcpServer.Spec.ResourceOverrides.ProxyDeployment.Annotations != nil {
46+
deploymentAnnotations = mergeAnnotations(baseAnnotations, mcpServer.Spec.ResourceOverrides.ProxyDeployment.Annotations)
47+
}
48+
49+
return deploymentLabels, deploymentAnnotations
50+
}
51+
52+
// GetProxyDeploymentTemplateLabelsAndAnnotations returns labels and annotations for the deployment pod template
53+
func (*mcpServerFieldAccessor) GetProxyDeploymentTemplateLabelsAndAnnotations(
54+
mcpServer *mcpv1alpha1.MCPServer,
55+
) (map[string]string, map[string]string) {
56+
baseAnnotations := make(map[string]string)
57+
baseLabels := make(map[string]string)
58+
59+
if mcpServer.Spec.ResourceOverrides == nil ||
60+
mcpServer.Spec.ResourceOverrides.ProxyDeployment == nil ||
61+
mcpServer.Spec.ResourceOverrides.ProxyDeployment.PodTemplateMetadataOverrides == nil {
62+
return baseLabels, baseAnnotations
63+
}
64+
65+
deploymentLabels := baseLabels
66+
deploymentAnnotations := baseAnnotations
67+
68+
if mcpServer.Spec.ResourceOverrides.ProxyDeployment.PodTemplateMetadataOverrides.Labels != nil {
69+
deploymentLabels = mergeLabels(baseLabels, mcpServer.Spec.ResourceOverrides.ProxyDeployment.PodTemplateMetadataOverrides.Labels)
70+
}
71+
if mcpServer.Spec.ResourceOverrides.ProxyDeployment.PodTemplateMetadataOverrides.Annotations != nil {
72+
overrides := mcpServer.Spec.ResourceOverrides.ProxyDeployment.PodTemplateMetadataOverrides.Annotations
73+
deploymentAnnotations = mergeAnnotations(baseAnnotations, overrides)
74+
}
75+
76+
return deploymentLabels, deploymentAnnotations
77+
}
78+
79+
// mergeLabels merges override labels with default labels, with default labels taking precedence
80+
func mergeLabels(defaultLabels, overrideLabels map[string]string) map[string]string {
81+
return mergeStringMaps(defaultLabels, overrideLabels)
82+
}
83+
84+
// mergeAnnotations merges override annotations with default annotations, with default annotations taking precedence
85+
func mergeAnnotations(defaultAnnotations, overrideAnnotations map[string]string) map[string]string {
86+
return mergeStringMaps(defaultAnnotations, overrideAnnotations)
87+
}
88+
89+
// mergeStringMaps merges override map with default map, with default map taking precedence
90+
// This ensures that operator-required metadata is preserved for proper functionality
91+
func mergeStringMaps(defaultMap, overrideMap map[string]string) map[string]string {
92+
if overrideMap == nil && defaultMap == nil {
93+
return make(map[string]string)
94+
}
95+
if overrideMap == nil {
96+
return maps.Clone(defaultMap)
97+
}
98+
result := maps.Clone(overrideMap)
99+
if defaultMap != nil {
100+
maps.Copy(result, defaultMap) // default map takes precedence
101+
}
102+
return result
103+
}

0 commit comments

Comments
 (0)