@@ -27,7 +27,12 @@ var serveCmd = &cobra.Command{
27
27
Use : "serve" ,
28
28
Short : "Start the registry API server" ,
29
29
Long : `Start the registry API server to serve MCP registry data.
30
- The server reads registry data from ConfigMaps and provides REST endpoints for clients.` ,
30
+ The server can read registry data from either:
31
+ - ConfigMaps using --from-configmap flag (requires Kubernetes API access)
32
+ - Local files using --from-file flag (for mounted ConfigMaps)
33
+
34
+ Both options require --registry-name to specify the registry identifier.
35
+ One of --from-configmap or --from-file must be specified.` ,
31
36
RunE : runServe ,
32
37
}
33
38
@@ -41,15 +46,25 @@ const (
41
46
42
47
func init () {
43
48
serveCmd .Flags ().String ("address" , ":8080" , "Address to listen on" )
44
- serveCmd .Flags ().String ("configmap" , "" , "ConfigMap name containing registry data" )
49
+ serveCmd .Flags ().String ("from-configmap" , "" , "ConfigMap name containing registry data (mutually exclusive with --from-file)" )
50
+ serveCmd .Flags ().String ("from-file" , "" , "File path to registry.json (mutually exclusive with --from-configmap)" )
51
+ serveCmd .Flags ().String ("registry-name" , "" , "Registry name identifier (required)" )
45
52
46
53
err := viper .BindPFlag ("address" , serveCmd .Flags ().Lookup ("address" ))
47
54
if err != nil {
48
55
logger .Fatalf ("Failed to bind address flag: %v" , err )
49
56
}
50
- err = viper .BindPFlag ("configmap" , serveCmd .Flags ().Lookup ("configmap" ))
57
+ err = viper .BindPFlag ("from-configmap" , serveCmd .Flags ().Lookup ("from-configmap" ))
58
+ if err != nil {
59
+ logger .Fatalf ("Failed to bind from-configmap flag: %v" , err )
60
+ }
61
+ err = viper .BindPFlag ("from-file" , serveCmd .Flags ().Lookup ("from-file" ))
62
+ if err != nil {
63
+ logger .Fatalf ("Failed to bind from-file flag: %v" , err )
64
+ }
65
+ err = viper .BindPFlag ("registry-name" , serveCmd .Flags ().Lookup ("registry-name" ))
51
66
if err != nil {
52
- logger .Fatalf ("Failed to bind configmap flag: %v" , err )
67
+ logger .Fatalf ("Failed to bind registry-name flag: %v" , err )
53
68
}
54
69
}
55
70
@@ -68,48 +83,95 @@ func getKubernetesConfig() (*rest.Config, error) {
68
83
return kubeConfig .ClientConfig ()
69
84
}
70
85
71
- func runServe (_ * cobra.Command , _ []string ) error {
72
- ctx := context .Background ()
86
+ // buildProviderConfig creates provider configuration based on command-line flags
87
+ func buildProviderConfig () (* service.RegistryProviderConfig , error ) {
88
+ configMapName := viper .GetString ("from-configmap" )
89
+ filePath := viper .GetString ("from-file" )
90
+ registryName := viper .GetString ("registry-name" )
73
91
74
- // Get configuration
75
- address := viper .GetString ("address" )
76
- configMapName := viper .GetString ("configmap" )
92
+ // Validate mutual exclusivity
93
+ if configMapName != "" && filePath != "" {
94
+ return nil , fmt .Errorf ("--from-configmap and --from-file flags are mutually exclusive" )
95
+ }
96
+
97
+ // Require one of the flags
98
+ if configMapName == "" && filePath == "" {
99
+ return nil , fmt .Errorf ("either --from-configmap or --from-file flag is required" )
100
+ }
77
101
78
- if configMapName == "" {
79
- return fmt .Errorf ("configmap flag is required" )
102
+ // Require registry name
103
+ if registryName == "" {
104
+ return nil , fmt .Errorf ("--registry-name flag is required" )
80
105
}
81
106
82
- namespace := thvk8scli .GetCurrentNamespace ()
107
+ if configMapName != "" {
108
+ config , err := getKubernetesConfig ()
109
+ if err != nil {
110
+ return nil , fmt .Errorf ("failed to create kubernetes config: %w" , err )
111
+ }
112
+
113
+ clientset , err := kubernetes .NewForConfig (config )
114
+ if err != nil {
115
+ return nil , fmt .Errorf ("failed to create kubernetes client: %w" , err )
116
+ }
117
+
118
+ return & service.RegistryProviderConfig {
119
+ Type : service .RegistryProviderTypeConfigMap ,
120
+ ConfigMap : & service.ConfigMapProviderConfig {
121
+ Name : configMapName ,
122
+ Namespace : thvk8scli .GetCurrentNamespace (),
123
+ Clientset : clientset ,
124
+ RegistryName : registryName ,
125
+ },
126
+ }, nil
127
+ }
128
+
129
+ return & service.RegistryProviderConfig {
130
+ Type : service .RegistryProviderTypeFile ,
131
+ File : & service.FileProviderConfig {
132
+ FilePath : filePath ,
133
+ RegistryName : registryName ,
134
+ },
135
+ }, nil
136
+ }
137
+
138
+ func runServe (_ * cobra.Command , _ []string ) error {
139
+ ctx := context .Background ()
140
+ address := viper .GetString ("address" )
83
141
84
142
logger .Infof ("Starting registry API server on %s" , address )
85
- logger .Infof ("ConfigMap: %s, Namespace: %s" , configMapName , namespace )
86
143
87
- // Create Kubernetes client and providers
88
- var registryProvider service.RegistryDataProvider
89
- var deploymentProvider service.DeploymentProvider
144
+ providerConfig , err := buildProviderConfig ()
145
+ if err != nil {
146
+ return fmt .Errorf ("failed to build provider configuration: %w" , err )
147
+ }
90
148
91
- // Get Kubernetes config
92
- config , err := getKubernetesConfig ()
149
+ if err := providerConfig .Validate (); err != nil {
150
+ return fmt .Errorf ("invalid provider configuration: %w" , err )
151
+ }
152
+
153
+ factory := service .NewRegistryProviderFactory ()
154
+ registryProvider , err := factory .CreateProvider (providerConfig )
93
155
if err != nil {
94
- return fmt .Errorf ("failed to create kubernetes config : %w" , err )
156
+ return fmt .Errorf ("failed to create registry provider : %w" , err )
95
157
}
96
158
97
- // Create Kubernetes client
98
- clientset , err := kubernetes .NewForConfig (config )
159
+ logger .Infof ("Created registry data provider: %s" , registryProvider .GetSource ())
160
+
161
+ var deploymentProvider service.DeploymentProvider
162
+ config , err := getKubernetesConfig ()
99
163
if err != nil {
100
- return fmt .Errorf ("failed to create kubernetes client : %w" , err )
164
+ return fmt .Errorf ("failed to create kubernetes config for deployment provider : %w" , err )
101
165
}
102
166
103
- // Create the Kubernetes-based registry data provider
104
- registryProvider = service .NewK8sRegistryDataProvider (clientset , configMapName , namespace )
105
- logger .Infof ("Created Kubernetes registry data provider for ConfigMap %s/%s" , namespace , configMapName )
167
+ // Use registry name from provider
168
+ registryName := registryProvider .GetRegistryName ()
106
169
107
- // Create the Kubernetes-based deployment provider
108
- deploymentProvider , err = service .NewK8sDeploymentProvider (config , configMapName )
170
+ deploymentProvider , err = service .NewK8sDeploymentProvider (config , registryName )
109
171
if err != nil {
110
172
return fmt .Errorf ("failed to create kubernetes deployment provider: %w" , err )
111
173
}
112
- logger .Infof ("Created Kubernetes deployment provider for registry: %s" , configMapName )
174
+ logger .Infof ("Created Kubernetes deployment provider for registry: %s" , registryName )
113
175
114
176
// Create the registry service
115
177
svc , err := service .NewService (ctx , registryProvider , deploymentProvider )
0 commit comments