@@ -2,6 +2,7 @@ package kubernetes
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "time"
78
@@ -17,11 +18,76 @@ import (
1718 "k8s.io/client-go/tools/clientcmd"
1819 "k8s.io/klog/v2"
1920
21+ "github.com/BurntSushi/toml"
2022 "github.com/containers/kubernetes-mcp-server/pkg/config"
2123)
2224
2325const ACMHubTargetParameterName = "cluster"
2426
27+ // ACMProviderConfig holds ACM-specific configuration that users can set in config.toml
28+ type ACMProviderConfig struct {
29+ // The host for the ACM cluster proxy addon
30+ // If using the acm-kubeconfig strategy, this should be the route for the proxy
31+ // If using the acm strategy, this should be the service for the proxy
32+ ClusterProxyAddonHost string `toml:"cluster_proxy_addon_host,omitempty"`
33+
34+ // Whether to skip verifying the TLS certs from the cluster proxy
35+ ClusterProxyAddonSkipTLSVerify bool `toml:"cluster_proxy_addon_skip_tls_verify"`
36+
37+ // The CA file for the cluster proxy addon
38+ ClusterProxyAddonCAFile string `toml:"cluster_proxy_addon_ca_file,omitempty"`
39+ }
40+
41+ func (c * ACMProviderConfig ) Validate () error {
42+ var err error = nil
43+
44+ if c .ClusterProxyAddonCAFile == "" {
45+ err = errors .Join (err , fmt .Errorf ("cluster_proxy_addon_host is required" ))
46+ }
47+
48+ if ! c .ClusterProxyAddonSkipTLSVerify && c .ClusterProxyAddonCAFile == "" {
49+ err = errors .Join (err , fmt .Errorf ("cluster_proxy_addon_ca_file is required if tls verification is not disabled" ))
50+ }
51+
52+ return err
53+ }
54+
55+ type ACMKubeConfigProviderConfig struct {
56+ ACMProviderConfig
57+
58+ // Name of the context in the kubeconfig file to look for acm access credentials in.
59+ // Should point to the "hub" cluster.
60+ ContextName string `toml:"context_name,omitempty"`
61+ }
62+
63+ func (c * ACMKubeConfigProviderConfig ) Validate () error {
64+ err := c .ACMProviderConfig .Validate ()
65+
66+ if c .ContextName == "" {
67+ err = errors .Join (err , fmt .Errorf ("context_name is required is acm-kubeconfig strategy is used" ))
68+ }
69+
70+ return err
71+ }
72+
73+ func parseAcmConfig (primitive toml.Primitive , md toml.MetaData ) (config.ProviderConfig , error ) {
74+ var cfg ACMProviderConfig
75+ if err := md .PrimitiveDecode (primitive , & cfg ); err != nil {
76+ return nil , err
77+ }
78+
79+ return & cfg , nil
80+ }
81+
82+ func parseAcmKubeConfigConfig (primitive toml.Primitive , md toml.MetaData ) (config.ProviderConfig , error ) {
83+ var cfg ACMKubeConfigProviderConfig
84+ if err := md .PrimitiveDecode (primitive , & cfg ); err != nil {
85+ return nil , err
86+ }
87+
88+ return & cfg , nil
89+ }
90+
2591type acmHubClusterProvider struct {
2692 hubManager * Manager // for the main "hub" cluster
2793 clusterManagers map [string ]* Manager
@@ -45,6 +111,9 @@ var _ Provider = &acmHubClusterProvider{}
45111func init () {
46112 RegisterProvider (config .ClusterProviderACM , newACMHubClusterProvider )
47113 RegisterProvider (config .ClusterProviderACMKubeConfig , newACMKubeConfigClusterProvider )
114+
115+ config .RegisterProviderConfig (config .ClusterProviderACM , parseAcmConfig )
116+ config .RegisterProviderConfig (config .ClusterProviderACMKubeConfig , parseAcmKubeConfigConfig )
48117}
49118
50119// IsACMHub checks if the current cluster is an ACM hub by looking for ACM CRDs
@@ -82,39 +151,38 @@ func newACMHubClusterProvider(m *Manager, cfg *config.StaticConfig) (Provider, e
82151 return nil , fmt .Errorf ("acm provider required in-cluster deployment" )
83152 }
84153
85- return newACMClusterProvider (m , cfg , false )
154+ providerCfg , ok := cfg .GetProviderConfig (config .ClusterProviderACM )
155+ if ! ok {
156+ return nil , fmt .Errorf ("missing required config for strategy '%s'" , config .ClusterProviderACM )
157+ }
158+
159+ return newACMClusterProvider (m , providerCfg .(* ACMProviderConfig ), false )
86160}
87161
88162func newACMKubeConfigClusterProvider (m * Manager , cfg * config.StaticConfig ) (Provider , error ) {
89- if cfg .AcmContextName == "" {
90- return nil , fmt .Errorf ("acm_context_name is required for ACM kubeconfig cluster provider" )
163+ providerCfg , ok := cfg .GetProviderConfig (config .ClusterProviderACMKubeConfig )
164+ if ! ok {
165+ return nil , fmt .Errorf ("missing required config for strategy '%s'" , config .ClusterProviderACMKubeConfig )
91166 }
92167
93- baseManager , err := m .newForContext (cfg .AcmContextName )
168+ acmKubeConfigProviderCfg := providerCfg .(* ACMKubeConfigProviderConfig )
169+ baseManager , err := m .newForContext (acmKubeConfigProviderCfg .ContextName )
94170 if err != nil {
95171 return nil , fmt .Errorf (
96172 "failed to create manager to hub cluster specified by acm_context_name %s: %w" ,
97- cfg . AcmContextName ,
173+ acmKubeConfigProviderCfg . ContextName ,
98174 err ,
99175 )
100176 }
101177
102- return newACMClusterProvider (baseManager , cfg , true )
178+ return newACMClusterProvider (baseManager , & acmKubeConfigProviderCfg . ACMProviderConfig , true )
103179}
104180
105- func newACMClusterProvider (m * Manager , cfg * config. StaticConfig , watchKubeConfig bool ) (Provider , error ) {
181+ func newACMClusterProvider (m * Manager , cfg * ACMProviderConfig , watchKubeConfig bool ) (Provider , error ) {
106182 if ! m .IsACMHub () {
107183 return nil , fmt .Errorf ("not deployed in an ACM hub cluster" )
108184 }
109185
110- if cfg .AcmClusterProxyAddonHost == "" {
111- return nil , fmt .Errorf ("cluster proxy addon host is required when using any acm cluster provider strategy" )
112- }
113-
114- if ! cfg .AcmClusterProxyAddonSkipTLSVerify && cfg .AcmClusterProxyAddonCaFile == "" {
115- return nil , fmt .Errorf ("cluster proxy addon ca file is required if tls verification is not disabled" )
116- }
117-
118186 // Create cancellable context for the watch goroutine
119187 watchCtx , watchCancel := context .WithCancel (context .Background ())
120188
@@ -124,9 +192,9 @@ func newACMClusterProvider(m *Manager, cfg *config.StaticConfig, watchKubeConfig
124192 watchKubeConfig : watchKubeConfig ,
125193 watchCtx : watchCtx ,
126194 watchCancel : watchCancel ,
127- clusterProxyHost : cfg .AcmClusterProxyAddonHost ,
128- clusterProxyCAFile : cfg .AcmClusterProxyAddonCaFile ,
129- skipTLSVerify : cfg .AcmClusterProxyAddonSkipTLSVerify ,
195+ clusterProxyHost : cfg .ClusterProxyAddonHost ,
196+ clusterProxyCAFile : cfg .ClusterProxyAddonCAFile ,
197+ skipTLSVerify : cfg .ClusterProxyAddonSkipTLSVerify ,
130198 }
131199
132200 ctx := context .Background ()
0 commit comments