/
client.go
152 lines (122 loc) · 4.6 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package k8s
import (
"fmt"
"os"
accessclient "github.com/servicemeshinterface/smi-sdk-go/pkg/gen/client/access/clientset/versioned"
specsclient "github.com/servicemeshinterface/smi-sdk-go/pkg/gen/client/specs/clientset/versioned"
splitclient "github.com/servicemeshinterface/smi-sdk-go/pkg/gen/client/split/clientset/versioned"
"github.com/sirupsen/logrus"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
// Client is an interface for the various resource controllers.
type Client interface {
KubernetesClient() kubernetes.Interface
AccessClient() accessclient.Interface
SpecsClient() specsclient.Interface
SplitClient() splitclient.Interface
}
// Ensure the client wrapper fits the Client interface.
var _ Client = (*ClientWrapper)(nil)
// ClientWrapper holds the clients for the various resource controllers.
type ClientWrapper struct {
kubeClient *kubernetes.Clientset
accessClient *accessclient.Clientset
specsClient *specsclient.Clientset
splitClient *splitclient.Clientset
}
// NewClient creates and returns a ClientWrapper that satisfies the Client interface.
func NewClient(logger logrus.FieldLogger, masterURL, kubeConfig string) (Client, error) {
config, err := buildConfig(logger, masterURL, kubeConfig)
if err != nil {
return nil, err
}
kubeClient, err := buildKubernetesClient(logger, config)
if err != nil {
return nil, err
}
accessClient, err := buildSmiAccessClient(logger, config)
if err != nil {
return nil, err
}
specsClient, err := buildSmiSpecsClient(logger, config)
if err != nil {
return nil, err
}
splitClient, err := buildSmiSplitClient(logger, config)
if err != nil {
return nil, err
}
return &ClientWrapper{
kubeClient: kubeClient,
accessClient: accessClient,
specsClient: specsClient,
splitClient: splitClient,
}, nil
}
// buildConfig takes the master URL and kubeconfig, and returns an external or internal config.
func buildConfig(logger logrus.FieldLogger, masterURL, kubeConfig string) (*rest.Config, error) {
if os.Getenv("KUBERNETES_SERVICE_HOST") != "" && os.Getenv("KUBERNETES_SERVICE_PORT") != "" {
// If these env vars are set, we can build an in-cluster config.
logger.Debug("Creating in-cluster client")
return rest.InClusterConfig()
}
if masterURL != "" || kubeConfig != "" {
logger.Debug("Creating cluster-external client from provided masterURL or kubeconfig")
return clientcmd.BuildConfigFromFlags(masterURL, kubeConfig)
}
return nil, fmt.Errorf("could not create client: missing masterURL or kubeConfig")
}
// KubernetesClient is used to get the kubernetes clientset.
func (w *ClientWrapper) KubernetesClient() kubernetes.Interface {
return w.kubeClient
}
// AccessClient is used to get the SMI Access clientset.
func (w *ClientWrapper) AccessClient() accessclient.Interface {
return w.accessClient
}
// SpecsClient is used to get the SMI Specs clientset.
func (w *ClientWrapper) SpecsClient() specsclient.Interface {
return w.specsClient
}
// SplitClient is used to get the SMI Split clientset.
func (w *ClientWrapper) SplitClient() splitclient.Interface {
return w.splitClient
}
// buildClient returns a useable kubernetes client.
func buildKubernetesClient(logger logrus.FieldLogger, config *rest.Config) (*kubernetes.Clientset, error) {
logger.Debug("Building Kubernetes Client...")
client, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to create kubernetes client: %w", err)
}
return client, nil
}
// buildSmiAccessClient returns a client to manage SMI Access objects.
func buildSmiAccessClient(logger logrus.FieldLogger, config *rest.Config) (*accessclient.Clientset, error) {
logger.Debug("Building SMI Access Client...")
client, err := accessclient.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to create SMI Access Client: %w", err)
}
return client, nil
}
// buildSmiSpecsClient returns a client to manage SMI Specs objects.
func buildSmiSpecsClient(logger logrus.FieldLogger, config *rest.Config) (*specsclient.Clientset, error) {
logger.Debug("Building SMI Specs Client...")
client, err := specsclient.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to create SMI Specs Client: %w", err)
}
return client, nil
}
// buildSmiSplitClient returns a client to manage SMI Split objects.
func buildSmiSplitClient(logger logrus.FieldLogger, config *rest.Config) (*splitclient.Clientset, error) {
logger.Debug("Building SMI Split Client...")
client, err := splitclient.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("unable to create SMI Split Client: %w", err)
}
return client, nil
}