Skip to content

Commit d7decc7

Browse files
authored
adds function for creating a configmap from a registry server config (#2547)
* we want to convert the reg server config to configmap 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 d116c53 commit d7decc7

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

cmd/thv-operator/pkg/registryapi/config.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ package registryapi
33
import (
44
"fmt"
55

6+
"gopkg.in/yaml.v2"
7+
corev1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
610
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
11+
ctrlutil "github.com/stacklok/toolhive/cmd/thv-operator/pkg/controllerutil"
712
)
813

914
// ConfigManager provides methods to build registry server configuration from MCPRegistry resources
@@ -110,6 +115,28 @@ type TagFilterConfig struct {
110115
Exclude []string `yaml:"exclude,omitempty"`
111116
}
112117

118+
// ToConfigMapWithContentChecksum converts the Config to a ConfigMap with a content checksum annotation
119+
func (c *Config) ToConfigMapWithContentChecksum(mcpRegistry *mcpv1alpha1.MCPRegistry) (*corev1.ConfigMap, error) {
120+
yamlData, err := yaml.Marshal(c)
121+
if err != nil {
122+
return nil, fmt.Errorf("failed to marshal config to YAML: %w", err)
123+
}
124+
125+
configMap := &corev1.ConfigMap{
126+
ObjectMeta: metav1.ObjectMeta{
127+
Name: fmt.Sprintf("%s-configmap", c.RegistryName),
128+
Namespace: mcpRegistry.Namespace,
129+
Annotations: map[string]string{
130+
"toolhive.dev/content-checksum": ctrlutil.CalculateConfigHash(yamlData),
131+
},
132+
},
133+
Data: map[string]string{
134+
"config.yaml": string(yamlData),
135+
},
136+
}
137+
return configMap, nil
138+
}
139+
113140
func (*configManager) BuildConfig(mcpRegistry *mcpv1alpha1.MCPRegistry) (*Config, error) {
114141
config := Config{}
115142

cmd/thv-operator/pkg/registryapi/config_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,3 +740,81 @@ func TestBuildConfig_Filter(t *testing.T) {
740740
assert.Empty(t, config.Filter.Tags.Exclude)
741741
})
742742
}
743+
744+
// TestToConfigMapWithContentChecksum tests that ToConfigMapWithContentChecksum creates
745+
// a ConfigMap with the correct checksum annotation based on the YAML content.
746+
func TestToConfigMapWithContentChecksum(t *testing.T) {
747+
t.Parallel()
748+
749+
// Create a populated Config object
750+
config := &Config{
751+
RegistryName: "checksum-test-registry",
752+
Source: &SourceConfig{
753+
Format: "toolhive",
754+
Git: &GitConfig{
755+
Repository: "https://github.com/example/mcp-servers.git",
756+
Branch: "main",
757+
},
758+
},
759+
SyncPolicy: &SyncPolicyConfig{
760+
Interval: "15m",
761+
},
762+
Filter: &FilterConfig{
763+
Names: &NameFilterConfig{
764+
Include: []string{"mcp-*"},
765+
Exclude: []string{"*-dev"},
766+
},
767+
},
768+
}
769+
770+
mcpRegistry := &mcpv1alpha1.MCPRegistry{
771+
ObjectMeta: metav1.ObjectMeta{
772+
Name: "test-registry",
773+
Namespace: "test-namespace",
774+
},
775+
}
776+
777+
// Call ToConfigMapWithContentChecksum
778+
configMap, err := config.ToConfigMapWithContentChecksum(mcpRegistry)
779+
780+
// Verify no error occurred
781+
require.NoError(t, err)
782+
require.NotNil(t, configMap)
783+
784+
// Verify basic ConfigMap properties
785+
assert.Equal(t, "checksum-test-registry-configmap", configMap.Name)
786+
assert.Equal(t, "test-namespace", configMap.Namespace)
787+
788+
// Verify the checksum annotation exists
789+
require.NotNil(t, configMap.Annotations)
790+
checksum, exists := configMap.Annotations["toolhive.dev/content-checksum"]
791+
require.True(t, exists, "Expected checksum annotation to exist")
792+
require.NotEmpty(t, checksum, "Checksum should not be empty")
793+
794+
// Verify the checksum format (should be a hex string)
795+
// The actual checksum is calculated by ctrlutil.CalculateConfigHash
796+
assert.Regexp(t, "^[a-f0-9]+$", checksum, "Checksum should be a hex string")
797+
798+
// Verify the Data contains config.yaml
799+
require.Contains(t, configMap.Data, "config.yaml")
800+
yamlData := configMap.Data["config.yaml"]
801+
require.NotEmpty(t, yamlData)
802+
803+
// Verify YAML content includes expected fields
804+
assert.Contains(t, yamlData, "registryName: checksum-test-registry")
805+
assert.Contains(t, yamlData, "repository: https://github.com/example/mcp-servers.git")
806+
assert.Contains(t, yamlData, "interval: 15m")
807+
808+
// Test that the same config produces the same checksum
809+
configMap2, err := config.ToConfigMapWithContentChecksum(mcpRegistry)
810+
require.NoError(t, err)
811+
checksum2 := configMap2.Annotations["toolhive.dev/content-checksum"]
812+
assert.Equal(t, checksum, checksum2, "Same config should produce same checksum")
813+
814+
// Test that different config produces different checksum
815+
config.SyncPolicy.Interval = "30m"
816+
configMap3, err := config.ToConfigMapWithContentChecksum(mcpRegistry)
817+
require.NoError(t, err)
818+
checksum3 := configMap3.Annotations["toolhive.dev/content-checksum"]
819+
assert.NotEqual(t, checksum, checksum3, "Different config should produce different checksum")
820+
}

0 commit comments

Comments
 (0)