Files
netbird/client/cmd/kubeconfig.go
coderabbitai[bot] 8c5648bb7b 📝 Add docstrings to feature/k8s-api-auth-proxy
Docstrings generation was requested by @shyamganesh-tide.

* https://github.com/netbirdio/netbird/pull/4975#issuecomment-3685447791

The following files were modified:

* `client/cmd/kubeconfig.go`
* `client/cmd/root.go`
* `management/internals/shared/grpc/conversion.go`
2025-12-23 07:06:53 +00:00

136 lines
4.9 KiB
Go

package cmd
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"
"github.com/netbirdio/netbird/client/proto"
)
var (
kubeconfigOutput string
kubeconfigCluster string
kubeconfigContext string
kubeconfigUser string
kubeconfigServer string
kubeconfigNamespace string
)
var kubeconfigCmd = &cobra.Command{
Use: "kubeconfig",
Short: "Generate kubeconfig for accessing Kubernetes via NetBird",
Long: `Generate a kubeconfig file that points to a Kubernetes cluster accessible via NetBird.
The generated kubeconfig uses a dummy bearer token for authentication when the
cluster's auth proxy is running in 'auth' mode. The actual authentication is
handled by the NetBird network - the auth proxy identifies users by their
NetBird peer IP and impersonates them in the Kubernetes API.
Example:
netbird kubeconfig --server https://k8s.example.netbird.cloud:6443 --cluster my-cluster
netbird kubeconfig --server https://10.100.0.1:6443 -o ~/.kube/netbird-config`,
RunE: kubeconfigFunc,
}
// init configures command-line flags for the kubeconfig command.
// It registers flags for output path, cluster, context, user, server, and namespace
// and marks the server flag as required.
func init() {
kubeconfigCmd.Flags().StringVarP(&kubeconfigOutput, "output", "o", "", "Output file path (default: stdout)")
kubeconfigCmd.Flags().StringVar(&kubeconfigCluster, "cluster", "netbird-cluster", "Cluster name in kubeconfig")
kubeconfigCmd.Flags().StringVar(&kubeconfigContext, "context", "netbird", "Context name in kubeconfig")
kubeconfigCmd.Flags().StringVar(&kubeconfigUser, "user", "netbird-user", "User name in kubeconfig")
kubeconfigCmd.Flags().StringVar(&kubeconfigServer, "server", "", "Kubernetes API server URL (required)")
kubeconfigCmd.Flags().StringVar(&kubeconfigNamespace, "namespace", "default", "Default namespace")
_ = kubeconfigCmd.MarkFlagRequired("server")
}
// kubeconfigFunc generates a kubeconfig file for accessing Kubernetes via the NetBird auth proxy.
// KUBECONFIG and running kubectl.
func kubeconfigFunc(cmd *cobra.Command, args []string) error {
ctx := context.Background()
// Get current NetBird status to verify connection
conn, err := DialClientGRPCServer(ctx, daemonAddr)
if err != nil {
cmd.PrintErrf("Warning: Could not connect to NetBird daemon: %v\n", err)
cmd.PrintErrln("Generating kubeconfig anyway, but make sure NetBird is running before using it.")
} else {
defer conn.Close()
resp, err := proto.NewDaemonServiceClient(conn).Status(ctx, &proto.StatusRequest{})
if err != nil {
cmd.PrintErrf("Warning: Could not get NetBird status: %v\n", status.Convert(err).Message())
} else if resp.Status != "Connected" {
cmd.PrintErrf("Warning: NetBird is not connected (status: %s)\n", resp.Status)
cmd.PrintErrln("Make sure to run 'netbird up' before using the generated kubeconfig.")
}
}
kubeconfig := generateKubeconfig(kubeconfigServer, kubeconfigCluster, kubeconfigContext, kubeconfigUser, kubeconfigNamespace)
if kubeconfigOutput == "" {
fmt.Println(kubeconfig)
return nil
}
// Expand ~ in path
if strings.HasPrefix(kubeconfigOutput, "~/") {
home, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("failed to get home directory: %w", err)
}
kubeconfigOutput = filepath.Join(home, kubeconfigOutput[2:])
}
// Create directory if needed
dir := filepath.Dir(kubeconfigOutput)
if err := os.MkdirAll(dir, 0700); err != nil {
return fmt.Errorf("failed to create directory %s: %w", dir, err)
}
if err := os.WriteFile(kubeconfigOutput, []byte(kubeconfig), 0600); err != nil {
return fmt.Errorf("failed to write kubeconfig: %w", err)
}
cmd.Printf("Kubeconfig written to %s\n", kubeconfigOutput)
cmd.PrintErrln("\nWarning: TLS verification is disabled (insecure-skip-tls-verify: true).")
cmd.PrintErrln("This is safe when traffic is encrypted via NetBird's WireGuard tunnel.")
cmd.Printf("\nTo use this kubeconfig:\n")
cmd.Printf(" export KUBECONFIG=%s\n", kubeconfigOutput)
cmd.Printf(" kubectl get nodes\n")
return nil
}
// generateKubeconfig creates a kubeconfig YAML string with the given parameters.
// generateKubeconfig generates a kubeconfig YAML for accessing the specified Kubernetes API server via NetBird.
// The returned config sets the current context to the provided context, includes the given cluster, user, and namespace,
// enables `insecure-skip-tls-verify: true`, and embeds the static token `netbird-auth-proxy`.
func generateKubeconfig(server, cluster, context, user, namespace string) string {
return fmt.Sprintf(`apiVersion: v1
kind: Config
clusters:
- cluster:
insecure-skip-tls-verify: true
server: %s
name: %s
contexts:
- context:
cluster: %s
namespace: %s
user: %s
name: %s
current-context: %s
users:
- name: %s
user:
token: netbird-auth-proxy
`, server, cluster, cluster, namespace, user, context, context, user)
}