Skip to content

Commit ae6ccad

Browse files
authored
fix(api): make use of the provided kube config for all the client init (#2453)
* fix(api): make use of the provided kube config for all the client init * chore: better handling of the clientset schemes for the base kube-client * chore: fix unit tests * chore: tests for the clients * chore: remove Close() calls * chore: add more tests * chore: fix integration tests * fix: add missing api extensions scheme
1 parent 200a977 commit ae6ccad

File tree

13 files changed

+719
-138
lines changed

13 files changed

+719
-138
lines changed

api/controllers/kubernetes/install/controller.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package install
22

33
import (
44
"context"
5+
"fmt"
56
"sync"
67

78
appconfig "github.com/replicatedhq/embedded-cluster/api/internal/managers/app/config"
@@ -17,6 +18,7 @@ import (
1718
"github.com/replicatedhq/embedded-cluster/pkg/release"
1819
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
1920
"github.com/sirupsen/logrus"
21+
helmcli "helm.sh/helm/v3/pkg/cli"
2022
"k8s.io/cli-runtime/pkg/genericclioptions"
2123
)
2224

@@ -162,6 +164,11 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
162164
opt(controller)
163165
}
164166

167+
// If none is provided, use the default env settings from helm to create a RESTClientGetter
168+
if controller.restClientGetter == nil {
169+
controller.restClientGetter = helmcli.New().RESTClientGetter()
170+
}
171+
165172
if controller.installationManager == nil {
166173
controller.installationManager = installation.NewInstallationManager(
167174
installation.WithLogger(controller.logger),
@@ -170,7 +177,7 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
170177
}
171178

172179
if controller.infraManager == nil {
173-
controller.infraManager = infra.NewInfraManager(
180+
infraManager, err := infra.NewInfraManager(
174181
infra.WithLogger(controller.logger),
175182
infra.WithInfraStore(controller.store.LinuxInfraStore()),
176183
infra.WithRESTClientGetter(controller.restClientGetter),
@@ -182,6 +189,10 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
182189
infra.WithReleaseData(controller.releaseData),
183190
infra.WithEndUserConfig(controller.endUserConfig),
184191
)
192+
if err != nil {
193+
return nil, fmt.Errorf("create infra manager: %w", err)
194+
}
195+
controller.infraManager = infraManager
185196
}
186197

187198
if controller.appConfigManager == nil {

api/integration/kubernetes/install/infra_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func TestKubernetesPostSetupInfra(t *testing.T) {
6666
ki := kubernetesinstallation.New(nil)
6767

6868
// Create infra manager with mocks
69-
infraManager := kubernetesinfra.NewInfraManager(
69+
infraManager, err := kubernetesinfra.NewInfraManager(
7070
kubernetesinfra.WithKubeClient(fakeKcli),
7171
kubernetesinfra.WithMetadataClient(fakeMcli),
7272
kubernetesinfra.WithHelmClient(helmMock),
@@ -84,10 +84,10 @@ func TestKubernetesPostSetupInfra(t *testing.T) {
8484
},
8585
}),
8686
)
87+
require.NoError(t, err)
8788

8889
mock.InOrder(
8990
helmMock.On("Install", mock.Anything, mock.Anything).Times(1).Return(nil, nil), // 1 addon
90-
helmMock.On("Close").Return(nil),
9191
)
9292

9393
// Create an install controller with the mocked managers
@@ -254,7 +254,7 @@ func TestKubernetesPostSetupInfra(t *testing.T) {
254254
ki := kubernetesinstallation.New(nil)
255255

256256
// Create infra manager with mocks
257-
infraManager := kubernetesinfra.NewInfraManager(
257+
infraManager, err := kubernetesinfra.NewInfraManager(
258258
kubernetesinfra.WithKubeClient(fakeKcli),
259259
kubernetesinfra.WithMetadataClient(fakeMcli),
260260
kubernetesinfra.WithHelmClient(helmMock),
@@ -272,10 +272,10 @@ func TestKubernetesPostSetupInfra(t *testing.T) {
272272
},
273273
}),
274274
)
275+
require.NoError(t, err)
275276

276277
mock.InOrder(
277278
helmMock.On("Install", mock.Anything, mock.Anything).Times(1).Return(nil, assert.AnError), // 1 addon
278-
helmMock.On("Close").Return(nil),
279279
)
280280

281281
// Create an install controller with the mocked managers

api/integration/linux/install/infra_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ func TestLinuxPostSetupInfra(t *testing.T) {
133133
k0sMock.On("WaitForK0s").Return(nil),
134134
hostutilsMock.On("AddInsecureRegistry", mock.Anything).Return(nil),
135135
helmMock.On("Install", mock.Anything, mock.Anything).Times(4).Return(nil, nil), // 4 addons
136-
helmMock.On("Close").Return(nil),
137136
)
138137

139138
// Create an install controller with the mocked managers

api/internal/clients/kube.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package clients
2+
3+
import (
4+
"fmt"
5+
6+
autopilotv1beta2 "github.com/k0sproject/k0s/pkg/apis/autopilot/v1beta2"
7+
k0shelmv1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1"
8+
k0sv1beta1 "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
9+
embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
10+
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
11+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
12+
"k8s.io/apimachinery/pkg/runtime"
13+
"k8s.io/cli-runtime/pkg/genericclioptions"
14+
coreclientset "k8s.io/client-go/kubernetes/scheme"
15+
"k8s.io/client-go/metadata"
16+
"k8s.io/client-go/rest"
17+
"k8s.io/client-go/tools/clientcmd"
18+
"sigs.k8s.io/controller-runtime/pkg/client"
19+
)
20+
21+
var localSchemeBuilder = runtime.NewSchemeBuilder(
22+
apiextensionsv1.AddToScheme,
23+
embeddedclusterv1beta1.AddToScheme,
24+
//nolint:staticcheck // SA1019 we are using the deprecated scheme for backwards compatibility, we can remove this once we stop supporting k0s v1.30
25+
autopilotv1beta2.AddToScheme,
26+
//nolint:staticcheck // SA1019 we are using the deprecated scheme for backwards compatibility, we can remove this once we stop supporting k0s v1.30
27+
k0sv1beta1.AddToScheme,
28+
//nolint:staticcheck // SA1019 we are using the deprecated scheme for backwards compatibility, we can remove this once we stop supporting k0s v1.30
29+
k0shelmv1beta1.AddToScheme,
30+
velerov1.AddToScheme,
31+
)
32+
33+
type KubeClientOptions struct {
34+
RESTClientGetter genericclioptions.RESTClientGetter
35+
KubeConfigPath string
36+
}
37+
38+
func getScheme() *runtime.Scheme {
39+
s := runtime.NewScheme()
40+
coreclientset.AddToScheme(s)
41+
localSchemeBuilder.AddToScheme(s)
42+
return s
43+
}
44+
45+
// NewKubeClient returns a new kubernetes client.
46+
func NewKubeClient(opts KubeClientOptions) (client.Client, error) {
47+
var restConfig *rest.Config
48+
if opts.RESTClientGetter == nil && opts.KubeConfigPath == "" {
49+
return nil, fmt.Errorf("a valid kube config is required to create a kube client")
50+
}
51+
52+
if opts.RESTClientGetter == nil {
53+
conf, err := clientcmd.BuildConfigFromFlags("", opts.KubeConfigPath)
54+
if err != nil {
55+
return nil, fmt.Errorf("unable to process kubernetes config for kube client: %w", err)
56+
}
57+
restConfig = conf
58+
} else {
59+
conf, err := opts.RESTClientGetter.ToRESTConfig()
60+
if err != nil {
61+
return nil, fmt.Errorf("unable to process rest client config for kube client: %w", err)
62+
}
63+
restConfig = conf
64+
}
65+
66+
return client.New(restConfig, client.Options{Scheme: getScheme()})
67+
}
68+
69+
// NewMetadataClient returns a new kube metadata client.
70+
func NewMetadataClient(opts KubeClientOptions) (metadata.Interface, error) {
71+
var restConfig *rest.Config
72+
if opts.RESTClientGetter == nil && opts.KubeConfigPath == "" {
73+
return nil, fmt.Errorf("a valid kube config is required to create a kube client")
74+
}
75+
76+
if opts.RESTClientGetter == nil {
77+
conf, err := clientcmd.BuildConfigFromFlags("", opts.KubeConfigPath)
78+
if err != nil {
79+
return nil, fmt.Errorf("unable to process kubernetes config for kube client: %w", err)
80+
}
81+
restConfig = conf
82+
} else {
83+
conf, err := opts.RESTClientGetter.ToRESTConfig()
84+
if err != nil {
85+
return nil, fmt.Errorf("unable to process rest client config for kube client: %w", err)
86+
}
87+
restConfig = conf
88+
}
89+
90+
return metadata.NewForConfig(restConfig)
91+
}

0 commit comments

Comments
 (0)