-
Notifications
You must be signed in to change notification settings - Fork 21
/
backend.go
141 lines (116 loc) · 3.18 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
135
136
137
138
139
140
141
package artifactory
import (
"context"
"crypto/tls"
"fmt"
"net/http"
"strings"
"sync"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/template"
"github.com/hashicorp/vault/sdk/logical"
)
var Version = "v1.0.0"
var productId = "vault-plugin-secrets-artifactory/" + Version[1:] // don't need the 'v' prefix in productId
type backend struct {
*framework.Backend
configMutex sync.RWMutex
rolesMutex sync.RWMutex
httpClient *http.Client
usernameProducer template.StringTemplate
}
// UsernameMetadata defines the metadata that a user_template can use to dynamically create user account in Artifactory
type UsernameMetadata struct {
DisplayName string
RoleName string
}
// Factory configures and returns Artifactory secrets backends.
func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) {
if conf == nil {
return nil, fmt.Errorf("configuration passed into backend is nil")
}
b, err := Backend(conf)
if err != nil {
return nil, err
}
if err := b.Backend.Setup(ctx, conf); err != nil {
return nil, err
}
return b, nil
}
func Backend(_ *logical.BackendConfig) (*backend, error) {
b := &backend{}
up, err := testUsernameTemplate(defaultUserNameTemplate)
if err != nil {
return nil, err
}
b.usernameProducer = up
b.Backend = &framework.Backend{
Help: strings.TrimSpace(artifactoryHelp),
RunningVersion: Version,
PathsSpecial: &logical.Paths{
SealWrapStorage: []string{configAdminPath},
},
BackendType: logical.TypeLogical,
InitializeFunc: b.initialize,
Invalidate: b.invalidate,
}
b.Backend.Secrets = append(b.Backend.Secrets, b.secretAccessToken())
b.Backend.Paths = append(b.Backend.Paths,
b.pathListRoles(),
b.pathRoles(),
b.pathTokenCreate(),
b.pathUserTokenCreate(),
b.pathConfig(),
b.pathConfigRotate(),
b.pathConfigUserToken())
return b, nil
}
// initialize will initialize the backend configuration
func (b *backend) initialize(ctx context.Context, req *logical.InitializationRequest) error {
config, err := b.fetchAdminConfiguration(ctx, req.Storage)
if err != nil {
return err
}
if config == nil {
return nil
}
b.InitializeHttpClient(config)
if len(config.UsernameTemplate) != 0 {
up, err := testUsernameTemplate(config.UsernameTemplate)
if err != nil {
return err
}
b.usernameProducer = up
}
return nil
}
func (b *backend) InitializeHttpClient(config *adminConfiguration) {
if config.BypassArtifactoryTLSVerification {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: config.BypassArtifactoryTLSVerification,
},
}
b.httpClient = &http.Client{Transport: tr}
} else {
b.httpClient = http.DefaultClient
}
}
// invalidate clears an existing client configuration in
// the backend
func (b *backend) invalidate(ctx context.Context, key string) {
if key == "config" {
b.reset()
}
}
// reset clears any client configuration for a new
// backend to be configured
func (b *backend) reset() {
b.configMutex.Lock()
defer b.configMutex.Unlock()
b.httpClient = nil
}
const artifactoryHelp = `
The Artifactory secrets backend provides Artifactory access tokens based on configured roles.
`