11package jobs
22
33import (
4+ "bytes"
5+ "context"
46 "fmt"
57
68 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -93,7 +95,7 @@ func flattenJobDefinitionCron(cron *jobs.CronSchedule) []any {
9395
9496type JobDefinitionSecret struct {
9597 SecretReferenceID string
96- SecretID string
98+ SecretID regional. ID
9799 SecretVersion string
98100 File string
99101 Environment string
@@ -119,7 +121,7 @@ func expandJobDefinitionSecret(i any) []JobDefinitionSecret {
119121 }
120122
121123 secret := JobDefinitionSecret {
122- SecretID : secretMap ["secret_id" ].(string ),
124+ SecretID : regional . ExpandID ( secretMap ["secret_id" ].(string ) ),
123125 SecretVersion : secretMap ["secret_version" ].(string ),
124126 File : file ,
125127 Environment : env ,
@@ -134,45 +136,132 @@ func expandJobDefinitionSecret(i any) []JobDefinitionSecret {
134136 return parsedSecrets
135137}
136138
137- func CreateJobDefinitionSecret (rawSecretReference any , api * jobs.API , region scw.Region , jobID string ) error {
138- parsedSecretReferences := expandJobDefinitionSecret (rawSecretReference )
139- secrets := []* jobs.CreateJobDefinitionSecretsRequestSecretConfig {}
139+ func flattenJobDefinitionSecret (jobSecrets []* jobs.Secret ) []any {
140+ secretRefs := make ([]interface {}, len (jobSecrets ))
140141
141- for _ , parsedSecretRef := range parsedSecretReferences {
142- var secretConfig * jobs.CreateJobDefinitionSecretsRequestSecretConfig
142+ for i , secret := range jobSecrets {
143+ secretRef := make (map [string ]interface {})
144+ secretRef ["secret_id" ] = secret .SecretManagerID
145+ secretRef ["secret_reference_id" ] = secret .SecretID
146+ secretRef ["secret_version" ] = secret .SecretManagerVersion
143147
144- if parsedSecretRef .Environment != "" {
145- secretConfig = & jobs.CreateJobDefinitionSecretsRequestSecretConfig {
146- SecretManagerID : parsedSecretRef .SecretID ,
147- SecretManagerVersion : parsedSecretRef .SecretVersion ,
148- EnvVarName : & parsedSecretRef .Environment ,
149- }
148+ if secret .File != nil {
149+ secretRef ["file" ] = secret .File .Path
150150 }
151151
152- if parsedSecretRef .File != "" {
153- secretConfig = & jobs.CreateJobDefinitionSecretsRequestSecretConfig {
154- SecretManagerID : parsedSecretRef .SecretID ,
155- SecretManagerVersion : parsedSecretRef .SecretVersion ,
156- Path : & parsedSecretRef .File ,
152+ if secret .EnvVar != nil {
153+ secretRef ["environment" ] = secret .EnvVar .Name
154+ }
155+
156+ secretRefs [i ] = secretRef
157+ }
158+
159+ return secretRefs
160+ }
161+
162+ func CreateJobDefinitionSecret (ctx context.Context , api * jobs.API , jobSecrets []JobDefinitionSecret , region scw.Region , jobID string ) error {
163+ secretConfigs := []* jobs.CreateJobDefinitionSecretsRequestSecretConfig {}
164+
165+ for _ , parsedSecretRef := range jobSecrets {
166+ secretConfig := & jobs.CreateJobDefinitionSecretsRequestSecretConfig {}
167+
168+ secretConfigs = append (secretConfigs , secretConfig )
169+
170+ if parsedSecretRef .SecretID .Region .String () != "" {
171+ if parsedSecretRef .SecretID .Region .String () != region .String () {
172+ return fmt .Errorf ("the secret id %s is in the region %s, expected %s" , parsedSecretRef .SecretID , parsedSecretRef .SecretID .Region , region )
157173 }
158174 }
159175
160- if parsedSecretRef .Environment != "" && parsedSecretRef .File != "" {
161- return fmt .Errorf ("the secret id %s must have exactly one mount point: file or environment" , parsedSecretRef .SecretID )
176+ secretConfig .SecretManagerID = parsedSecretRef .SecretID .ID
177+ secretConfig .SecretManagerVersion = parsedSecretRef .SecretVersion
178+
179+ if err := validateJobDefinitionSecret (& parsedSecretRef ); err != nil {
180+ return err
162181 }
163182
164- if parsedSecretRef .Environment == "" && parsedSecretRef . File = = "" {
165- return fmt . Errorf ( "the secret id %s is missing a mount point: file or environment" , parsedSecretRef .SecretID )
183+ if parsedSecretRef .Environment ! = "" {
184+ secretConfig . EnvVarName = & parsedSecretRef .Environment
166185 }
167186
168- secrets = append (secrets , secretConfig )
187+ if parsedSecretRef .File != "" {
188+ secretConfig .Path = & parsedSecretRef .File
189+ }
169190 }
170191
171192 _ , err := api .CreateJobDefinitionSecrets (& jobs.CreateJobDefinitionSecretsRequest {
172193 Region : region ,
173194 JobDefinitionID : jobID ,
174- Secrets : secrets ,
175- })
195+ Secrets : secretConfigs ,
196+ }, scw . WithContext ( ctx ) )
176197
177198 return err
178199}
200+
201+ func hashJobDefinitionSecret (secret * JobDefinitionSecret ) int {
202+ buf := bytes .NewBufferString (secret .SecretID .String ())
203+ buf .WriteString (secret .SecretVersion )
204+
205+ if secret .Environment != "" {
206+ buf .WriteString (secret .Environment )
207+ }
208+
209+ if secret .File != "" {
210+ buf .WriteString (secret .File )
211+ }
212+
213+ return schema .HashString (buf .String ())
214+ }
215+
216+ func DiffJobDefinitionSecrets (oldSecretRefs , newSecretRefs []JobDefinitionSecret ) (toCreate []JobDefinitionSecret , toDelete []JobDefinitionSecret , err error ) {
217+ toCreate = make ([]JobDefinitionSecret , 0 )
218+ toDelete = make ([]JobDefinitionSecret , 0 )
219+
220+ // hash the new and old secret sets
221+ oldSecretRefsMap := make (map [int ]JobDefinitionSecret , len (oldSecretRefs ))
222+ for _ , secret := range oldSecretRefs {
223+ oldSecretRefsMap [hashJobDefinitionSecret (& secret )] = secret
224+ }
225+
226+ newSecretRefsMap := make (map [int ]JobDefinitionSecret , len (newSecretRefs ))
227+
228+ for _ , secret := range newSecretRefs {
229+ if err := validateJobDefinitionSecret (& secret ); err != nil {
230+ return toCreate , toDelete , err
231+ }
232+
233+ newSecretRefsMap [hashJobDefinitionSecret (& secret )] = secret
234+ }
235+
236+ // filter secrets to delete
237+ for hash , secret := range oldSecretRefsMap {
238+ if _ , ok := newSecretRefsMap [hash ]; ! ok {
239+ toDelete = append (toDelete , secret )
240+ }
241+ }
242+
243+ // filter secrets to create
244+ for hash , secret := range newSecretRefsMap {
245+ if _ , ok := oldSecretRefsMap [hash ]; ! ok {
246+ toCreate = append (toCreate , secret )
247+ }
248+ }
249+
250+ return toCreate , toDelete , nil
251+ }
252+
253+ func validateJobDefinitionSecret (secret * JobDefinitionSecret ) error {
254+ if secret == nil {
255+ return nil
256+ }
257+
258+ if secret .Environment != "" && secret .File != "" {
259+ return fmt .Errorf ("the secret id %s must have exactly one mount point: file or environment" , secret .SecretID )
260+ }
261+
262+ if secret .Environment == "" && secret .File == "" {
263+ return fmt .Errorf ("the secret id %s is missing a mount point: file or environment" , secret .SecretID )
264+ }
265+
266+ return nil
267+ }
0 commit comments