@@ -11,11 +11,15 @@ import (
11
11
"github.com/splunk/vault-plugin-splunk/clients/splunk"
12
12
)
13
13
14
+ const (
15
+ SEARCHHEAD = "search_head"
16
+ INDEXER = "indexer"
17
+ )
14
18
func (b * backend ) pathCredsCreate () * framework.Path {
15
19
return & framework.Path {
16
20
Pattern : "creds/" + framework .GenericNameRegex ("name" ),
17
21
Fields : map [string ]* framework.FieldSchema {
18
- "name" : & framework. FieldSchema {
22
+ "name" : {
19
23
Type : framework .TypeString ,
20
24
Description : "Name of the role" ,
21
25
},
@@ -30,7 +34,30 @@ func (b *backend) pathCredsCreate() *framework.Path {
30
34
}
31
35
}
32
36
33
- func (b * backend ) credsReadHandler (ctx context.Context , req * logical.Request , d * framework.FieldData ) (* logical.Response , error ) {
37
+ func (b * backend ) pathCredsCreateMulti () * framework.Path {
38
+ return & framework.Path {
39
+ Pattern : "creds/" + framework .GenericNameRegex ("name" ) + "/" + framework .GenericNameRegex ("node_fqdn" ),
40
+ Fields : map [string ]* framework.FieldSchema {
41
+ "name" : {
42
+ Type : framework .TypeString ,
43
+ Description : "Name of the role" ,
44
+ },
45
+ "node_fqdn" : {
46
+ Type : framework .TypeString ,
47
+ Description : "FQDN for the Splunk Stack node" ,
48
+ },
49
+ },
50
+
51
+ Callbacks : map [logical.Operation ]framework.OperationFunc {
52
+ logical .ReadOperation : b .credsReadHandler ,
53
+ },
54
+
55
+ HelpSynopsis : pathCredsCreateHelpSyn ,
56
+ HelpDescription : pathCredsCreateHelpDesc ,
57
+ }
58
+ }
59
+
60
+ func (b * backend ) credsReadHandlerStandalone (ctx context.Context , req * logical.Request , d * framework.FieldData ) (* logical.Response , error ) {
34
61
name := d .Get ("name" ).(string )
35
62
role , err := roleConfigLoad (ctx , req .Storage , name )
36
63
if err != nil {
@@ -100,6 +127,122 @@ func (b *backend) credsReadHandler(ctx context.Context, req *logical.Request, d
100
127
return resp , nil
101
128
}
102
129
130
+ func findNode (nodeFQDN string , hosts []splunk.ServerInfoEntry ) (bool , error ) {
131
+ for _ , host := range hosts {
132
+ // check if node_fqdn is in either of HostFQDN or Host. User might not always the FQDN on the cli input
133
+ if host .Content .HostFQDN == nodeFQDN || host .Content .Host == nodeFQDN {
134
+ // Return true if the requested node is a search head
135
+ for _ , role := range host .Content .Roles {
136
+ if role == SEARCHHEAD {
137
+ return true , nil
138
+ }
139
+ }
140
+ return false , fmt .Errorf ("host: %s isn't search head; creating ephemeral creds is only supported for search heads" , nodeFQDN )
141
+ }
142
+ }
143
+ return false , fmt .Errorf ("host: %s not found" , nodeFQDN )
144
+ }
145
+
146
+ func (b * backend ) credsReadHandlerMulti (ctx context.Context , req * logical.Request , d * framework.FieldData ) (* logical.Response , error ) {
147
+ name := d .Get ("name" ).(string )
148
+ node , _ := d .GetOk ("node_fqdn" )
149
+ nodeFQDN := node .(string )
150
+ role , err := roleConfigLoad (ctx , req .Storage , name )
151
+ if err != nil {
152
+ return nil , err
153
+ }
154
+ if role == nil {
155
+ return logical .ErrorResponse (fmt .Sprintf ("role not found: %q" , name )), nil
156
+ }
157
+
158
+ config , err := connectionConfigLoad (ctx , req .Storage , role .Connection )
159
+ if err != nil {
160
+ return nil , err
161
+ }
162
+ // Check if isStandalone is set
163
+ if config .IsStandalone {
164
+ return nil , fmt .Errorf ("expected is_standalone to be set for connection: %q" , role .Connection )
165
+ }
166
+
167
+ // If role name isn't in allowed roles, send back a permission denied.
168
+ if ! strutil .StrListContains (config .AllowedRoles , "*" ) && ! strutil .StrListContainsGlob (config .AllowedRoles , name ) {
169
+ return nil , fmt .Errorf ("%q is not an allowed role for connection %q" , name , role .Connection )
170
+ }
171
+
172
+ conn , err := b .ensureConnection (ctx , role .Connection , config )
173
+ if err != nil {
174
+ return nil , err
175
+ }
176
+
177
+ nodes , _ , err := conn .Deployment .GetSearchPeers ()
178
+ if err != nil {
179
+ b .Logger ().Error ("Error while reading SearchPeers from cluster master" , err )
180
+ return nil , fmt .Errorf ("unable to read searchpeers from cluster master" )
181
+ }
182
+ _ , err = findNode (nodeFQDN , nodes )
183
+ if err != nil {
184
+ return nil , err
185
+ }
186
+
187
+ /*
188
+ // Generate credentials
189
+ userUUID, err := uuid.GenerateUUID()
190
+ if err != nil {
191
+ return nil, err
192
+ }
193
+ userPrefix := role.UserPrefix
194
+ if role.UserPrefix == defaultUserPrefix {
195
+ userPrefix = fmt.Sprintf("%s_%s", role.UserPrefix, req.DisplayName)
196
+ }
197
+ username := fmt.Sprintf("%s_%s", userPrefix, userUUID)
198
+ passwd, err := uuid.GenerateUUID()
199
+ if err != nil {
200
+ return nil, errwrap.Wrapf("error generating new password {{err}}", err)
201
+ }
202
+ opts := splunk.CreateUserOptions{
203
+ Name: username,
204
+ Password: passwd,
205
+ Roles: role.Roles,
206
+ DefaultApp: role.DefaultApp,
207
+ Email: role.Email,
208
+ TZ: role.TZ,
209
+ }
210
+ if _, _, err := conn.AccessControl.Authentication.Users.Create(&opts); err != nil {
211
+ return nil, err
212
+ }
213
+
214
+ resp := b.Secret(secretCredsType).Response(map[string]interface{}{
215
+ // return to user
216
+ "username": username,
217
+ "password": passwd,
218
+ "roles": role.Roles,
219
+ "connection": role.Connection,
220
+ "url": conn.Params().BaseURL,
221
+ }, map[string]interface{}{
222
+ // store (with lease)
223
+ "username": username,
224
+ "role": name,
225
+ "connection": role.Connection,
226
+ })
227
+ resp.Secret.TTL = role.DefaultTTL
228
+ resp.Secret.MaxTTL = role.MaxTTL
229
+
230
+ return resp, nil
231
+ */
232
+ return nil , fmt .Errorf ("XXX" )
233
+ }
234
+ func (b * backend ) credsReadHandler (ctx context.Context , req * logical.Request , d * framework.FieldData ) (* logical.Response , error ) {
235
+ name := d .Get ("name" ).(string )
236
+ node_fqdn , present := d .GetOk ("node_fqdn" )
237
+ // if node_fqdn is specified then the treat the request for a multi-node deployment
238
+ if present {
239
+ b .Logger ().Debug (fmt .Sprintf ("node_fqdn: [%s] specified for role: [%s]. using clustered mode getting temporary creds" , node_fqdn .(string ), name ))
240
+ return b .credsReadHandlerMulti (ctx , req , d )
241
+ }
242
+ b .Logger ().Debug (fmt .Sprintf ("node_fqdn not specified for role: [%s]. using standalone mode getting temporary creds" , name ))
243
+ return b .credsReadHandlerStandalone (ctx , req , d )
244
+ }
245
+
103
246
const pathCredsCreateHelpSyn = `
104
247
Request Splunk credentials for a certain role.
105
248
`
0 commit comments