-
Notifications
You must be signed in to change notification settings - Fork 432
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1973 from FabianKramm/mappings-store
feat: add name & labels mapping store
- Loading branch information
Showing
165 changed files
with
4,804 additions
and
12,144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package debug | ||
|
||
import ( | ||
"github.com/loft-sh/vcluster/cmd/vcluster/cmd/debug/etcd" | ||
"github.com/loft-sh/vcluster/cmd/vcluster/cmd/debug/mappings" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func NewDebugCmd() *cobra.Command { | ||
debugCmd := &cobra.Command{ | ||
Use: "debug", | ||
Short: "vCluster debug subcommand", | ||
Long: `####################################################### | ||
################### vcluster debug #################### | ||
####################################################### | ||
`, | ||
Args: cobra.NoArgs, | ||
} | ||
|
||
debugCmd.AddCommand(mappings.NewMappingsCmd()) | ||
debugCmd.AddCommand(etcd.NewEtcdCmd()) | ||
return debugCmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package etcd | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func NewEtcdCmd() *cobra.Command { | ||
debugCmd := &cobra.Command{ | ||
Use: "etcd", | ||
Short: "vCluster etcd subcommand", | ||
Long: `####################################################### | ||
############### vcluster debug etcd ############### | ||
####################################################### | ||
`, | ||
Args: cobra.NoArgs, | ||
} | ||
|
||
debugCmd.AddCommand(NewKeysCommand()) | ||
return debugCmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package etcd | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/loft-sh/vcluster/pkg/config" | ||
"github.com/loft-sh/vcluster/pkg/constants" | ||
"github.com/loft-sh/vcluster/pkg/etcd" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
type KeysOptions struct { | ||
Config string | ||
|
||
Prefix string | ||
} | ||
|
||
func NewKeysCommand() *cobra.Command { | ||
options := &KeysOptions{} | ||
cmd := &cobra.Command{ | ||
Use: "keys", | ||
Short: "Dump the vCluster etcd stored keys", | ||
Args: cobra.NoArgs, | ||
RunE: func(cobraCommand *cobra.Command, _ []string) (err error) { | ||
return ExecuteKeys(cobraCommand.Context(), options) | ||
}, | ||
} | ||
|
||
cmd.Flags().StringVar(&options.Config, "config", constants.DefaultVClusterConfigLocation, "The path where to find the vCluster config to load") | ||
cmd.Flags().StringVar(&options.Prefix, "prefix", "/", "The prefix to use for listing the keys") | ||
return cmd | ||
} | ||
|
||
func ExecuteKeys(ctx context.Context, options *KeysOptions) error { | ||
// parse vCluster config | ||
vConfig, err := config.ParseConfig(options.Config, os.Getenv("VCLUSTER_NAME"), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// create new etcd client | ||
etcdClient, err := etcd.NewFromConfig(ctx, vConfig) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// create new etcd backend & list mappings | ||
keyValues, err := etcdClient.List(ctx, options.Prefix, 0) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// print mappings | ||
for _, keyValue := range keyValues { | ||
fmt.Println(string(keyValue.Key)) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package mappings | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"github.com/loft-sh/vcluster/pkg/config" | ||
"github.com/loft-sh/vcluster/pkg/constants" | ||
"github.com/loft-sh/vcluster/pkg/etcd" | ||
"github.com/loft-sh/vcluster/pkg/mappings/store" | ||
"github.com/loft-sh/vcluster/pkg/syncer/synccontext" | ||
"github.com/spf13/cobra" | ||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/klog/v2" | ||
) | ||
|
||
type AddOptions struct { | ||
Config string | ||
|
||
APIVersion string | ||
Kind string | ||
|
||
Host string | ||
Virtual string | ||
} | ||
|
||
func NewAddCommand() *cobra.Command { | ||
options := &AddOptions{} | ||
cmd := &cobra.Command{ | ||
Use: "add", | ||
Short: "Adds a custom mapping to the vCluster stored mappings", | ||
RunE: func(cobraCommand *cobra.Command, _ []string) (err error) { | ||
return ExecuteSave(cobraCommand.Context(), options) | ||
}, | ||
} | ||
|
||
cmd.Flags().StringVar(&options.Config, "config", constants.DefaultVClusterConfigLocation, "The path where to find the vCluster config to load") | ||
cmd.Flags().StringVar(&options.Kind, "kind", "", "The Kind of the object") | ||
cmd.Flags().StringVar(&options.APIVersion, "api-version", "", "The APIVersion of the object") | ||
cmd.Flags().StringVar(&options.Host, "host", "", "The host object in the form of namespace/name") | ||
cmd.Flags().StringVar(&options.Virtual, "virtual", "", "The virtual object in the form of namespace/name") | ||
|
||
return cmd | ||
} | ||
func ExecuteSave(ctx context.Context, options *AddOptions) error { | ||
nameMapping, etcdBackend, err := parseMappingAndClient(ctx, options.Config, options.Kind, options.APIVersion, options.Virtual, options.Host) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = etcdBackend.Save(ctx, &store.Mapping{ | ||
NameMapping: nameMapping, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("error saving %s: %w", nameMapping.String(), err) | ||
} | ||
|
||
klog.FromContext(ctx).Info("Successfully added name mapping to store", "mapping", nameMapping.String()) | ||
return nil | ||
} | ||
|
||
func parseMappingAndClient(ctx context.Context, configPath, kind, apiVersion, virtual, host string) (synccontext.NameMapping, store.Backend, error) { | ||
if kind == "" || apiVersion == "" || virtual == "" || host == "" { | ||
return synccontext.NameMapping{}, nil, fmt.Errorf("make sure to specify --kind, --api-version, --host and --virtual") | ||
} | ||
|
||
// parse group version | ||
groupVersion, err := schema.ParseGroupVersion(apiVersion) | ||
if err != nil { | ||
return synccontext.NameMapping{}, nil, fmt.Errorf("parse group version: %w", err) | ||
} | ||
|
||
// parse host | ||
hostName := types.NamespacedName{Name: host} | ||
if strings.Contains(host, "/") { | ||
namespaceName := strings.SplitN(host, "/", 2) | ||
hostName.Namespace = namespaceName[0] | ||
hostName.Name = namespaceName[1] | ||
} | ||
|
||
// parse virtual | ||
virtualName := types.NamespacedName{Name: virtual} | ||
if strings.Contains(virtual, "/") { | ||
namespaceName := strings.SplitN(virtual, "/", 2) | ||
virtualName.Namespace = namespaceName[0] | ||
virtualName.Name = namespaceName[1] | ||
} | ||
|
||
// build name mapping | ||
nameMapping := synccontext.NameMapping{ | ||
GroupVersionKind: schema.GroupVersionKind{ | ||
Group: groupVersion.Group, | ||
Version: groupVersion.Version, | ||
Kind: kind, | ||
}, | ||
VirtualName: virtualName, | ||
HostName: hostName, | ||
} | ||
|
||
// parse vCluster config | ||
vConfig, err := config.ParseConfig(configPath, os.Getenv("VCLUSTER_NAME"), nil) | ||
if err != nil { | ||
return synccontext.NameMapping{}, nil, err | ||
} | ||
|
||
// create new etcd client | ||
etcdClient, err := etcd.NewFromConfig(ctx, vConfig) | ||
if err != nil { | ||
return synccontext.NameMapping{}, nil, err | ||
} | ||
|
||
// create new etcd backend & list mappings | ||
etcdBackend := store.NewEtcdBackend(etcdClient) | ||
return nameMapping, etcdBackend, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package mappings | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/loft-sh/vcluster/pkg/config" | ||
"github.com/loft-sh/vcluster/pkg/constants" | ||
"github.com/loft-sh/vcluster/pkg/etcd" | ||
"github.com/loft-sh/vcluster/pkg/mappings/store" | ||
"github.com/spf13/cobra" | ||
"k8s.io/klog/v2" | ||
) | ||
|
||
type ClearOptions struct { | ||
Config string | ||
} | ||
|
||
func NewClearCommand() *cobra.Command { | ||
options := &ClearOptions{} | ||
cmd := &cobra.Command{ | ||
Use: "clear", | ||
Short: "Empty the vCluster stored mappings", | ||
Args: cobra.NoArgs, | ||
RunE: func(cobraCommand *cobra.Command, _ []string) (err error) { | ||
return ExecuteClear(cobraCommand.Context(), options) | ||
}, | ||
} | ||
|
||
cmd.Flags().StringVar(&options.Config, "config", constants.DefaultVClusterConfigLocation, "The path where to find the vCluster config to load") | ||
return cmd | ||
} | ||
func ExecuteClear(ctx context.Context, options *ClearOptions) error { | ||
// parse vCluster config | ||
vConfig, err := config.ParseConfig(options.Config, os.Getenv("VCLUSTER_NAME"), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// create new etcd client | ||
etcdClient, err := etcd.NewFromConfig(ctx, vConfig) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// create new etcd backend & list mappings | ||
etcdBackend := store.NewEtcdBackend(etcdClient) | ||
mappings, err := etcdBackend.List(ctx) | ||
if err != nil { | ||
return fmt.Errorf("list mappings: %w", err) | ||
} | ||
|
||
// print mappings | ||
for _, mapping := range mappings { | ||
klog.FromContext(ctx).Info("Delete mapping", "mapping", mapping.String()) | ||
err = etcdBackend.Delete(ctx, mapping) | ||
if err != nil { | ||
return fmt.Errorf("delete mapping %s: %w", mapping.String(), err) | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package mappings | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/loft-sh/vcluster/pkg/constants" | ||
"github.com/loft-sh/vcluster/pkg/mappings/store" | ||
"github.com/spf13/cobra" | ||
"k8s.io/klog/v2" | ||
) | ||
|
||
type DeleteOptions struct { | ||
Config string | ||
|
||
APIVersion string | ||
Kind string | ||
|
||
Host string | ||
Virtual string | ||
} | ||
|
||
func NewDeleteCommand() *cobra.Command { | ||
options := &DeleteOptions{} | ||
cmd := &cobra.Command{ | ||
Use: "delete", | ||
Short: "Deletes a custom mapping to the vCluster stored mappings", | ||
RunE: func(cobraCommand *cobra.Command, _ []string) (err error) { | ||
return ExecuteDelete(cobraCommand.Context(), options) | ||
}, | ||
} | ||
|
||
cmd.Flags().StringVar(&options.Config, "config", constants.DefaultVClusterConfigLocation, "The path where to find the vCluster config to load") | ||
cmd.Flags().StringVar(&options.Kind, "kind", "", "The Kind of the object") | ||
cmd.Flags().StringVar(&options.APIVersion, "api-version", "", "The APIVersion of the object") | ||
cmd.Flags().StringVar(&options.Host, "host", "", "The host object in the form of namespace/name") | ||
cmd.Flags().StringVar(&options.Virtual, "virtual", "", "The virtual object in the form of namespace/name") | ||
|
||
return cmd | ||
} | ||
func ExecuteDelete(ctx context.Context, options *DeleteOptions) error { | ||
nameMapping, etcdBackend, err := parseMappingAndClient(ctx, options.Config, options.Kind, options.APIVersion, options.Virtual, options.Host) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = etcdBackend.Delete(ctx, &store.Mapping{ | ||
NameMapping: nameMapping, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("error saving %s: %w", nameMapping.String(), err) | ||
} | ||
|
||
klog.FromContext(ctx).Info("Successfully deleted name mapping from store", "mapping", nameMapping.String()) | ||
return nil | ||
} |
Oops, something went wrong.