Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions src/go/pt-k8s-debug-collector/dumper/dumper.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,17 @@ type exportJob struct {
}

// New return new Dumper object
func New(location, namespace, kubeconfig, forwardport, resource string, skipPodSummary bool, concurrentExportWorkers int) (*Dumper, error) {
var config *rest.Config

func New(location, namespace, kubeconfig, clusterName, forwardport, resource string, skipPodSummary bool, concurrentExportWorkers int) (*Dumper, error) {
safeLog := NewSafeLogger()

log.AddHook(&ErrorArchiveHook{safeLogger: safeLog})

config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
_, resourceClusterName := parseResourceSpec(resource)
if clusterName == "" {
clusterName = resourceClusterName
}

config, err := buildRestConfig(kubeconfig, clusterName)
if err != nil {
return nil, fmt.Errorf("failed to build config from flags: %w", err)
}
Expand Down Expand Up @@ -181,6 +184,27 @@ func New(location, namespace, kubeconfig, forwardport, resource string, skipPodS
return d, err
}

func buildRestConfig(kubeconfig, clusterName string) (*rest.Config, error) {
if clusterName == "" {
return clientcmd.BuildConfigFromFlags("", kubeconfig)
}

loadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}
overrides := &clientcmd.ConfigOverrides{CurrentContext: clusterName}
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)

rawConfig, err := clientConfig.RawConfig()
if err != nil {
return nil, err
}

if _, ok := rawConfig.Contexts[clusterName]; !ok {
return nil, fmt.Errorf("context %q not found in kubeconfig", clusterName)
}

return clientConfig.ClientConfig()
}

// DumpCluster create dump of a cluster in Dumper.location
func (d *Dumper) DumpCluster() error {
var err error
Expand Down
92 changes: 92 additions & 0 deletions src/go/pt-k8s-debug-collector/dumper/dumper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package dumper

import (
"context"
"os"
"testing"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -186,6 +187,97 @@ func TestResourceTypeParsing(t *testing.T) {
}
}

func TestParseResourceSpec(t *testing.T) {
tests := []struct {
name string
resource string
wantResource string
wantClusterName string
}{
{
name: "plain resource",
resource: "auto",
wantResource: "auto",
wantClusterName: "",
},
{
name: "resource with cluster suffix",
resource: "auto/k3d-pgv2",
wantResource: "auto",
wantClusterName: "k3d-pgv2",
},
{
name: "resource is trimmed",
resource: " psmdb/k3d-psmdb ",
wantResource: "psmdb",
wantClusterName: "k3d-psmdb",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotResource, gotClusterName := parseResourceSpec(tt.resource)
if gotResource != tt.wantResource || gotClusterName != tt.wantClusterName {
t.Fatalf("parseResourceSpec(%q) = (%q, %q), want (%q, %q)", tt.resource, gotResource, gotClusterName, tt.wantResource, tt.wantClusterName)
}
})
}
}

func TestBuildRestConfigUsesSelectedContext(t *testing.T) {
tmpFile, err := os.CreateTemp("", "kubeconfig-*.yaml")
if err != nil {
t.Fatalf("create temp kubeconfig: %v", err)
}
defer os.Remove(tmpFile.Name())

kubeconfig := `
apiVersion: v1
kind: Config
clusters:
- cluster:
server: https://default.example
name: default-cluster
- cluster:
server: https://pgv2.example
name: pgv2-cluster
contexts:
- context:
cluster: default-cluster
user: default-user
name: default
- context:
cluster: pgv2-cluster
user: pgv2-user
name: k3d-pgv2
current-context: default
users:
- name: default-user
user:
token: default-token
- name: pgv2-user
user:
token: pgv2-token
`

if _, err := tmpFile.WriteString(kubeconfig); err != nil {
t.Fatalf("write temp kubeconfig: %v", err)
}

if err := tmpFile.Close(); err != nil {
t.Fatalf("close temp kubeconfig: %v", err)
}

cfg, err := buildRestConfig(tmpFile.Name(), "k3d-pgv2")
if err != nil {
t.Fatalf("buildRestConfig returned error: %v", err)
}

if cfg.Host != "https://pgv2.example" {
t.Fatalf("buildRestConfig selected host %q, want %q", cfg.Host, "https://pgv2.example")
}
}

// Tests for individual_files.go

func TestGetSummarySkipPodSummary(t *testing.T) {
Expand Down
14 changes: 14 additions & 0 deletions src/go/pt-k8s-debug-collector/dumper/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ func (d *Dumper) autoCustomResource() ([]string, error) {
return result, nil
}

func parseResourceSpec(resource string) (string, string) {
resource = strings.TrimSpace(resource)
if resource == "" {
return "", ""
}

resourceName, clusterName, found := strings.Cut(resource, "/")
if !found {
return resourceName, ""
}

return resourceName, clusterName
}

// TODO: rewrite to use map or switch
func resourceType(s string) string {
if s == "auto" {
Expand Down
6 changes: 1 addition & 5 deletions src/go/pt-k8s-debug-collector/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ func (c *cliOptions) AfterApply() error {
}
}

if len(c.ClusterName) > 0 {
c.Resource += "/" + c.ClusterName
}

ll, err := log.ParseLevel(c.LogLevel)
if err != nil {
return err
Expand Down Expand Up @@ -111,7 +107,7 @@ func main() {
log.Infof("loaded default kubeconfig: %s", path)
}

d, err := dumper.New("cluster-dump", opts.Namespace, opts.Kubeconfig, opts.ForwardPort, opts.Resource, opts.SkipPodSummary, opts.ConcurrentExportWorkers)
d, err := dumper.New("cluster-dump", opts.Namespace, opts.Kubeconfig, opts.ClusterName, opts.ForwardPort, opts.Resource, opts.SkipPodSummary, opts.ConcurrentExportWorkers)
if err != nil {
log.Error(err)
os.Exit(1)
Expand Down
Loading