@@ -13,6 +13,7 @@ import (
1313 "go/ast"
1414 "go/parser"
1515 "go/token"
16+ "maps"
1617 "os"
1718 "path"
1819 "path/filepath"
@@ -124,7 +125,8 @@ func main() {
124125 "inc" : func (i int ) int {
125126 return i + 1
126127 },
127- "NewVersion" : version .NewVersion ,
128+ "NewVersion" : version .NewVersion ,
129+ "VersionDecrementMinor" : common .VersionDecrementMinor ,
128130 }
129131 templates := template .New ("identitytests" ).Funcs (templateFuncMap )
130132
@@ -205,13 +207,15 @@ func main() {
205207 g .Fatalf ("parsing config template: %s" , err )
206208 }
207209
208- common := commonConfig {
210+ commonConfig := commonConfig {
209211 AdditionalTfVars : additionalTfVars ,
210212 RequiredEnvVars : resource .RequiredEnvVars ,
211213 WithRName : (resource .Generator != "" ),
212214 }
213215
214- generateTestConfig (g , testDirPath , "basic" , tfTemplates , common )
216+ generateTestConfig (g , testDirPath , "basic" , tfTemplates , commonConfig )
217+
218+ var versions []* version.Version
215219
216220 if resource .PreIdentityVersion != nil {
217221 if resource .PreIdentityVersion .Equal (v5_100_0 ) {
@@ -234,33 +238,39 @@ func main() {
234238 g .Fatalf ("parsing config template %q: %s" , configTmplV5Path , err )
235239 }
236240 }
237- commonV5 := common
238- commonV5 .ExternalProviders = map [string ]requiredProvider {
241+ commonConfigV5 := commonConfig
242+ commonConfigV5 .ExternalProviders = map [string ]requiredProvider {
239243 "aws" : {
240244 Source : "hashicorp/aws" ,
241245 Version : "5.100.0" ,
242246 },
243247 }
244- generateTestConfig (g , testDirPath , "basic_v5.100.0" , tfTemplatesV5 , commonV5 )
248+ generateTestConfig (g , testDirPath , "basic_v5.100.0" , tfTemplatesV5 , commonConfigV5 )
245249
246- commonV6 := common
247- commonV6 .ExternalProviders = map [string ]requiredProvider {
248- "aws" : {
249- Source : "hashicorp/aws" ,
250- Version : "6.0.0" ,
251- },
252- }
253- generateTestConfig (g , testDirPath , "basic_v6.0.0" , tfTemplates , commonV6 )
250+ versions = append (versions , version .Must (version .NewVersion ("6.0.0" )))
254251 } else {
255- commonPreIdentity := common
256- commonPreIdentity .ExternalProviders = map [string ]requiredProvider {
257- "aws" : {
258- Source : "hashicorp/aws" ,
259- Version : resource .PreIdentityVersion .String (),
260- },
261- }
262- generateTestConfig (g , testDirPath , fmt .Sprintf ("basic_v%s" , resource .PreIdentityVersion .String ()), tfTemplates , commonPreIdentity )
252+ versions = append (versions , resource .PreIdentityVersion )
253+ }
254+ }
255+
256+ if len (resource .IdentityVersions ) > 1 {
257+ v := resource .IdentityVersions [1 ]
258+ v , err := common .VersionDecrementMinor (v )
259+ if err != nil {
260+ g .Fatalf ("generating versioned configurations: %s" , err )
263261 }
262+ versions = append (versions , v )
263+ }
264+
265+ for _ , version := range versions {
266+ common := commonConfig
267+ common .ExternalProviders = map [string ]requiredProvider {
268+ "aws" : {
269+ Source : "hashicorp/aws" ,
270+ Version : version .String (),
271+ },
272+ }
273+ generateTestConfig (g , testDirPath , fmt .Sprintf ("basic_v%s" , version .String ()), tfTemplates , common )
264274 }
265275
266276 _ , err = tfTemplates .New ("region" ).Parse ("\n region = var.region\n " )
@@ -269,9 +279,9 @@ func main() {
269279 }
270280
271281 if resource .GenerateRegionOverrideTest () {
272- common .WithRegion = true
282+ commonConfig .WithRegion = true
273283
274- generateTestConfig (g , testDirPath , "region_override" , tfTemplates , common )
284+ generateTestConfig (g , testDirPath , "region_override" , tfTemplates , commonConfig )
275285 }
276286 }
277287 }
@@ -364,26 +374,29 @@ const (
364374)
365375
366376type ResourceDatum struct {
367- service * serviceRecords
368- FileName string
369- idAttrDuplicates string // TODO: Remove. Still needed for Parameterized Identity
370- GenerateConfig bool
371- ARNFormat string
372- arnAttribute string
373- isARNFormatGlobal triBoolean
374- ArnIdentity bool
375- MutableIdentity bool
376- IsGlobal bool
377- isSingleton bool
378- HasRegionOverrideTest bool
379- identityAttributes []identityAttribute
380- identityAttribute string
381- IdentityDuplicateAttrs []string
382- IDAttrFormat string
383- HasV6_0NullValuesError bool
384- HasV6_0RefreshError bool
385- HasNoPreExistingResource bool
386- PreIdentityVersion * version.Version
377+ service * serviceRecords
378+ FileName string
379+ idAttrDuplicates string // TODO: Remove. Still needed for Parameterized Identity
380+ GenerateConfig bool
381+ ARNFormat string
382+ arnAttribute string
383+ isARNFormatGlobal triBoolean
384+ ArnIdentity bool
385+ MutableIdentity bool
386+ IsGlobal bool
387+ isSingleton bool
388+ HasRegionOverrideTest bool
389+ identityAttributes []identityAttribute
390+ identityAttribute string
391+ IdentityDuplicateAttrs []string
392+ IDAttrFormat string
393+ HasV6_0NullValuesError bool
394+ HasV6_0RefreshError bool
395+ HasNoPreExistingResource bool
396+ PreIdentityVersion * version.Version
397+ IsCustomInherentRegionIdentity bool
398+ customIdentityAttribute string
399+ IdentityVersions map [int64 ]* version.Version
387400 tests.CommonArgs
388401}
389402
@@ -436,7 +449,7 @@ func (d ResourceDatum) GenerateRegionOverrideTest() bool {
436449}
437450
438451func (d ResourceDatum ) HasInherentRegion () bool {
439- return d .IsARNIdentity () || d .IsRegionalSingleton ()
452+ return d .IsARNIdentity () || d .IsRegionalSingleton () || d . IsCustomInherentRegionIdentity
440453}
441454
442455func (d ResourceDatum ) IdentityAttribute () string {
@@ -455,6 +468,17 @@ func (r ResourceDatum) IdentityAttributes() []identityAttribute {
455468 return r .identityAttributes
456469}
457470
471+ func (r ResourceDatum ) CustomIdentityAttribute () string {
472+ return namesgen .ConstOrQuote (r .customIdentityAttribute )
473+ }
474+
475+ func (r ResourceDatum ) LatestIdentityVersion () int64 {
476+ if len (r .IdentityVersions ) == 0 {
477+ return 0
478+ }
479+ return slices .Max (slices .Collect (maps .Keys (r .IdentityVersions )))
480+ }
481+
458482type identityAttribute struct {
459483 name string
460484 Optional bool
@@ -552,6 +576,7 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) {
552576 CommonArgs : tests .InitCommonArgs (),
553577 IsGlobal : false ,
554578 HasRegionOverrideTest : true ,
579+ IdentityVersions : make (map [int64 ]* version.Version , 0 ),
555580 }
556581 hasIdentity := false
557582 skip := false
@@ -719,6 +744,27 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) {
719744 }
720745 }
721746
747+ case "CustomInherentRegionIdentity" :
748+ hasIdentity = true
749+ d .IsCustomInherentRegionIdentity = true
750+
751+ args := common .ParseArgs (m [3 ])
752+ d .customIdentityAttribute = args .Positional [0 ]
753+ d .identityAttribute = args .Positional [0 ]
754+
755+ var attrs []string
756+ if attr , ok := args .Keyword ["identityDuplicateAttributes" ]; ok {
757+ attrs = strings .Split (attr , ";" )
758+ }
759+ if d .Implementation == tests .ImplementationSDK {
760+ attrs = append (attrs , "id" )
761+ }
762+ slices .Sort (attrs )
763+ attrs = slices .Compact (attrs )
764+ d .IdentityDuplicateAttrs = tfslices .ApplyToAll (attrs , func (s string ) string {
765+ return namesgen .ConstOrQuote (s )
766+ })
767+
722768 case "Testing" :
723769 args := common .ParseArgs (m [3 ])
724770
@@ -812,6 +858,26 @@ func (v *visitor) processFuncDecl(funcDecl *ast.FuncDecl) {
812858 if attr , ok := args .Keyword ["tlsKeyDomain" ]; ok {
813859 tlsKeyCN = attr
814860 }
861+ if attr , ok := args .Keyword ["identityVersion" ]; ok {
862+ parts := strings .Split (attr , ";" )
863+ if len (parts ) != 2 {
864+ v .errs = append (v .errs , fmt .Errorf ("invalid identityVersion value: %q at %s. Should be in format <identity version>;<provider version>." , attr , fmt .Sprintf ("%s.%s" , v .packageName , v .functionName )))
865+ continue
866+ }
867+ var identityVersion int64
868+ if i , err := strconv .ParseInt (parts [0 ], 10 , 64 ); err != nil {
869+ v .errs = append (v .errs , fmt .Errorf ("invalid identity version value: %q at %s. Should be integer value." , parts [0 ], fmt .Sprintf ("%s.%s" , v .packageName , v .functionName )))
870+ continue
871+ } else {
872+ identityVersion = i
873+ }
874+ providerVersion , err := version .NewVersion (parts [1 ])
875+ if err != nil {
876+ v .errs = append (v .errs , fmt .Errorf ("invalid provider version value: %q at %s. Should be version value." , parts [1 ], fmt .Sprintf ("%s.%s" , v .packageName , v .functionName )))
877+ continue
878+ }
879+ d .IdentityVersions [identityVersion ] = providerVersion
880+ }
815881 }
816882 }
817883 }
0 commit comments