-
Notifications
You must be signed in to change notification settings - Fork 5
/
backend.go
134 lines (112 loc) · 3.49 KB
/
backend.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
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package kubesecrets
import (
"context"
"fmt"
"strings"
"sync"
"time"
"github.com/hashicorp/go-secure-stdlib/fileutil"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
)
var (
// jwtReloadPeriod is the time period how often the in-memory copy of local
// service account token can be used, before reading it again from disk.
//
// The value is selected according to recommendation in Kubernetes 1.21 changelog:
// "Clients should reload the token from disk periodically (once per minute
// is recommended) to ensure they continue to use a valid token."
jwtReloadPeriod = 1 * time.Minute
// caReloadPeriod is the time period how often the in-memory copy of local
// CA cert can be used, before reading it again from disk.
caReloadPeriod = 1 * time.Hour
// operationPrefixKubernetes is used as a prefix for OpenAPI operation id's.
operationPrefixKubernetes = "kubernetes"
WALRollbackMinAge = "10m"
)
// backend wraps the backend framework and adds a map for storing key value pairs
type backend struct {
*framework.Backend
lock sync.Mutex
client *client
// localSATokenReader caches the service account token in memory.
// It periodically reloads the token to support token rotation/renewal.
// Local token is used when running in a pod with following configuration
// - token_reviewer_jwt is not set
// - disable_local_ca_jwt is false
localSATokenReader *fileutil.CachingFileReader
// localCACertReader contains the local CA certificate. Local CA certificate is
// used when running in a pod with following configuration
// - kubernetes_ca_cert is not set
// - disable_local_ca_jwt is false
localCACertReader *fileutil.CachingFileReader
}
var _ logical.Factory = Factory
// Factory configures and returns Mock backends
func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) {
b, err := newBackend()
if err != nil {
return nil, err
}
if conf == nil {
return nil, fmt.Errorf("configuration passed into backend is nil")
}
if err := b.Setup(ctx, conf); err != nil {
return nil, err
}
return b, nil
}
func newBackend() (*backend, error) {
b := &backend{
localSATokenReader: fileutil.NewCachingFileReader(localJWTPath, jwtReloadPeriod),
localCACertReader: fileutil.NewCachingFileReader(localCACertPath, caReloadPeriod),
}
walRollbackMinAge, err := time.ParseDuration(WALRollbackMinAge)
if err != nil {
return nil, err
}
b.Backend = &framework.Backend{
BackendType: logical.TypeLogical,
Help: strings.TrimSpace(backendHelp),
Invalidate: b.invalidate,
Paths: framework.PathAppend(
[]*framework.Path{
b.pathConfig(),
b.pathCredentials(),
b.pathCheck(),
},
b.pathRoles(),
),
PathsSpecial: &logical.Paths{
LocalStorage: []string{
framework.WALPrefix,
},
SealWrapStorage: []string{
"config",
},
},
Secrets: []*framework.Secret{
b.kubeServiceAccount(),
},
WALRollback: b.walRollback,
WALRollbackMinAge: walRollbackMinAge,
}
return b, nil
}
// This resets anything that needs to be rebuilt after a change. In our case,
// the k8s client if the config is changed.
func (b *backend) invalidate(_ context.Context, key string) {
if key == "config" {
b.reset()
}
}
func (b *backend) reset() {
b.lock.Lock()
defer b.lock.Unlock()
b.client = nil
}
const backendHelp = `
The Kubernetes Secret Engine generates Kubernetes service account tokens with associated roles and role bindings.
`