Skip to content

Commit 05c6f0e

Browse files
authored
Fix: vCluster config parsing not forward compatible (#38)
1 parent 631a64a commit 05c6f0e

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

cmd/hostpaths/hostpaths.go

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import (
1212
podtranslate "github.com/loft-sh/vcluster/pkg/controllers/resources/pods/translate"
1313
"github.com/loft-sh/vcluster/pkg/util/clienthelper"
1414

15-
"github.com/loft-sh/vcluster/config"
1615
"github.com/loft-sh/vcluster/config/legacyconfig"
1716
"github.com/loft-sh/vcluster/pkg/util/blockingcacheclient"
1817
"github.com/loft-sh/vcluster/pkg/util/pluginhookclient"
1918
"github.com/loft-sh/vcluster/pkg/util/translate"
19+
"github.com/mitchellh/mapstructure"
2020
"github.com/pkg/errors"
2121
"github.com/spf13/cobra"
2222
corev1 "k8s.io/api/core/v1"
@@ -66,6 +66,18 @@ const (
6666
configFilename = "config.yaml"
6767
)
6868

69+
// The Config type from the vcluster module may change between versions.
70+
// By defining our own type, we avoid parsing issues with incompatible vCluster versions.
71+
type vclusterConfig struct {
72+
Sync struct {
73+
ToHost struct {
74+
Namespaces struct {
75+
Enabled bool `mapstructure:"enabled"`
76+
} `mapstructure:"namespaces"`
77+
} `mapstructure:"toHost"`
78+
} `mapstructure:"sync"`
79+
}
80+
6981
// map of physical pod names to the corresponding virtual pod
7082
type PhysicalPodMap map[string]*PodDetail
7183

@@ -233,7 +245,7 @@ func Start(ctx context.Context, options *VirtualClusterOptions, init bool) error
233245
return mapHostPaths(ctx, localManager, virtualClusterManager)
234246
}
235247

236-
func getVclusterConfigFromSecret(ctx context.Context, kubeClient kubernetes.Interface, vclusterName, vclusterNamespace string) (*config.Config, error) {
248+
func getVclusterConfigFromSecret(ctx context.Context, kubeClient kubernetes.Interface, vclusterName, vclusterNamespace string) (*vclusterConfig, error) {
237249
configSecret, err := kubeClient.CoreV1().Secrets(vclusterNamespace).Get(ctx, fmt.Sprintf(configSecretNameTemplate, vclusterName), metav1.GetOptions{})
238250
if err != nil {
239251
return nil, err
@@ -244,23 +256,31 @@ func getVclusterConfigFromSecret(ctx context.Context, kubeClient kubernetes.Inte
244256
return nil, fmt.Errorf("key '%s' not found in secret", configFilename)
245257
}
246258

247-
// create a new strict decoder
248-
rawConfig := &config.Config{}
249-
err = yaml.UnmarshalStrict(rawBytes, rawConfig)
259+
var rawConfig map[string]any
260+
err = yaml.Unmarshal(rawBytes, &rawConfig)
250261
if err != nil {
251262
klog.Errorf("unmarshal %s: %#+v", configFilename, errors.Unwrap(err))
252-
return nil, err
263+
return nil, fmt.Errorf("failed to parse vCluster config: %w", err)
264+
}
265+
266+
var vClusterConfig vclusterConfig
267+
err = mapstructure.Decode(rawConfig, &vClusterConfig)
268+
if err != nil {
269+
return nil, fmt.Errorf("failed to decode config: %w", err)
253270
}
254271

255-
return rawConfig, nil
272+
return &vClusterConfig, nil
256273
}
257274

258275
func findVclusterModeAndSetDefaultTranslation(ctx context.Context, kubeClient kubernetes.Interface, options *VirtualClusterOptions) error {
259276
vClusterConfig, err := getVclusterConfigFromSecret(ctx, kubeClient, options.Name, options.TargetNamespace)
260277
if err != nil && !kerrors.IsNotFound(err) {
261278
return err
262-
} else if vClusterConfig != nil && vClusterConfig.Sync.ToHost.Namespaces.Enabled {
263-
return fmt.Errorf("unsupported vCluster config. Hostpathmapper is not compatible with toHost namespace syncing (sync.toHost.namespaces)")
279+
}
280+
if vClusterConfig != nil {
281+
if vClusterConfig.Sync.ToHost.Namespaces.Enabled {
282+
return fmt.Errorf("unsupported vCluster config. Hostpathmapper is not compatible with toHost namespace syncing (sync.toHost.namespaces)")
283+
}
264284
}
265285

266286
translate.Default = translate.NewSingleNamespaceTranslator(options.TargetNamespace)

0 commit comments

Comments
 (0)