Skip to content

Commit

Permalink
Merge pull request #1973 from FabianKramm/mappings-store
Browse files Browse the repository at this point in the history
feat: add name & labels mapping store
  • Loading branch information
FabianKramm authored Jul 31, 2024
2 parents e11e204 + 9bea0d4 commit 8cea580
Show file tree
Hide file tree
Showing 165 changed files with 4,804 additions and 12,144 deletions.
23 changes: 23 additions & 0 deletions cmd/vcluster/cmd/debug/debug.go
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
}
20 changes: 20 additions & 0 deletions cmd/vcluster/cmd/debug/etcd/etcd.go
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
}
61 changes: 61 additions & 0 deletions cmd/vcluster/cmd/debug/etcd/keys.go
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
}
118 changes: 118 additions & 0 deletions cmd/vcluster/cmd/debug/mappings/add.go
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
}
64 changes: 64 additions & 0 deletions cmd/vcluster/cmd/debug/mappings/clear.go
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
}
56 changes: 56 additions & 0 deletions cmd/vcluster/cmd/debug/mappings/delete.go
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
}
Loading

0 comments on commit 8cea580

Please sign in to comment.