4
4
package vault
5
5
6
6
import (
7
- "encoding/json "
7
+ "context "
8
8
"fmt"
9
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
10
+ "github.com/hashicorp/terraform-provider-vault/internal/consts"
9
11
"log"
10
12
"regexp"
11
13
"strings"
@@ -20,39 +22,44 @@ var (
20
22
databaseSecretBackendStaticRoleNameFromPathRegex = regexp .MustCompile ("^.+/static-roles/(.+$)" )
21
23
)
22
24
25
+ var staticRoleFields = []string {
26
+ consts .FieldRotationPeriod ,
27
+ consts .FieldRotationStatements ,
28
+ consts .FieldDBName ,
29
+ }
30
+
23
31
func databaseSecretBackendStaticRoleResource () * schema.Resource {
24
32
return & schema.Resource {
25
- Create : databaseSecretBackendStaticRoleWrite ,
26
- Read : provider .ReadWrapper (databaseSecretBackendStaticRoleRead ),
27
- Update : databaseSecretBackendStaticRoleWrite ,
28
- Delete : databaseSecretBackendStaticRoleDelete ,
29
- Exists : databaseSecretBackendStaticRoleExists ,
33
+ CreateContext : databaseSecretBackendStaticRoleWrite ,
34
+ ReadContext : provider .ReadContextWrapper (databaseSecretBackendStaticRoleRead ),
35
+ UpdateContext : databaseSecretBackendStaticRoleWrite ,
36
+ DeleteContext : databaseSecretBackendStaticRoleDelete ,
30
37
Importer : & schema.ResourceImporter {
31
- State : schema .ImportStatePassthrough ,
38
+ StateContext : schema .ImportStatePassthroughContext ,
32
39
},
33
40
34
41
Schema : map [string ]* schema.Schema {
35
- "name" : {
42
+ consts . FieldName : {
36
43
Type : schema .TypeString ,
37
44
Required : true ,
38
45
ForceNew : true ,
39
46
Description : "Unique name for the static role." ,
40
47
},
41
- "backend" : {
48
+ consts . FieldBackend : {
42
49
Type : schema .TypeString ,
43
50
Required : true ,
44
51
ForceNew : true ,
45
52
Description : "The path of the Database Secret Backend the role belongs to." ,
46
53
},
47
- "username" : {
54
+ consts . FieldUsername : {
48
55
Type : schema .TypeString ,
49
56
Required : true ,
50
57
ForceNew : true ,
51
58
Description : "The database username that this role corresponds to." ,
52
59
},
53
- "rotation_period" : {
60
+ consts . FieldRotationPeriod : {
54
61
Type : schema .TypeInt ,
55
- Required : true ,
62
+ Optional : true ,
56
63
Description : "The amount of time Vault should wait before rotating the password, in seconds." ,
57
64
ValidateFunc : func (v interface {}, k string ) (ws []string , errs []error ) {
58
65
value := v .(int )
@@ -62,13 +69,24 @@ func databaseSecretBackendStaticRoleResource() *schema.Resource {
62
69
return
63
70
},
64
71
},
65
- "db_name" : {
72
+ consts .FieldRotationSchedule : {
73
+ Type : schema .TypeString ,
74
+ Optional : true ,
75
+ Description : "A cron-style string that will define the schedule on which rotations should occur." ,
76
+ },
77
+ consts .FieldRotationWindow : {
78
+ Type : schema .TypeInt ,
79
+ Optional : true ,
80
+ Description : "The amount of time in seconds in which the rotations are allowed to occur starting " +
81
+ "from a given rotation_schedule." ,
82
+ },
83
+ consts .FieldDBName : {
66
84
Type : schema .TypeString ,
67
85
Required : true ,
68
86
ForceNew : true ,
69
87
Description : "Database connection to use for this role." ,
70
88
},
71
- "rotation_statements" : {
89
+ consts . FieldRotationStatements : {
72
90
Type : schema .TypeList ,
73
91
Optional : true ,
74
92
Elem : & schema.Schema {Type : schema .TypeString },
@@ -78,43 +96,56 @@ func databaseSecretBackendStaticRoleResource() *schema.Resource {
78
96
}
79
97
}
80
98
81
- func databaseSecretBackendStaticRoleWrite (d * schema.ResourceData , meta interface {}) error {
99
+ func databaseSecretBackendStaticRoleWrite (ctx context. Context , d * schema.ResourceData , meta interface {}) diag. Diagnostics {
82
100
client , e := provider .GetClient (d , meta )
83
101
if e != nil {
84
- return e
102
+ return diag . FromErr ( e )
85
103
}
86
104
87
- backend := d .Get ("backend" ).(string )
88
- name := d .Get ("name" ).(string )
105
+ backend := d .Get (consts . FieldBackend ).(string )
106
+ name := d .Get (consts . FieldName ).(string )
89
107
90
108
path := databaseSecretBackendStaticRolePath (backend , name )
91
109
92
110
data := map [string ]interface {}{
93
- "username" : d .Get ("username" ),
94
- "rotation_period" : d .Get ("rotation_period" ),
95
- "db_name" : d .Get ("db_name" ),
111
+ "username" : d .Get (consts .FieldUsername ),
112
+ "db_name" : d .Get (consts .FieldDBName ),
96
113
"rotation_statements" : []string {},
97
114
}
98
115
99
- if v , ok := d .GetOkExists ("rotation_statements" ); ok && v != "" {
100
- data ["rotation_statements" ] = v
116
+ useAPIVer115 := provider .IsAPISupported (meta , provider .VaultVersion115 )
117
+ if useAPIVer115 {
118
+ if v , ok := d .GetOk (consts .FieldRotationSchedule ); ok && v != "" {
119
+ data [consts .FieldRotationSchedule ] = v
120
+ }
121
+ if v , ok := d .GetOk (consts .FieldRotationWindow ); ok && v != "" {
122
+ data [consts .FieldRotationWindow ] = v
123
+ }
124
+ }
125
+
126
+ if v , ok := d .GetOk (consts .FieldRotationStatements ); ok && v != "" {
127
+ data [consts .FieldRotationStatements ] = v
128
+ }
129
+
130
+ if v , ok := d .GetOk (consts .FieldRotationPeriod ); ok && v != "" {
131
+ data [consts .FieldRotationPeriod ] = v
101
132
}
102
133
103
134
log .Printf ("[DEBUG] Creating static role %q on database backend %q" , name , backend )
104
135
_ , err := client .Logical ().Write (path , data )
105
136
if err != nil {
106
- return fmt .Errorf ("error creating static role %q for backend %q: %s" , name , backend , err )
137
+ return diag .Errorf ("error creating static role %q for backend %q: %s" , name , backend , err )
107
138
}
108
139
log .Printf ("[DEBUG] Created static role %q on AWS backend %q" , name , backend )
109
140
110
141
d .SetId (path )
111
- return databaseSecretBackendStaticRoleRead (d , meta )
142
+ return databaseSecretBackendStaticRoleRead (ctx , d , meta )
112
143
}
113
144
114
- func databaseSecretBackendStaticRoleRead (d * schema.ResourceData , meta interface {}) error {
145
+ func databaseSecretBackendStaticRoleRead (ctx context. Context , d * schema.ResourceData , meta interface {}) diag. Diagnostics {
115
146
client , e := provider .GetClient (d , meta )
116
147
if e != nil {
117
- return e
148
+ return diag . FromErr ( e )
118
149
}
119
150
120
151
path := d .Id ()
@@ -123,20 +154,20 @@ func databaseSecretBackendStaticRoleRead(d *schema.ResourceData, meta interface{
123
154
if err != nil {
124
155
log .Printf ("[WARN] Removing database static role %q because its ID is invalid" , path )
125
156
d .SetId ("" )
126
- return fmt .Errorf ("invalid static role ID %q: %s" , path , err )
157
+ return diag .Errorf ("invalid static role ID %q: %s" , path , err )
127
158
}
128
159
129
160
backend , err := databaseSecretBackendStaticRoleBackendFromPath (path )
130
161
if err != nil {
131
162
log .Printf ("[WARN] Removing database static role %q because its ID is invalid" , path )
132
163
d .SetId ("" )
133
- return fmt .Errorf ("invalid static role ID %q: %s" , path , err )
164
+ return diag .Errorf ("invalid static role ID %q: %s" , path , err )
134
165
}
135
166
136
167
log .Printf ("[DEBUG] Reading static role from %q" , path )
137
168
role , err := client .Logical ().Read (path )
138
169
if err != nil {
139
- return fmt .Errorf ("error reading static role %q: %s" , path , err )
170
+ return diag .Errorf ("error reading static role %q: %s" , path , err )
140
171
}
141
172
log .Printf ("[DEBUG] Read static role from %q" , path )
142
173
if role == nil {
@@ -145,67 +176,55 @@ func databaseSecretBackendStaticRoleRead(d *schema.ResourceData, meta interface{
145
176
return nil
146
177
}
147
178
148
- d .Set ("backend" , backend )
149
- d .Set ("name" , name )
150
- d .Set ("username" , role .Data ["username" ])
151
- d .Set ("db_name" , role .Data ["db_name" ])
179
+ if err := d .Set (consts .FieldBackend , backend ); err != nil {
180
+ return diag .FromErr (err )
181
+ }
152
182
153
- if v , ok := role .Data ["rotation_period" ]; ok {
154
- n , err := v .(json.Number ).Int64 ()
155
- if err != nil {
156
- return fmt .Errorf ("unexpected value %q for rotation_period of %q" , v , path )
157
- }
158
- d .Set ("rotation_period" , n )
183
+ if err := d .Set (consts .FieldName , name ); err != nil {
184
+ return diag .FromErr (err )
159
185
}
160
186
161
- var rotation []string
162
- if rotationStr , ok := role .Data ["rotation_statements" ].(string ); ok {
163
- rotation = append (rotation , rotationStr )
164
- } else if rotations , ok := role .Data ["rotation_statements" ].([]interface {}); ok {
165
- for _ , cr := range rotations {
166
- rotation = append (rotation , cr .(string ))
187
+ if err := d .Set (consts .FieldUsername , role .Data [consts .FieldUsername ]); err != nil {
188
+ return diag .FromErr (err )
189
+ }
190
+
191
+ useAPIVer115 := provider .IsAPISupported (meta , provider .VaultVersion115 )
192
+ if useAPIVer115 {
193
+ if err := d .Set (consts .FieldRotationSchedule , role .Data [consts .FieldRotationSchedule ]); err != nil {
194
+ return diag .FromErr (err )
195
+ }
196
+ if err := d .Set (consts .FieldRotationWindow , role .Data [consts .FieldRotationWindow ]); err != nil {
197
+ return diag .FromErr (err )
167
198
}
168
199
}
169
- err = d .Set ("rotation_statements" , rotation )
170
- if err != nil {
171
- return fmt .Errorf ("unexpected value %q for rotation_statements of %s: %s" , rotation , path , err )
200
+
201
+ for _ , k := range staticRoleFields {
202
+ if v , ok := role .Data [k ]; ok {
203
+ if err := d .Set (k , v ); err != nil {
204
+ return diag .FromErr (err )
205
+ }
206
+ }
172
207
}
173
208
174
209
return nil
175
210
}
176
211
177
- func databaseSecretBackendStaticRoleDelete (d * schema.ResourceData , meta interface {}) error {
212
+ func databaseSecretBackendStaticRoleDelete (_ context. Context , d * schema.ResourceData , meta interface {}) diag. Diagnostics {
178
213
client , e := provider .GetClient (d , meta )
179
214
if e != nil {
180
- return e
215
+ return diag . FromErr ( e )
181
216
}
182
217
183
218
path := d .Id ()
184
219
log .Printf ("[DEBUG] Deleting static role %q" , path )
185
220
_ , err := client .Logical ().Delete (path )
186
221
if err != nil {
187
- return fmt .Errorf ("error deleting static role %q: %s" , path , err )
222
+ return diag .Errorf ("error deleting static role %q: %s" , path , err )
188
223
}
189
224
log .Printf ("[DEBUG] Deleted static role %q" , path )
190
225
return nil
191
226
}
192
227
193
- func databaseSecretBackendStaticRoleExists (d * schema.ResourceData , meta interface {}) (bool , error ) {
194
- client , e := provider .GetClient (d , meta )
195
- if e != nil {
196
- return false , e
197
- }
198
-
199
- path := d .Id ()
200
- log .Printf ("[DEBUG] Checking if %q exists" , path )
201
- role , err := client .Logical ().Read (path )
202
- if err != nil {
203
- return true , fmt .Errorf ("error checking if %q exists: %s" , path , err )
204
- }
205
- log .Printf ("[DEBUG] Checked if %q exists" , path )
206
- return role != nil , nil
207
- }
208
-
209
228
func databaseSecretBackendStaticRolePath (backend , name string ) string {
210
229
return strings .Trim (backend , "/" ) + "/static-roles/" + strings .Trim (name , "/" )
211
230
}
0 commit comments