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,109 @@ 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 CreateJobDefinitionSecret (ctx context.Context , api * jobs.API , jobSecrets []JobDefinitionSecret , region scw.Region , jobID string ) error {
140+ secretConfigs := []* jobs.CreateJobDefinitionSecretsRequestSecretConfig {}
140141
141- for _ , parsedSecretRef := range parsedSecretReferences {
142- var secretConfig * jobs.CreateJobDefinitionSecretsRequestSecretConfig
142+ for _ , parsedSecretRef := range jobSecrets {
143+ secretConfig := & jobs.CreateJobDefinitionSecretsRequestSecretConfig {}
143144
144- if parsedSecretRef .Environment != "" {
145- secretConfig = & jobs.CreateJobDefinitionSecretsRequestSecretConfig {
146- SecretManagerID : parsedSecretRef .SecretID ,
147- SecretManagerVersion : parsedSecretRef .SecretVersion ,
148- EnvVarName : & parsedSecretRef .Environment ,
149- }
150- }
145+ secretConfigs = append (secretConfigs , secretConfig )
151146
152- if parsedSecretRef .File != "" {
153- secretConfig = & jobs.CreateJobDefinitionSecretsRequestSecretConfig {
154- SecretManagerID : parsedSecretRef .SecretID ,
155- SecretManagerVersion : parsedSecretRef .SecretVersion ,
156- Path : & parsedSecretRef .File ,
147+ if parsedSecretRef .SecretID .Region .String () != "" {
148+ if parsedSecretRef .SecretID .Region .String () != region .String () {
149+ return fmt .Errorf ("the secret id %s is in the region %s, expected %s" , parsedSecretRef .SecretID , parsedSecretRef .SecretID .Region , region )
157150 }
158151 }
159152
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 )
153+ secretConfig .SecretManagerID = parsedSecretRef .SecretID .ID
154+ secretConfig .SecretManagerVersion = parsedSecretRef .SecretVersion
155+
156+ if err := validateJobDefinitionSecret (& parsedSecretRef ); err != nil {
157+ return err
162158 }
163159
164- if parsedSecretRef .Environment == "" && parsedSecretRef . File = = "" {
165- return fmt . Errorf ( "the secret id %s is missing a mount point: file or environment" , parsedSecretRef .SecretID )
160+ if parsedSecretRef .Environment ! = "" {
161+ secretConfig . EnvVarName = & parsedSecretRef .Environment
166162 }
167163
168- secrets = append (secrets , secretConfig )
164+ if parsedSecretRef .File != "" {
165+ secretConfig .Path = & parsedSecretRef .File
166+ }
169167 }
170168
171169 _ , err := api .CreateJobDefinitionSecrets (& jobs.CreateJobDefinitionSecretsRequest {
172170 Region : region ,
173171 JobDefinitionID : jobID ,
174- Secrets : secrets ,
175- })
172+ Secrets : secretConfigs ,
173+ }, scw . WithContext ( ctx ) )
176174
177175 return err
178176}
177+
178+ func hashJobDefinitionSecret (secret * JobDefinitionSecret ) int {
179+ buf := bytes .NewBufferString (secret .SecretID .String ())
180+ buf .WriteString (secret .SecretVersion )
181+
182+ if secret .Environment != "" {
183+ buf .WriteString (secret .Environment )
184+ }
185+
186+ if secret .File != "" {
187+ buf .WriteString (secret .File )
188+ }
189+
190+ return schema .HashString (buf .String ())
191+ }
192+
193+ func DiffJobDefinitionSecrets (oldSecretRefs , newSecretRefs []JobDefinitionSecret ) (toCreate []JobDefinitionSecret , toDelete []JobDefinitionSecret , err error ) {
194+ toCreate = make ([]JobDefinitionSecret , 0 )
195+ toDelete = make ([]JobDefinitionSecret , 0 )
196+
197+ // hash the new and old secret sets
198+ oldSecretRefsMap := make (map [int ]JobDefinitionSecret , len (oldSecretRefs ))
199+ for _ , secret := range oldSecretRefs {
200+ oldSecretRefsMap [hashJobDefinitionSecret (& secret )] = secret
201+ }
202+
203+ newSecretRefsMap := make (map [int ]JobDefinitionSecret , len (newSecretRefs ))
204+
205+ for _ , secret := range newSecretRefs {
206+ if err := validateJobDefinitionSecret (& secret ); err != nil {
207+ return toCreate , toDelete , err
208+ }
209+
210+ newSecretRefsMap [hashJobDefinitionSecret (& secret )] = secret
211+ }
212+
213+ // filter secrets to delete
214+ for hash , secret := range oldSecretRefsMap {
215+ if _ , ok := newSecretRefsMap [hash ]; ! ok {
216+ toDelete = append (toDelete , secret )
217+ }
218+ }
219+
220+ // filter secrets to create
221+ for hash , secret := range newSecretRefsMap {
222+ if _ , ok := oldSecretRefsMap [hash ]; ! ok {
223+ toCreate = append (toCreate , secret )
224+ }
225+ }
226+
227+ return toCreate , toDelete , nil
228+ }
229+
230+ func validateJobDefinitionSecret (secret * JobDefinitionSecret ) error {
231+ if secret == nil {
232+ return nil
233+ }
234+
235+ if secret .Environment != "" && secret .File != "" {
236+ return fmt .Errorf ("the secret id %s must have exactly one mount point: file or environment" , secret .SecretID )
237+ }
238+
239+ if secret .Environment == "" && secret .File == "" {
240+ return fmt .Errorf ("the secret id %s is missing a mount point: file or environment" , secret .SecretID )
241+ }
242+
243+ return nil
244+ }
0 commit comments