diff --git a/cmd/debug/debug.go b/cmd/debug/debug.go new file mode 100644 index 00000000..c524790b --- /dev/null +++ b/cmd/debug/debug.go @@ -0,0 +1,91 @@ +/* +Copyright © 2020-2021 The k3d Author(s) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +package debug + +import ( + "fmt" + + "github.com/rancher/k3d/v4/pkg/client" + "github.com/rancher/k3d/v4/pkg/runtimes" + "github.com/rancher/k3d/v4/pkg/types" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "gopkg.in/yaml.v2" +) + +// NewCmdDebug returns a new cobra command +func NewCmdDebug() *cobra.Command { + cmd := &cobra.Command{ + Use: "debug", + Hidden: true, + Short: "Debug k3d cluster(s)", + Long: `Debug k3d cluster(s)`, + Run: func(cmd *cobra.Command, args []string) { + if err := cmd.Help(); err != nil { + log.Errorln("Couldn't get help text") + log.Fatalln(err) + } + }, + } + + cmd.AddCommand(NewCmdDebugLoadbalancer()) + + return cmd +} + +func NewCmdDebugLoadbalancer() *cobra.Command { + cmd := &cobra.Command{ + Use: "loadbalancer", + Aliases: []string{"lb"}, + Short: "Debug the loadbalancer", + Long: `Debug the loadbalancer`, + Run: func(cmd *cobra.Command, args []string) { + if err := cmd.Help(); err != nil { + log.Errorln("Couldn't get help text") + log.Fatalln(err) + } + }, + } + + cmd.AddCommand(&cobra.Command{ + Use: "get-config", + Args: cobra.ExactArgs(1), // cluster name + Run: func(cmd *cobra.Command, args []string) { + c, err := client.ClusterGet(cmd.Context(), runtimes.SelectedRuntime, &types.Cluster{Name: args[0]}) + if err != nil { + log.Fatalln(err) + } + + lbconf, err := client.GetLoadbalancerConfig(cmd.Context(), runtimes.SelectedRuntime, c) + if err != nil { + log.Fatalln(err) + } + yamlized, err := yaml.Marshal(lbconf) + if err != nil { + log.Fatalln(err) + } + fmt.Println(string(yamlized)) + }, + }) + + return cmd +} diff --git a/cmd/root.go b/cmd/root.go index 418e4008..8eb9c9d5 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -34,6 +34,7 @@ import ( "github.com/rancher/k3d/v4/cmd/cluster" cfg "github.com/rancher/k3d/v4/cmd/config" + "github.com/rancher/k3d/v4/cmd/debug" "github.com/rancher/k3d/v4/cmd/image" "github.com/rancher/k3d/v4/cmd/kubeconfig" "github.com/rancher/k3d/v4/cmd/node" @@ -116,6 +117,7 @@ func init() { rootCmd.AddCommand(image.NewCmdImage()) rootCmd.AddCommand(cfg.NewCmdConfig()) rootCmd.AddCommand(registry.NewCmdRegistry()) + rootCmd.AddCommand(debug.NewCmdDebug()) rootCmd.AddCommand(&cobra.Command{ Use: "version", diff --git a/pkg/client/loadbalancer.go b/pkg/client/loadbalancer.go index f0fa74fc..489a4ef1 100644 --- a/pkg/client/loadbalancer.go +++ b/pkg/client/loadbalancer.go @@ -22,13 +22,17 @@ THE SOFTWARE. package client import ( + "bytes" "context" "fmt" + "io/ioutil" "strings" "github.com/rancher/k3d/v4/pkg/runtimes" + "github.com/rancher/k3d/v4/pkg/types" k3d "github.com/rancher/k3d/v4/pkg/types" log "github.com/sirupsen/logrus" + "sigs.k8s.io/yaml" ) // UpdateLoadbalancerConfig updates the loadbalancer config with an updated list of servers belonging to that cluster @@ -70,3 +74,38 @@ func UpdateLoadbalancerConfig(ctx context.Context, runtime runtimes.Runtime, clu return nil } + +func GetLoadbalancerConfig(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.Cluster) (*types.LoadbalancerConfig, error) { + + if cluster.ServerLoadBalancer == nil { + for _, node := range cluster.Nodes { + if node.Role == types.LoadBalancerRole { + var err error + cluster.ServerLoadBalancer, err = NodeGet(ctx, runtime, node) + if err != nil { + return nil, err + } + } + } + } + + reader, err := runtime.ReadFromNode(ctx, types.DefaultLoadbalancerConfigPath, cluster.ServerLoadBalancer) + if err != nil { + return &k3d.LoadbalancerConfig{}, err + } + defer reader.Close() + + file, err := ioutil.ReadAll(reader) + if err != nil { + return nil, err + } + + file = bytes.Trim(file[512:], "\x00") // trim control characters, etc. + + currentConfig := &types.LoadbalancerConfig{} + if err := yaml.Unmarshal(file, currentConfig); err != nil { + return nil, err + } + + return currentConfig, nil +} diff --git a/pkg/types/types.go b/pkg/types/types.go index 4df5e434..674cf576 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -427,3 +427,23 @@ type RegistryExternal struct { Host string `yaml:"host" json:"host"` Port string `yaml:"port" json:"port"` } + +/* + * Loadbalancer + */ + +/* LoadbalancerConfig defines the coarse file structure to configure the k3d-proxy + * Example: + * ports: + * 1234.tcp: + * - k3d-k3s-default-server-0 + * - k3d-k3s-default-server-1 + * 4321.udp: + * - k3d-k3s-default-agent-0 + * - k3d-k3s-default-agent-1 + */ +type LoadbalancerConfig struct { + Ports map[string][]string `yaml:"ports"` +} + +const DefaultLoadbalancerConfigPath = "/etc/confd/portmap.yaml"