forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
impersonate.go
85 lines (70 loc) · 2.88 KB
/
impersonate.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
package impersonatingclient
import (
"net/http"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/authentication/user"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/transport"
"k8s.io/client-go/util/flowcontrol"
kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
)
// NewImpersonatingConfig wraps the config's transport to impersonate a user, including user, groups, and scopes
func NewImpersonatingConfig(user user.Info, config restclient.Config) restclient.Config {
oldWrapTransport := config.WrapTransport
config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
newConfig := transport.ImpersonationConfig{
UserName: user.GetName(),
Groups: user.GetGroups(),
Extra: user.GetExtra(),
}
return transport.NewImpersonatingRoundTripper(newConfig, oldWrapTransport(rt))
}
return config
}
// NewImpersonatingKubernetesClientset returns a Kubernetes clientset that will impersonate a user, including user, groups, and scopes
func NewImpersonatingKubernetesClientset(user user.Info, config restclient.Config) (kclientset.Interface, error) {
impersonatingConfig := NewImpersonatingConfig(user, config)
return kclientset.NewForConfig(&impersonatingConfig)
}
// impersonatingRESTClient sets impersonating user, groups, and scopes headers per request
type impersonatingRESTClient struct {
user user.Info
delegate restclient.Interface
}
func NewImpersonatingRESTClient(user user.Info, client restclient.Interface) restclient.Interface {
return &impersonatingRESTClient{user: user, delegate: client}
}
// Verb does the impersonation per request by setting the proper headers
func (c impersonatingRESTClient) impersonate(req *restclient.Request) *restclient.Request {
req.SetHeader(transport.ImpersonateUserHeader, c.user.GetName())
req.SetHeader(transport.ImpersonateGroupHeader, c.user.GetGroups()...)
for k, vv := range c.user.GetExtra() {
req.SetHeader(transport.ImpersonateUserExtraHeaderPrefix+k, vv...)
}
return req
}
func (c impersonatingRESTClient) Verb(verb string) *restclient.Request {
return c.impersonate(c.delegate.Verb(verb))
}
func (c impersonatingRESTClient) Post() *restclient.Request {
return c.impersonate(c.delegate.Post())
}
func (c impersonatingRESTClient) Put() *restclient.Request {
return c.impersonate(c.delegate.Put())
}
func (c impersonatingRESTClient) Patch(pt types.PatchType) *restclient.Request {
return c.impersonate(c.delegate.Patch(pt))
}
func (c impersonatingRESTClient) Get() *restclient.Request {
return c.impersonate(c.delegate.Get())
}
func (c impersonatingRESTClient) Delete() *restclient.Request {
return c.impersonate(c.delegate.Delete())
}
func (c impersonatingRESTClient) APIVersion() schema.GroupVersion {
return c.delegate.APIVersion()
}
func (c impersonatingRESTClient) GetRateLimiter() flowcontrol.RateLimiter {
return c.delegate.GetRateLimiter()
}