-
Notifications
You must be signed in to change notification settings - Fork 216
/
sdk.gen.go
258 lines (215 loc) · 8.4 KB
/
sdk.gen.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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// Code generated by protoc-gen-go-flipt-sdk. DO NOT EDIT.
package sdk
import (
context "context"
flipt "go.flipt.io/flipt/rpc/flipt"
auth "go.flipt.io/flipt/rpc/flipt/auth"
evaluation "go.flipt.io/flipt/rpc/flipt/evaluation"
meta "go.flipt.io/flipt/rpc/flipt/meta"
metadata "google.golang.org/grpc/metadata"
os "os"
sync "sync"
time "time"
)
var _ *time.Time
var _ *os.File
var _ *sync.Mutex
var _ auth.Method
const (
defaultServiceAccountTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
defaultKubernetesExpiryLeeway = 10 * time.Second
)
type Transport interface {
AuthClient() AuthClient
EvaluationClient() evaluation.EvaluationServiceClient
FliptClient() flipt.FliptClient
MetaClient() meta.MetadataServiceClient
}
// ClientTokenProvider is a type which when requested provides a
// client token which can be used to authenticate RPC/API calls
// invoked through the SDK.
// Deprecated: Use ClientAuthenticationProvider instead.
type ClientTokenProvider interface {
ClientToken() (string, error)
}
// WithClientTokenProviders returns an Option which configures
// any supplied SDK with the provided ClientTokenProvider.
// Deprecated: Use WithAuthenticationProvider instead.
func WithClientTokenProvider(p ClientTokenProvider) Option {
return func(s *SDK) {
s.authenticationProvider = authenticationProviderFunc(func(context.Context) (string, error) {
clientToken, err := p.ClientToken()
if err != nil {
return "", err
}
return "Bearer " + string(clientToken), nil
})
}
}
type authenticationProviderFunc func(context.Context) (string, error)
func (f authenticationProviderFunc) Authentication(ctx context.Context) (string, error) {
return f(ctx)
}
// StaticClientTokenProvider is a string which is supplied as a static client token
// on each RPC which requires authentication.
// Deprecated: Use StaticTokenAuthenticationProvider instead.
type StaticClientTokenProvider string
// ClientToken returns the underlying string that is the StaticClientTokenProvider.
// Deprecated: Use StaticTokenAuthenticationProvider instead.
func (p StaticClientTokenProvider) ClientToken() (string, error) {
return string(p), nil
}
// ClientAuthenticationProvider is a type which when requested provides a
// client authentication which can be used to authenticate RPC/API calls
// invoked through the SDK.
type ClientAuthenticationProvider interface {
Authentication(context.Context) (string, error)
}
// SDK is the definition of Flipt's Go SDK.
// It depends on a pluggable transport implementation and exposes
// a consistent API surface area across both transport implementations.
// It also provides consistent client-side instrumentation and authentication
// lifecycle support.
type SDK struct {
transport Transport
authenticationProvider ClientAuthenticationProvider
}
// Option is a functional option which configures the Flipt SDK.
type Option func(*SDK)
// WithAuthenticationProviders returns an Option which configures
// any supplied SDK with the provided ClientAuthenticationProvider.
func WithAuthenticationProvider(p ClientAuthenticationProvider) Option {
return func(s *SDK) {
s.authenticationProvider = p
}
}
// StaticTokenAuthenticationProvider is a string which is supplied as a static client authentication
// on each RPC which requires authentication.
type StaticTokenAuthenticationProvider string
// Authentication returns the underlying string that is the StaticTokenAuthenticationProvider.
func (p StaticTokenAuthenticationProvider) Authentication(context.Context) (string, error) {
return "Bearer " + string(p), nil
}
// JWTAuthenticationProvider is a string which is supplied as a JWT client authentication
// on each RPC which requires authentication.
type JWTAuthenticationProvider string
// Authentication returns the underlying string that is the JWTAuthenticationProvider.
func (p JWTAuthenticationProvider) Authentication(context.Context) (string, error) {
return "JWT " + string(p), nil
}
// KubernetesAuthenticationProvider is an implementation of ClientAuthenticationProvider
// which automatically uses the service account token from the environment and exchanges
// it with Flipt for a client token.
// This provider keeps the client token up to date and refreshes it for a new client
// token before expiry. It re-reads the service account token as Kubernetes can and will refresh
// this token, as it also has its own expiry.
type KubernetesAuthenticationProvider struct {
transport Transport
serviceAccountTokenPath string
leeway time.Duration
mu sync.RWMutex
resp *auth.VerifyServiceAccountResponse
}
// KubernetesAuthenticationProviderOption is a functional option for configuring KubernetesAuthenticationProvider.
type KubernetesAuthenticationProviderOption func(*KubernetesAuthenticationProvider)
// WithKubernetesServiceAccountTokenPath sets the path on the host to locate the kubernetes service account.
// The KubernetesAuthenticationProvider uses the default location set by Kubernetes.
// This option lets you override that if your path happens to differ.
func WithKubernetesServiceAccountTokenPath(p string) KubernetesAuthenticationProviderOption {
return func(kctp *KubernetesAuthenticationProvider) {
kctp.serviceAccountTokenPath = p
}
}
// WithKubernetesExpiryLeeway configures the duration leeway for deciding when to refresh
// the client token. The default is 10 seconds, which ensures that tokens are automatically refreshed
// when their is less that 10 seconds of lifetime left on the previously fetched client token.
func WithKubernetesExpiryLeeway(d time.Duration) KubernetesAuthenticationProviderOption {
return func(kctp *KubernetesAuthenticationProvider) {
kctp.leeway = d
}
}
// NewKubernetesAuthenticationProvider constructs and configures a new KubernetesAuthenticationProvider
// using the provided transport.
func NewKubernetesAuthenticationProvider(transport Transport, opts ...KubernetesAuthenticationProviderOption) *KubernetesAuthenticationProvider {
k := &KubernetesAuthenticationProvider{
transport: transport,
serviceAccountTokenPath: defaultServiceAccountTokenPath,
leeway: defaultKubernetesExpiryLeeway,
}
for _, opt := range opts {
opt(k)
}
return k
}
// Authentication returns the authentication header string to be used for a request
// by the client SDK. It is generated via exchanging the local service account token
// with Flipt for a client token. The token is then formatted appropriately for use
// in the Authentication header as a bearer token.
func (k *KubernetesAuthenticationProvider) Authentication(ctx context.Context) (string, error) {
k.mu.RLock()
resp := k.resp
k.mu.RUnlock()
if resp != nil && time.Now().UTC().Add(k.leeway).Before(resp.Authentication.ExpiresAt.AsTime()) {
return StaticTokenAuthenticationProvider(k.resp.ClientToken).Authentication(ctx)
}
k.mu.Lock()
defer k.mu.Unlock()
saToken, err := os.ReadFile(k.serviceAccountTokenPath)
if err != nil {
return "", err
}
resp, err = k.transport.
AuthClient().
AuthenticationMethodKubernetesServiceClient().
VerifyServiceAccount(ctx, &auth.VerifyServiceAccountRequest{
ServiceAccountToken: string(saToken),
})
if err != nil {
return "", err
}
k.resp = resp
return StaticTokenAuthenticationProvider(k.resp.ClientToken).Authentication(ctx)
}
// New constructs and configures a Flipt SDK instance from
// the provided Transport implementation and options.
func New(t Transport, opts ...Option) SDK {
sdk := SDK{transport: t}
for _, opt := range opts {
opt(&sdk)
}
return sdk
}
func (s SDK) Auth() *Auth {
return &Auth{
transport: s.transport.AuthClient(),
authenticationProvider: s.authenticationProvider,
}
}
func (s SDK) Evaluation() *Evaluation {
return &Evaluation{
transport: s.transport.EvaluationClient(),
authenticationProvider: s.authenticationProvider,
}
}
func (s SDK) Flipt() *Flipt {
return &Flipt{
transport: s.transport.FliptClient(),
authenticationProvider: s.authenticationProvider,
}
}
func (s SDK) Meta() *Meta {
return &Meta{
transport: s.transport.MetaClient(),
authenticationProvider: s.authenticationProvider,
}
}
func authenticate(ctx context.Context, p ClientAuthenticationProvider) (context.Context, error) {
if p != nil {
authentication, err := p.Authentication(ctx)
if err != nil {
return ctx, err
}
ctx = metadata.AppendToOutgoingContext(ctx, "authorization", authentication)
}
return ctx, nil
}