@@ -72,17 +72,23 @@ type metadataItem struct {
72
72
IsNull bool `mapstructure:"is_null"`
73
73
}
74
74
75
- // ConvertResourcesAndParameters consumes Terraform state and a GraphViz representation
75
+ type ConvertedState struct {
76
+ Resources []* proto.Resource
77
+ Parameters []* proto.RichParameter
78
+ GitAuthProviders []string
79
+ }
80
+
81
+ // ConvertState consumes Terraform state and a GraphViz representation
76
82
// produced by `terraform graph` to produce resources consumable by Coder.
77
83
// nolint:gocyclo
78
- func ConvertResourcesAndParameters (modules []* tfjson.StateModule , rawGraph string ) ([] * proto. Resource , [] * proto. RichParameter , error ) {
84
+ func ConvertState (modules []* tfjson.StateModule , rawGraph string ) (* ConvertedState , error ) {
79
85
parsedGraph , err := gographviz .ParseString (rawGraph )
80
86
if err != nil {
81
- return nil , nil , xerrors .Errorf ("parse graph: %w" , err )
87
+ return nil , xerrors .Errorf ("parse graph: %w" , err )
82
88
}
83
89
graph , err := gographviz .NewAnalysedGraph (parsedGraph )
84
90
if err != nil {
85
- return nil , nil , xerrors .Errorf ("analyze graph: %w" , err )
91
+ return nil , xerrors .Errorf ("analyze graph: %w" , err )
86
92
}
87
93
88
94
resources := make ([]* proto.Resource , 0 )
@@ -118,11 +124,11 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
118
124
var attrs agentAttributes
119
125
err = mapstructure .Decode (tfResource .AttributeValues , & attrs )
120
126
if err != nil {
121
- return nil , nil , xerrors .Errorf ("decode agent attributes: %w" , err )
127
+ return nil , xerrors .Errorf ("decode agent attributes: %w" , err )
122
128
}
123
129
124
130
if _ , ok := agentNames [tfResource .Name ]; ok {
125
- return nil , nil , xerrors .Errorf ("duplicate agent name: %s" , tfResource .Name )
131
+ return nil , xerrors .Errorf ("duplicate agent name: %s" , tfResource .Name )
126
132
}
127
133
agentNames [tfResource .Name ] = struct {}{}
128
134
@@ -171,7 +177,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
171
177
break
172
178
}
173
179
if agentNode == nil {
174
- return nil , nil , xerrors .Errorf ("couldn't find node on graph: %q" , agentLabel )
180
+ return nil , xerrors .Errorf ("couldn't find node on graph: %q" , agentLabel )
175
181
}
176
182
177
183
var agentResource * graphResource
@@ -260,7 +266,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
260
266
var attrs agentAppAttributes
261
267
err = mapstructure .Decode (resource .AttributeValues , & attrs )
262
268
if err != nil {
263
- return nil , nil , xerrors .Errorf ("decode app attributes: %w" , err )
269
+ return nil , xerrors .Errorf ("decode app attributes: %w" , err )
264
270
}
265
271
266
272
// Default to the resource name if none is set!
@@ -277,11 +283,11 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
277
283
}
278
284
279
285
if ! provisioner .AppSlugRegex .MatchString (attrs .Slug ) {
280
- return nil , nil , xerrors .Errorf ("invalid app slug %q, please update your coder/coder provider to the latest version and specify the slug property on each coder_app" , attrs .Slug )
286
+ return nil , xerrors .Errorf ("invalid app slug %q, please update your coder/coder provider to the latest version and specify the slug property on each coder_app" , attrs .Slug )
281
287
}
282
288
283
289
if _ , exists := appSlugs [attrs .Slug ]; exists {
284
- return nil , nil , xerrors .Errorf ("duplicate app slug, they must be unique per template: %q" , attrs .Slug )
290
+ return nil , xerrors .Errorf ("duplicate app slug, they must be unique per template: %q" , attrs .Slug )
285
291
}
286
292
appSlugs [attrs .Slug ] = struct {}{}
287
293
@@ -341,7 +347,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
341
347
var attrs metadataAttributes
342
348
err = mapstructure .Decode (resource .AttributeValues , & attrs )
343
349
if err != nil {
344
- return nil , nil , xerrors .Errorf ("decode metadata attributes: %w" , err )
350
+ return nil , xerrors .Errorf ("decode metadata attributes: %w" , err )
345
351
}
346
352
347
353
resourceLabel := convertAddressToLabel (resource .Address )
@@ -432,7 +438,7 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
432
438
var param provider.Parameter
433
439
err = mapstructure .Decode (resource .AttributeValues , & param )
434
440
if err != nil {
435
- return nil , nil , xerrors .Errorf ("decode map values for coder_parameter.%s: %w" , resource .Name , err )
441
+ return nil , xerrors .Errorf ("decode map values for coder_parameter.%s: %w" , resource .Name , err )
436
442
}
437
443
protoParam := & proto.RichParameter {
438
444
Name : param .Name ,
@@ -464,7 +470,31 @@ func ConvertResourcesAndParameters(modules []*tfjson.StateModule, rawGraph strin
464
470
}
465
471
}
466
472
467
- return resources , parameters , nil
473
+ // A map is used to ensure we don't have duplicates!
474
+ gitAuthProvidersMap := map [string ]struct {}{}
475
+ for _ , tfResources := range tfResourcesByLabel {
476
+ for _ , resource := range tfResources {
477
+ //
478
+ if resource .Type != "coder_git_auth" {
479
+ continue
480
+ }
481
+ id , ok := resource .AttributeValues ["id" ].(string )
482
+ if ! ok {
483
+ return nil , xerrors .Errorf ("git auth id is not a string" )
484
+ }
485
+ gitAuthProvidersMap [id ] = struct {}{}
486
+ }
487
+ }
488
+ gitAuthProviders := make ([]string , 0 , len (gitAuthProvidersMap ))
489
+ for id := range gitAuthProvidersMap {
490
+ gitAuthProviders = append (gitAuthProviders , id )
491
+ }
492
+
493
+ return & ConvertedState {
494
+ Resources : resources ,
495
+ Parameters : parameters ,
496
+ GitAuthProviders : gitAuthProviders ,
497
+ }, nil
468
498
}
469
499
470
500
// convertAddressToLabel returns the Terraform address without the count
0 commit comments