forked from SumoLogic/sumologic-otel-collector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathk8sconfig.go
163 lines (138 loc) · 4.8 KB
/
k8sconfig.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
153
154
155
156
157
158
159
160
161
162
163
// Copyright 2020, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This is a copy of https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/internal/k8sconfig/config.go
// We can't import it normally yet, since it's an internal package. We can use a normal import if/when we move to upstream
// or upstream makes this non-internal.
package rawk8seventsreceiver
import (
"fmt"
"net"
"net/http"
"os"
quotaclientset "github.com/openshift/client-go/quota/clientset/versioned"
k8s "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
// AuthType describes the type of authentication to use for the K8s API
type AuthType string
// TODO: Add option for TLS once
// https://go.opentelemetry.io/collector/issues/933
// is addressed.
const (
// AuthTypeNone means no auth is required
AuthTypeNone AuthType = "none"
// AuthTypeServiceAccount means to use the built-in service account that
// K8s automatically provisions for each pod.
AuthTypeServiceAccount AuthType = "serviceAccount"
// AuthTypeKubeConfig uses local credentials like those used by kubectl.
AuthTypeKubeConfig AuthType = "kubeConfig"
// AuthTypeTLS indicates that client TLS auth is desired
AuthTypeTLS AuthType = "tls"
)
var authTypes = map[AuthType]bool{
AuthTypeNone: true,
AuthTypeServiceAccount: true,
AuthTypeKubeConfig: true,
}
// APIConfig contains options relevant to connecting to the K8s API
type APIConfig struct {
// How to authenticate to the K8s API server. This can be one of `none`
// (for no auth), `serviceAccount` (to use the standard service account
// token provided to the agent pod), or `kubeConfig` to use credentials
// from `~/.kube/config`.
AuthType AuthType `mapstructure:"auth_type"`
}
// Validate validates the K8s API config
func (c APIConfig) Validate() error {
if !authTypes[c.AuthType] {
return fmt.Errorf("invalid authType for kubernetes: %v", c.AuthType)
}
return nil
}
// createRestConfig creates an Kubernetes API config from user configuration.
func createRestConfig(apiConf APIConfig) (*rest.Config, error) {
var authConf *rest.Config
var err error
authType := apiConf.AuthType
var k8sHost string
if authType != AuthTypeKubeConfig {
host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
if len(host) == 0 || len(port) == 0 {
return nil, fmt.Errorf("unable to load k8s config, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined")
}
k8sHost = "https://" + net.JoinHostPort(host, port)
}
switch authType {
case AuthTypeKubeConfig:
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
configOverrides := &clientcmd.ConfigOverrides{}
authConf, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
loadingRules, configOverrides).ClientConfig()
if err != nil {
return nil, fmt.Errorf("error connecting to k8s with auth_type=%s: %w", AuthTypeKubeConfig, err)
}
case AuthTypeNone:
authConf = &rest.Config{
Host: k8sHost,
}
authConf.Insecure = true
case AuthTypeServiceAccount:
// This should work for most clusters but other auth types can be added
authConf, err = rest.InClusterConfig()
if err != nil {
return nil, err
}
}
authConf.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
// Don't use system proxy settings since the API is local to the
// cluster
if t, ok := rt.(*http.Transport); ok {
t.Proxy = nil
}
return rt
}
return authConf, nil
}
// MakeClient can take configuration if needed for other types of auth
func MakeClient(apiConf APIConfig) (k8s.Interface, error) {
if err := apiConf.Validate(); err != nil {
return nil, err
}
authConf, err := createRestConfig(apiConf)
if err != nil {
return nil, err
}
client, err := k8s.NewForConfig(authConf)
if err != nil {
return nil, err
}
return client, nil
}
// MakeOpenShiftQuotaClient can take configuration if needed for other types of auth
// and return an OpenShift quota API client
func MakeOpenShiftQuotaClient(apiConf APIConfig) (quotaclientset.Interface, error) {
if err := apiConf.Validate(); err != nil {
return nil, err
}
authConf, err := createRestConfig(apiConf)
if err != nil {
return nil, err
}
client, err := quotaclientset.NewForConfig(authConf)
if err != nil {
return nil, err
}
return client, nil
}