Skip to content

Commit 7a979b2

Browse files
committed
Implement configutils
1 parent b444828 commit 7a979b2

26 files changed

+331
-37
lines changed

clientutils/clientutils_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package clientutils_test
1717
import (
1818
"testing"
1919

20-
. "github.com/onsi/ginkgo"
20+
. "github.com/onsi/ginkgo/v2"
2121
. "github.com/onsi/gomega"
2222
)
2323

clientutils/clientutils_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
mockclient "github.com/onmetal/controller-utils/mock/controller-runtime/client"
2727
mockclientutils "github.com/onmetal/controller-utils/mock/controller-utils/clientutils"
2828
"github.com/onmetal/controller-utils/testdata"
29-
. "github.com/onsi/ginkgo"
29+
. "github.com/onsi/ginkgo/v2"
3030
. "github.com/onsi/gomega"
3131
"github.com/stretchr/testify/mock"
3232
corev1 "k8s.io/api/core/v1"
@@ -66,7 +66,7 @@ var _ = Describe("Clientutils", func() {
6666

6767
patchProvider *mockclientutils.MockPatchProvider
6868
)
69-
setup := func() {
69+
BeforeEach(func() {
7070
ctx = context.Background()
7171
ctrl = gomock.NewController(GinkgoT())
7272

@@ -104,12 +104,6 @@ var _ = Describe("Clientutils", func() {
104104
secretKey = client.ObjectKeyFromObject(secret)
105105

106106
patchProvider = mockclientutils.NewMockPatchProvider(ctrl)
107-
}
108-
setup()
109-
BeforeEach(setup)
110-
111-
AfterEach(func() {
112-
ctrl.Finish()
113107
})
114108

115109
Describe("IgnoreAlreadyExists", func() {

clientutils/fieldindexer_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919

2020
"github.com/golang/mock/gomock"
2121
mockclient "github.com/onmetal/controller-utils/mock/controller-runtime/client"
22-
. "github.com/onsi/ginkgo"
22+
. "github.com/onsi/ginkgo/v2"
2323
. "github.com/onsi/gomega"
2424
corev1 "k8s.io/api/core/v1"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -37,9 +37,6 @@ var _ = Describe("FieldIndexer", func() {
3737
ctx = context.Background()
3838
ctrl = gomock.NewController(GinkgoT())
3939
})
40-
AfterEach(func() {
41-
ctrl.Finish()
42-
})
4340

4441
Context("SharedFieldIndexer", func() {
4542
var (

clientutils/objectkey_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package clientutils_test
1616

1717
import (
1818
. "github.com/onmetal/controller-utils/clientutils"
19-
. "github.com/onsi/ginkgo"
19+
. "github.com/onsi/ginkgo/v2"
2020
. "github.com/onsi/gomega"
2121
"sigs.k8s.io/controller-runtime/pkg/client"
2222
)

clientutils/objectref_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
package clientutils
1616

1717
import (
18-
. "github.com/onsi/ginkgo"
18+
. "github.com/onsi/ginkgo/v2"
1919
. "github.com/onsi/gomega"
2020
corev1 "k8s.io/api/core/v1"
2121
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

cmdutils/switches/switches_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package switches
1717
import (
1818
"testing"
1919

20-
. "github.com/onsi/ginkgo"
20+
. "github.com/onsi/ginkgo/v2"
2121
. "github.com/onsi/gomega"
2222
)
2323

cmdutils/switches/switches_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package switches
1616
import (
1717
"flag"
1818

19-
. "github.com/onsi/ginkgo"
19+
. "github.com/onsi/ginkgo/v2"
2020
. "github.com/onsi/gomega"
2121
"github.com/spf13/pflag"
2222
"k8s.io/apimachinery/pkg/util/sets"

conditionutils/conditionutils_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package conditionutils_test
1717
import (
1818
"testing"
1919

20-
. "github.com/onsi/ginkgo"
20+
. "github.com/onsi/ginkgo/v2"
2121
. "github.com/onsi/gomega"
2222
)
2323

conditionutils/conditionutils_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"time"
1919

2020
"github.com/onmetal/controller-utils/conditionutils"
21-
. "github.com/onsi/ginkgo"
21+
. "github.com/onsi/ginkgo/v2"
2222
. "github.com/onsi/gomega"
2323
. "github.com/onsi/gomega/gstruct"
2424
appsv1 "k8s.io/api/apps/v1"

configutils/configutils.go

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Copyright 2022 OnMetal authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package configutils
16+
17+
import (
18+
"flag"
19+
"fmt"
20+
"os"
21+
"os/user"
22+
"path/filepath"
23+
24+
"k8s.io/client-go/rest"
25+
"k8s.io/client-go/tools/clientcmd"
26+
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
27+
"k8s.io/utils/pointer"
28+
)
29+
30+
var (
31+
kubeconfig string
32+
)
33+
34+
const (
35+
RecommendedConfigUsage = "Paths to a kubeconfig. Only required if out-of-cluster."
36+
)
37+
38+
func init() {
39+
// TODO: Fix this to allow double vendoring this library but still register flags on behalf of users
40+
flag.StringVar(&kubeconfig, clientcmd.RecommendedConfigPathFlag, "",
41+
RecommendedConfigUsage)
42+
}
43+
44+
// GetConfigOptions are options to supply for a GetConfig call.
45+
type GetConfigOptions struct {
46+
// Context is the kubeconfig context to load.
47+
Context string
48+
// Kubeconfig is the path to a kubeconfig to load.
49+
// If unset, the '--kubeconfig' flag is used.
50+
Kubeconfig *string
51+
}
52+
53+
// ApplyToGetConfig implements GetConfigOption.
54+
func (o *GetConfigOptions) ApplyToGetConfig(o2 *GetConfigOptions) {
55+
if o.Context != "" {
56+
o2.Context = o.Context
57+
}
58+
if o.Kubeconfig != nil {
59+
o2.Kubeconfig = pointer.String(*o.Kubeconfig)
60+
}
61+
}
62+
63+
// ApplyOptions applies all GetConfigOption tro this GetConfigOptions.
64+
func (o *GetConfigOptions) ApplyOptions(opts []GetConfigOption) {
65+
for _, opt := range opts {
66+
opt.ApplyToGetConfig(o)
67+
}
68+
}
69+
70+
// Kubeconfig allows specifying the path to a kubeconfig file to use.
71+
type Kubeconfig string
72+
73+
// ApplyToGetConfig implements GetConfigOption.
74+
func (k Kubeconfig) ApplyToGetConfig(o *GetConfigOptions) {
75+
o.Kubeconfig = (*string)(&k)
76+
}
77+
78+
// Context allows specifying the context to load.
79+
type Context string
80+
81+
// ApplyToGetConfig implements GetConfigOption.
82+
func (c Context) ApplyToGetConfig(o *GetConfigOptions) {
83+
o.Context = string(c)
84+
}
85+
86+
// GetConfigOption are options to a GetConfig call.
87+
type GetConfigOption interface {
88+
// ApplyToGetConfig modifies the underlying GetConfigOptions.
89+
ApplyToGetConfig(o *GetConfigOptions)
90+
}
91+
92+
func loadConfigWithContext(apiServerURL string, loader clientcmd.ClientConfigLoader, context string) (*rest.Config, error) {
93+
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
94+
loader,
95+
&clientcmd.ConfigOverrides{
96+
ClusterInfo: clientcmdapi.Cluster{
97+
Server: apiServerURL,
98+
},
99+
CurrentContext: context,
100+
}).ClientConfig()
101+
}
102+
103+
// loadInClusterConfig is a function used to load the in-cluster
104+
// Kubernetes client config. This variable makes is possible to
105+
// test the precedence of loading the config.
106+
var loadInClusterConfig = rest.InClusterConfig
107+
108+
// GetConfig creates a *rest.Config for talking to a Kubernetes API server.
109+
// Kubeconfig / the '--kubeconfig' flag instruct to use the kubeconfig file at that location.
110+
// Otherwise, will assume running in cluster and use the cluster provided kubeconfig.
111+
//
112+
// It also applies saner defaults for QPS and burst based on the Kubernetes
113+
// controller manager defaults (20 QPS, 30 burst)
114+
//
115+
// Config precedence
116+
//
117+
// * Kubeconfig / --kubeconfig value / flag pointing at a file
118+
//
119+
// * KUBECONFIG environment variable pointing at a file
120+
//
121+
// * In-cluster config if running in cluster
122+
//
123+
// * $HOME/.kube/config if exists.
124+
func GetConfig(opts ...GetConfigOption) (*rest.Config, error) {
125+
o := &GetConfigOptions{}
126+
o.ApplyOptions(opts)
127+
128+
kubeconfig := kubeconfig
129+
if o.Kubeconfig != nil {
130+
kubeconfig = *o.Kubeconfig
131+
}
132+
133+
// If a flag is specified with the config location, use that
134+
if len(kubeconfig) > 0 {
135+
return loadConfigWithContext("", &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}, o.Context)
136+
}
137+
138+
// If the recommended kubeconfig env variable is not specified,
139+
// try the in-cluster config.
140+
kubeconfigPath := os.Getenv(clientcmd.RecommendedConfigPathEnvVar)
141+
if len(kubeconfigPath) == 0 {
142+
if c, err := loadInClusterConfig(); err == nil {
143+
return c, nil
144+
}
145+
}
146+
147+
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
148+
if _, ok := os.LookupEnv("HOME"); !ok {
149+
u, err := user.Current()
150+
if err != nil {
151+
return nil, fmt.Errorf("could not get current user: %v", err)
152+
}
153+
loadingRules.Precedence = append(loadingRules.Precedence, filepath.Join(u.HomeDir, clientcmd.RecommendedHomeDir, clientcmd.RecommendedFileName))
154+
}
155+
156+
return loadConfigWithContext("", loadingRules, o.Context)
157+
}

0 commit comments

Comments
 (0)