Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit 166db3f

Browse files
authored
Merge pull request #1189 from aiordache/kube_compose_up
Kube backend: Target the cluster referenced by the docker context
2 parents 24b5aea + 0807ec0 commit 166db3f

File tree

6 files changed

+101
-91
lines changed

6 files changed

+101
-91
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ require (
6464
helm.sh/helm/v3 v3.5.0
6565
k8s.io/api v0.20.1
6666
k8s.io/apimachinery v0.20.1
67+
k8s.io/cli-runtime v0.20.1
6768
k8s.io/client-go v0.20.1
6869
sigs.k8s.io/kustomize/kyaml v0.10.5
6970
)

kube/backend.go

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
"github.com/docker/compose-cli/api/cloud"
2626
"github.com/docker/compose-cli/api/compose"
2727
"github.com/docker/compose-cli/api/containers"
28-
apicontext "github.com/docker/compose-cli/api/context"
2928
"github.com/docker/compose-cli/api/context/store"
3029
"github.com/docker/compose-cli/api/resources"
3130
"github.com/docker/compose-cli/api/secrets"
@@ -35,7 +34,6 @@ import (
3534
const backendType = store.KubeContextType
3635

3736
type kubeAPIService struct {
38-
ctx store.KubeContext
3937
composeService compose.Service
4038
}
4139

@@ -44,20 +42,11 @@ func init() {
4442
}
4543

4644
func service(ctx context.Context) (backend.Service, error) {
47-
contextStore := store.ContextStore(ctx)
48-
currentContext := apicontext.CurrentContext(ctx)
49-
var kubeContext store.KubeContext
50-
51-
if err := contextStore.GetEndpoint(currentContext, &kubeContext); err != nil {
52-
return nil, err
53-
}
54-
55-
s, err := NewComposeService(kubeContext)
45+
s, err := NewComposeService(ctx)
5646
if err != nil {
5747
return nil, err
5848
}
5949
return &kubeAPIService{
60-
ctx: kubeContext,
6150
composeService: s,
6251
}, nil
6352
}

kube/charts/charts.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,46 @@
1919
package charts
2020

2121
import (
22-
"os"
22+
"context"
2323
"path/filepath"
2424
"strings"
2525

2626
"github.com/compose-spec/compose-go/types"
2727
"github.com/docker/compose-cli/api/compose"
28+
apicontext "github.com/docker/compose-cli/api/context"
2829
"github.com/docker/compose-cli/api/context/store"
2930
"github.com/docker/compose-cli/kube/charts/helm"
3031
"github.com/docker/compose-cli/kube/charts/kubernetes"
3132
chart "helm.sh/helm/v3/pkg/chart"
3233
util "helm.sh/helm/v3/pkg/chartutil"
33-
helmenv "helm.sh/helm/v3/pkg/cli"
3434
)
3535

3636
//SDK chart SDK
3737
type SDK struct {
38-
h *helm.Actions
39-
environment map[string]string
38+
action *helm.Actions
4039
}
4140

4241
// NewSDK new chart SDK
43-
func NewSDK(ctx store.KubeContext) (SDK, error) {
42+
func NewSDK(ctx context.Context) (SDK, error) {
43+
contextStore := store.ContextStore(ctx)
44+
currentContext := apicontext.CurrentContext(ctx)
45+
var kubeContext store.KubeContext
46+
47+
if err := contextStore.GetEndpoint(currentContext, &kubeContext); err != nil {
48+
return SDK{}, err
49+
}
50+
51+
config, err := kubernetes.LoadConfig(kubeContext)
52+
if err != nil {
53+
return SDK{}, err
54+
}
55+
56+
actions, err := helm.NewHelmActions(ctx, config)
57+
if err != nil {
58+
return SDK{}, err
59+
}
4460
return SDK{
45-
environment: environment(),
46-
h: helm.NewHelmActions(nil),
61+
action: actions,
4762
}, nil
4863
}
4964

@@ -53,22 +68,17 @@ func (s SDK) Install(project *types.Project) error {
5368
if err != nil {
5469
return err
5570
}
56-
return s.h.InstallChart(project.Name, chart)
71+
return s.action.InstallChart(project.Name, chart)
5772
}
5873

5974
// Uninstall removes a runnign compose stack
6075
func (s SDK) Uninstall(projectName string) error {
61-
return s.h.Uninstall(projectName)
76+
return s.action.Uninstall(projectName)
6277
}
6378

6479
// List returns a list of compose stacks
6580
func (s SDK) List() ([]compose.Stack, error) {
66-
return s.h.ListReleases()
67-
}
68-
69-
// GetDefaultEnv initializes Helm EnvSettings
70-
func (s SDK) GetDefaultEnv() *helmenv.EnvSettings {
71-
return helmenv.New()
81+
return s.action.ListReleases()
7282
}
7383

7484
// GetChartInMemory get memory representation of helm chart
@@ -108,13 +118,3 @@ func (s SDK) GenerateChart(project *types.Project, dirname string) error {
108118
dirname = filepath.Dir(dirname)
109119
return s.SaveChart(project, dirname)
110120
}
111-
112-
func environment() map[string]string {
113-
vars := make(map[string]string)
114-
env := os.Environ()
115-
for _, v := range env {
116-
k := strings.SplitN(v, "=", 2)
117-
vars[k[0]] = k[1]
118-
}
119-
return vars
120-
}

kube/charts/helm/helm.go

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package helm
2020

2121
import (
22+
"context"
2223
"errors"
2324
"log"
2425

@@ -28,44 +29,38 @@ import (
2829
loader "helm.sh/helm/v3/pkg/chart/loader"
2930
env "helm.sh/helm/v3/pkg/cli"
3031
"helm.sh/helm/v3/pkg/release"
32+
"k8s.io/cli-runtime/pkg/genericclioptions"
3133
)
3234

3335
// Actions helm actions
3436
type Actions struct {
35-
Config *action.Configuration
36-
Settings *env.EnvSettings
37-
kubeConnInit bool
37+
Config *action.Configuration
38+
Namespace string
3839
}
3940

4041
// NewHelmActions new helm action
41-
func NewHelmActions(settings *env.EnvSettings) *Actions {
42-
if settings == nil {
43-
settings = env.New()
42+
func NewHelmActions(ctx context.Context, getter genericclioptions.RESTClientGetter) (*Actions, error) {
43+
if getter == nil {
44+
settings := env.New()
45+
getter = settings.RESTClientGetter()
4446
}
45-
return &Actions{
46-
Config: new(action.Configuration),
47-
Settings: settings,
48-
kubeConnInit: false,
49-
}
50-
}
5147

52-
func (hc *Actions) initKubeClient() error {
53-
if hc.kubeConnInit {
54-
return nil
48+
namespace := "default"
49+
if ns, _, err := getter.ToRawKubeConfigLoader().Namespace(); err == nil {
50+
namespace = ns
5551
}
56-
if err := hc.Config.Init(
57-
hc.Settings.RESTClientGetter(),
58-
hc.Settings.Namespace(),
59-
"configmap",
60-
log.Printf,
61-
); err != nil {
62-
log.Fatal(err)
52+
actions := &Actions{
53+
Config: &action.Configuration{
54+
RESTClientGetter: getter,
55+
},
56+
Namespace: namespace,
6357
}
64-
if err := hc.Config.KubeClient.IsReachable(); err != nil {
65-
return err
58+
err := actions.Config.Init(getter, namespace, "configmap", log.Printf)
59+
if err != nil {
60+
return nil, err
6661
}
67-
hc.kubeConnInit = true
68-
return nil
62+
63+
return actions, actions.Config.KubeClient.IsReachable()
6964
}
7065

7166
//InstallChartFromDir install from dir
@@ -79,14 +74,9 @@ func (hc *Actions) InstallChartFromDir(name string, chartpath string) error {
7974

8075
// InstallChart instal chart
8176
func (hc *Actions) InstallChart(name string, chart *chart.Chart) error {
82-
err := hc.initKubeClient()
83-
if err != nil {
84-
return err
85-
}
86-
8777
actInstall := action.NewInstall(hc.Config)
8878
actInstall.ReleaseName = name
89-
actInstall.Namespace = hc.Settings.Namespace()
79+
actInstall.Namespace = hc.Namespace
9080

9181
release, err := actInstall.Run(chart, map[string]interface{}{})
9282
if err != nil {
@@ -99,11 +89,6 @@ func (hc *Actions) InstallChart(name string, chart *chart.Chart) error {
9989

10090
// Uninstall uninstall chart
10191
func (hc *Actions) Uninstall(name string) error {
102-
err := hc.initKubeClient()
103-
if err != nil {
104-
return err
105-
}
106-
10792
release, err := hc.Get(name)
10893
if err != nil {
10994
return err
@@ -122,20 +107,12 @@ func (hc *Actions) Uninstall(name string) error {
122107

123108
// Get get released object for a named chart
124109
func (hc *Actions) Get(name string) (*release.Release, error) {
125-
err := hc.initKubeClient()
126-
if err != nil {
127-
return nil, err
128-
}
129110
actGet := action.NewGet(hc.Config)
130111
return actGet.Run(name)
131112
}
132113

133114
// ListReleases lists chart releases
134115
func (hc *Actions) ListReleases() ([]compose.Stack, error) {
135-
err := hc.initKubeClient()
136-
if err != nil {
137-
return nil, err
138-
}
139116
actList := action.NewList(hc.Config)
140117
releases, err := actList.Run()
141118
if err != nil {

kube/charts/kubernetes/context.go

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,61 @@ import (
2222
"fmt"
2323
"os"
2424

25+
"github.com/docker/compose-cli/api/context/store"
26+
"k8s.io/cli-runtime/pkg/genericclioptions"
2527
"k8s.io/client-go/tools/clientcmd"
28+
"k8s.io/client-go/tools/clientcmd/api"
2629
)
2730

2831
// ListAvailableKubeConfigContexts list kube contexts
2932
func ListAvailableKubeConfigContexts(kubeconfig string) ([]string, error) {
33+
config, err := getKubeConfig(kubeconfig)
34+
if err != nil {
35+
return nil, err
36+
}
37+
contexts := []string{}
38+
for k := range config.Contexts {
39+
contexts = append(contexts, k)
40+
}
41+
return contexts, nil
42+
}
43+
44+
// LoadConfig returns kubeconfig data referenced in the docker context
45+
func LoadConfig(ctx store.KubeContext) (*genericclioptions.ConfigFlags, error) {
46+
if ctx.FromEnvironment {
47+
return nil, nil
48+
}
49+
config, err := getKubeConfig(ctx.KubeconfigPath)
50+
if err != nil {
51+
return nil, err
52+
}
53+
contextName := ctx.ContextName
54+
if contextName == "" {
55+
contextName = config.CurrentContext
56+
}
57+
58+
context, ok := config.Contexts[contextName]
59+
if !ok {
60+
return nil, fmt.Errorf("context name %s not found in kubeconfig", contextName)
61+
}
62+
cluster, ok := config.Clusters[context.Cluster]
63+
if !ok {
64+
return nil, fmt.Errorf("cluster %s not found for context %s", context.Cluster, contextName)
65+
}
66+
// bind to kubernetes config flags
67+
return &genericclioptions.ConfigFlags{
68+
Context: &ctx.ContextName,
69+
KubeConfig: &ctx.KubeconfigPath,
70+
71+
Namespace: &context.Namespace,
72+
ClusterName: &context.Cluster,
73+
74+
APIServer: &cluster.Server,
75+
CAFile: &cluster.CertificateAuthority,
76+
}, nil
77+
}
78+
79+
func getKubeConfig(kubeconfig string) (*api.Config, error) {
3080
config, err := clientcmd.NewDefaultPathOptions().GetStartingConfig()
3181
if err != nil {
3282
return nil, err
@@ -43,9 +93,5 @@ func ListAvailableKubeConfigContexts(kubeconfig string) ([]string, error) {
4393
config = clientcmd.GetConfigFromFileOrDie(kubeconfig)
4494
}
4595

46-
contexts := []string{}
47-
for k := range config.Contexts {
48-
contexts = append(contexts, k)
49-
}
50-
return contexts, nil
96+
return config, nil
5197
}

kube/compose.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,22 @@ import (
2424
"github.com/compose-spec/compose-go/types"
2525

2626
"github.com/docker/compose-cli/api/compose"
27-
"github.com/docker/compose-cli/api/context/store"
2827
"github.com/docker/compose-cli/api/errdefs"
2928
"github.com/docker/compose-cli/kube/charts"
3029
)
3130

3231
// NewComposeService create a kubernetes implementation of the compose.Service API
33-
func NewComposeService(ctx store.KubeContext) (compose.Service, error) {
32+
func NewComposeService(ctx context.Context) (compose.Service, error) {
3433
chartsAPI, err := charts.NewSDK(ctx)
3534
if err != nil {
3635
return nil, err
3736
}
3837
return &composeService{
39-
ctx: ctx,
4038
sdk: chartsAPI,
4139
}, nil
4240
}
4341

4442
type composeService struct {
45-
ctx store.KubeContext
4643
sdk charts.SDK
4744
}
4845

0 commit comments

Comments
 (0)