Bläddra i källkod

Target the kubernetes cluster referenced in the docker "kube" context

Signed-off-by: aiordache <[email protected]>
aiordache 4 år sedan
förälder
incheckning
0807ec0067
6 ändrade filer med 101 tillägg och 91 borttagningar
  1. 1 0
      go.mod
  2. 1 12
      kube/backend.go
  3. 25 25
      kube/charts/charts.go
  4. 22 45
      kube/charts/helm/helm.go
  5. 51 5
      kube/charts/kubernetes/context.go
  6. 1 4
      kube/compose.go

+ 1 - 0
go.mod

@@ -64,6 +64,7 @@ require (
 	helm.sh/helm/v3 v3.5.0
 	k8s.io/api v0.20.1
 	k8s.io/apimachinery v0.20.1
+	k8s.io/cli-runtime v0.20.1
 	k8s.io/client-go v0.20.1
 	sigs.k8s.io/kustomize/kyaml v0.10.5
 )

+ 1 - 12
kube/backend.go

@@ -25,7 +25,6 @@ import (
 	"github.com/docker/compose-cli/api/cloud"
 	"github.com/docker/compose-cli/api/compose"
 	"github.com/docker/compose-cli/api/containers"
-	apicontext "github.com/docker/compose-cli/api/context"
 	"github.com/docker/compose-cli/api/context/store"
 	"github.com/docker/compose-cli/api/resources"
 	"github.com/docker/compose-cli/api/secrets"
@@ -35,7 +34,6 @@ import (
 const backendType = store.KubeContextType
 
 type kubeAPIService struct {
-	ctx            store.KubeContext
 	composeService compose.Service
 }
 
@@ -44,20 +42,11 @@ func init() {
 }
 
 func service(ctx context.Context) (backend.Service, error) {
-	contextStore := store.ContextStore(ctx)
-	currentContext := apicontext.CurrentContext(ctx)
-	var kubeContext store.KubeContext
-
-	if err := contextStore.GetEndpoint(currentContext, &kubeContext); err != nil {
-		return nil, err
-	}
-
-	s, err := NewComposeService(kubeContext)
+	s, err := NewComposeService(ctx)
 	if err != nil {
 		return nil, err
 	}
 	return &kubeAPIService{
-		ctx:            kubeContext,
 		composeService: s,
 	}, nil
 }

+ 25 - 25
kube/charts/charts.go

@@ -19,31 +19,46 @@
 package charts
 
 import (
-	"os"
+	"context"
 	"path/filepath"
 	"strings"
 
 	"github.com/compose-spec/compose-go/types"
 	"github.com/docker/compose-cli/api/compose"
+	apicontext "github.com/docker/compose-cli/api/context"
 	"github.com/docker/compose-cli/api/context/store"
 	"github.com/docker/compose-cli/kube/charts/helm"
 	"github.com/docker/compose-cli/kube/charts/kubernetes"
 	chart "helm.sh/helm/v3/pkg/chart"
 	util "helm.sh/helm/v3/pkg/chartutil"
-	helmenv "helm.sh/helm/v3/pkg/cli"
 )
 
 //SDK chart SDK
 type SDK struct {
-	h           *helm.Actions
-	environment map[string]string
+	action *helm.Actions
 }
 
 // NewSDK new chart SDK
-func NewSDK(ctx store.KubeContext) (SDK, error) {
+func NewSDK(ctx context.Context) (SDK, error) {
+	contextStore := store.ContextStore(ctx)
+	currentContext := apicontext.CurrentContext(ctx)
+	var kubeContext store.KubeContext
+
+	if err := contextStore.GetEndpoint(currentContext, &kubeContext); err != nil {
+		return SDK{}, err
+	}
+
+	config, err := kubernetes.LoadConfig(kubeContext)
+	if err != nil {
+		return SDK{}, err
+	}
+
+	actions, err := helm.NewHelmActions(ctx, config)
+	if err != nil {
+		return SDK{}, err
+	}
 	return SDK{
-		environment: environment(),
-		h:           helm.NewHelmActions(nil),
+		action: actions,
 	}, nil
 }
 
@@ -53,22 +68,17 @@ func (s SDK) Install(project *types.Project) error {
 	if err != nil {
 		return err
 	}
-	return s.h.InstallChart(project.Name, chart)
+	return s.action.InstallChart(project.Name, chart)
 }
 
 // Uninstall removes a runnign compose stack
 func (s SDK) Uninstall(projectName string) error {
-	return s.h.Uninstall(projectName)
+	return s.action.Uninstall(projectName)
 }
 
 // List returns a list of compose stacks
 func (s SDK) List() ([]compose.Stack, error) {
-	return s.h.ListReleases()
-}
-
-// GetDefaultEnv initializes Helm EnvSettings
-func (s SDK) GetDefaultEnv() *helmenv.EnvSettings {
-	return helmenv.New()
+	return s.action.ListReleases()
 }
 
 // GetChartInMemory get memory representation of helm chart
@@ -108,13 +118,3 @@ func (s SDK) GenerateChart(project *types.Project, dirname string) error {
 	dirname = filepath.Dir(dirname)
 	return s.SaveChart(project, dirname)
 }
-
-func environment() map[string]string {
-	vars := make(map[string]string)
-	env := os.Environ()
-	for _, v := range env {
-		k := strings.SplitN(v, "=", 2)
-		vars[k[0]] = k[1]
-	}
-	return vars
-}

+ 22 - 45
kube/charts/helm/helm.go

@@ -19,6 +19,7 @@
 package helm
 
 import (
+	"context"
 	"errors"
 	"log"
 
@@ -28,44 +29,38 @@ import (
 	loader "helm.sh/helm/v3/pkg/chart/loader"
 	env "helm.sh/helm/v3/pkg/cli"
 	"helm.sh/helm/v3/pkg/release"
+	"k8s.io/cli-runtime/pkg/genericclioptions"
 )
 
 // Actions helm actions
 type Actions struct {
-	Config       *action.Configuration
-	Settings     *env.EnvSettings
-	kubeConnInit bool
+	Config    *action.Configuration
+	Namespace string
 }
 
 // NewHelmActions new helm action
-func NewHelmActions(settings *env.EnvSettings) *Actions {
-	if settings == nil {
-		settings = env.New()
+func NewHelmActions(ctx context.Context, getter genericclioptions.RESTClientGetter) (*Actions, error) {
+	if getter == nil {
+		settings := env.New()
+		getter = settings.RESTClientGetter()
 	}
-	return &Actions{
-		Config:       new(action.Configuration),
-		Settings:     settings,
-		kubeConnInit: false,
-	}
-}
 
-func (hc *Actions) initKubeClient() error {
-	if hc.kubeConnInit {
-		return nil
+	namespace := "default"
+	if ns, _, err := getter.ToRawKubeConfigLoader().Namespace(); err == nil {
+		namespace = ns
 	}
-	if err := hc.Config.Init(
-		hc.Settings.RESTClientGetter(),
-		hc.Settings.Namespace(),
-		"configmap",
-		log.Printf,
-	); err != nil {
-		log.Fatal(err)
+	actions := &Actions{
+		Config: &action.Configuration{
+			RESTClientGetter: getter,
+		},
+		Namespace: namespace,
 	}
-	if err := hc.Config.KubeClient.IsReachable(); err != nil {
-		return err
+	err := actions.Config.Init(getter, namespace, "configmap", log.Printf)
+	if err != nil {
+		return nil, err
 	}
-	hc.kubeConnInit = true
-	return nil
+
+	return actions, actions.Config.KubeClient.IsReachable()
 }
 
 //InstallChartFromDir install from dir
@@ -79,14 +74,9 @@ func (hc *Actions) InstallChartFromDir(name string, chartpath string) error {
 
 // InstallChart instal chart
 func (hc *Actions) InstallChart(name string, chart *chart.Chart) error {
-	err := hc.initKubeClient()
-	if err != nil {
-		return err
-	}
-
 	actInstall := action.NewInstall(hc.Config)
 	actInstall.ReleaseName = name
-	actInstall.Namespace = hc.Settings.Namespace()
+	actInstall.Namespace = hc.Namespace
 
 	release, err := actInstall.Run(chart, map[string]interface{}{})
 	if err != nil {
@@ -99,11 +89,6 @@ func (hc *Actions) InstallChart(name string, chart *chart.Chart) error {
 
 // Uninstall uninstall chart
 func (hc *Actions) Uninstall(name string) error {
-	err := hc.initKubeClient()
-	if err != nil {
-		return err
-	}
-
 	release, err := hc.Get(name)
 	if err != nil {
 		return err
@@ -122,20 +107,12 @@ func (hc *Actions) Uninstall(name string) error {
 
 // Get get released object for a named chart
 func (hc *Actions) Get(name string) (*release.Release, error) {
-	err := hc.initKubeClient()
-	if err != nil {
-		return nil, err
-	}
 	actGet := action.NewGet(hc.Config)
 	return actGet.Run(name)
 }
 
 // ListReleases lists chart releases
 func (hc *Actions) ListReleases() ([]compose.Stack, error) {
-	err := hc.initKubeClient()
-	if err != nil {
-		return nil, err
-	}
 	actList := action.NewList(hc.Config)
 	releases, err := actList.Run()
 	if err != nil {

+ 51 - 5
kube/charts/kubernetes/context.go

@@ -22,11 +22,61 @@ import (
 	"fmt"
 	"os"
 
+	"github.com/docker/compose-cli/api/context/store"
+	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/client-go/tools/clientcmd"
+	"k8s.io/client-go/tools/clientcmd/api"
 )
 
 // ListAvailableKubeConfigContexts list kube contexts
 func ListAvailableKubeConfigContexts(kubeconfig string) ([]string, error) {
+	config, err := getKubeConfig(kubeconfig)
+	if err != nil {
+		return nil, err
+	}
+	contexts := []string{}
+	for k := range config.Contexts {
+		contexts = append(contexts, k)
+	}
+	return contexts, nil
+}
+
+// LoadConfig returns kubeconfig data referenced in the docker context
+func LoadConfig(ctx store.KubeContext) (*genericclioptions.ConfigFlags, error) {
+	if ctx.FromEnvironment {
+		return nil, nil
+	}
+	config, err := getKubeConfig(ctx.KubeconfigPath)
+	if err != nil {
+		return nil, err
+	}
+	contextName := ctx.ContextName
+	if contextName == "" {
+		contextName = config.CurrentContext
+	}
+
+	context, ok := config.Contexts[contextName]
+	if !ok {
+		return nil, fmt.Errorf("context name %s not found in kubeconfig", contextName)
+	}
+	cluster, ok := config.Clusters[context.Cluster]
+	if !ok {
+		return nil, fmt.Errorf("cluster %s not found for context %s", context.Cluster, contextName)
+	}
+	// bind to kubernetes config flags
+	return &genericclioptions.ConfigFlags{
+		Context:    &ctx.ContextName,
+		KubeConfig: &ctx.KubeconfigPath,
+
+		Namespace:   &context.Namespace,
+		ClusterName: &context.Cluster,
+
+		APIServer: &cluster.Server,
+		CAFile:    &cluster.CertificateAuthority,
+	}, nil
+}
+
+func getKubeConfig(kubeconfig string) (*api.Config, error) {
 	config, err := clientcmd.NewDefaultPathOptions().GetStartingConfig()
 	if err != nil {
 		return nil, err
@@ -43,9 +93,5 @@ func ListAvailableKubeConfigContexts(kubeconfig string) ([]string, error) {
 		config = clientcmd.GetConfigFromFileOrDie(kubeconfig)
 	}
 
-	contexts := []string{}
-	for k := range config.Contexts {
-		contexts = append(contexts, k)
-	}
-	return contexts, nil
+	return config, nil
 }

+ 1 - 4
kube/compose.go

@@ -23,25 +23,22 @@ import (
 
 	"github.com/compose-spec/compose-go/types"
 	"github.com/docker/compose-cli/api/compose"
-	"github.com/docker/compose-cli/api/context/store"
 	"github.com/docker/compose-cli/api/errdefs"
 	"github.com/docker/compose-cli/kube/charts"
 )
 
 // NewComposeService create a kubernetes implementation of the compose.Service API
-func NewComposeService(ctx store.KubeContext) (compose.Service, error) {
+func NewComposeService(ctx context.Context) (compose.Service, error) {
 	chartsAPI, err := charts.NewSDK(ctx)
 	if err != nil {
 		return nil, err
 	}
 	return &composeService{
-		ctx: ctx,
 		sdk: chartsAPI,
 	}, nil
 }
 
 type composeService struct {
-	ctx store.KubeContext
 	sdk charts.SDK
 }