-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpath_config.go
145 lines (125 loc) · 3.91 KB
/
path_config.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
package exoscale
import (
"context"
"fmt"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
egoscale "github.com/exoscale/egoscale/v2"
)
const (
configStoragePath = "config"
configKeyAPIEnvironment = "api_environment"
configKeyAPIKey = "api_key"
configKeyAPISecret = "api_secret"
configKeyAppRoleMode = "approle_mode"
configKeyZone = "zone"
defaultAPIEnvironment = "api"
)
var (
pathConfigHelpSyn = "Configure the Exoscale auth backend plugin"
pathConfigHelpDesc = `
This endpoint manages the configuration of the root Exoscale auth backend
plugin, including the Exoscale API credentials enabling it to authenticate
Vault clients using this authentication method.
`
)
func pathConfig(b *exoscaleBackend) *framework.Path {
p := &framework.Path{
Pattern: "config",
Fields: map[string]*framework.FieldSchema{
configKeyAPIEnvironment: {
Type: framework.TypeString,
Description: "Exoscale API environment",
Default: defaultAPIEnvironment,
},
configKeyAPIKey: {
Type: framework.TypeString,
Description: "Exoscale API key",
Required: true,
DisplayAttrs: &framework.DisplayAttributes{Sensitive: true},
},
configKeyAPISecret: {
Type: framework.TypeString,
Description: "Exoscale API secret",
Required: true,
DisplayAttrs: &framework.DisplayAttributes{Sensitive: true},
},
configKeyAppRoleMode: {
Type: framework.TypeBool,
Default: false,
Description: "Run in AppRole-compatible mode",
},
configKeyZone: {
Type: framework.TypeString,
Description: "Exoscale zone",
Required: true,
},
},
Operations: map[logical.Operation]framework.OperationHandler{
logical.CreateOperation: &framework.PathOperation{Callback: b.pathConfigWrite},
logical.UpdateOperation: &framework.PathOperation{Callback: b.pathConfigWrite},
logical.ReadOperation: &framework.PathOperation{Callback: b.pathConfigRead},
},
HelpSynopsis: pathConfigHelpSyn,
HelpDescription: pathConfigHelpDesc,
}
return p
}
func (b *exoscaleBackend) pathConfigRead(
ctx context.Context,
req *logical.Request,
_ *framework.FieldData,
) (*logical.Response, error) {
config, err := b.config(ctx, req.Storage)
if err != nil {
return nil, err
} else if config == nil {
return nil, nil
}
d := map[string]interface{}{
configKeyAPIEnvironment: config.APIEnvironment,
configKeyAPIKey: config.APIKey,
configKeyAPISecret: config.APISecret,
configKeyAppRoleMode: config.AppRoleMode,
configKeyZone: config.Zone,
}
return &logical.Response{
Data: d,
}, nil
}
func (b *exoscaleBackend) pathConfigWrite(
ctx context.Context,
req *logical.Request,
data *framework.FieldData,
) (*logical.Response, error) {
config := backendConfig{
APIEnvironment: data.Get(configKeyAPIEnvironment).(string),
APIKey: data.Get(configKeyAPIKey).(string),
APISecret: data.Get(configKeyAPISecret).(string),
AppRoleMode: data.Get(configKeyAppRoleMode).(bool),
Zone: data.Get(configKeyZone).(string),
}
entry, err := logical.StorageEntryJSON(configStoragePath, config)
if err != nil {
return nil, err
}
if err := req.Storage.Put(ctx, entry); err != nil {
return nil, err
}
exo, err := egoscale.NewClient(config.APIKey, config.APISecret)
if err != nil {
return nil, fmt.Errorf("unable to initialize Exoscale client: %w", err)
}
b.exo = exo
res := &logical.Response{}
res.AddWarning("Read access to this endpoint should be controlled via ACLs as " +
"it will return sensitive information as-is, including the backend plugin API credentials")
return res, nil
}
type backendConfig struct {
APIEnvironment string `json:"api_environment"`
APIKey string `json:"api_key"`
APISecret string `json:"api_secret"`
AppRoleMode bool `json:"approle_mode"`
Zone string `json:"zone"`
}