@@ -6,40 +6,19 @@ import (
66 "strconv"
77
88 "github.com/google/go-github/v81/github"
9+ "github.com/hashicorp/terraform-plugin-log/tflog"
10+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
911 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1012)
1113
1214func resourceGithubEMUGroupMapping () * schema.Resource {
1315 return & schema.Resource {
14- Create : resourceGithubEMUGroupMappingCreate ,
15- Read : resourceGithubEMUGroupMappingRead ,
16- Update : resourceGithubEMUGroupMappingUpdate ,
17- Delete : resourceGithubEMUGroupMappingDelete ,
16+ CreateContext : resourceGithubEMUGroupMappingCreateOrUpdate ,
17+ ReadContext : resourceGithubEMUGroupMappingRead ,
18+ UpdateContext : resourceGithubEMUGroupMappingCreateOrUpdate ,
19+ DeleteContext : resourceGithubEMUGroupMappingDelete ,
1820 Importer : & schema.ResourceImporter {
19- State : func (d * schema.ResourceData , meta any ) ([]* schema.ResourceData , error ) {
20- id , err := strconv .Atoi (d .Id ())
21- if err != nil {
22- return nil , err
23- }
24- if err := d .Set ("group_id" , id ); err != nil {
25- return nil , err
26- }
27- ctx := context .WithValue (context .Background (), ctxId , d .Id ())
28- client := meta .(* Owner ).v3client
29- orgName := meta .(* Owner ).name
30- group , _ , err := client .Teams .GetExternalGroup (ctx , orgName , int64 (id ))
31- if err != nil {
32- return nil , err
33- }
34- if len (group .Teams ) != 1 {
35- return nil , fmt .Errorf ("could not get team_slug from %v number of teams" , len (group .Teams ))
36- }
37- if err := d .Set ("team_slug" , group .Teams [0 ].TeamName ); err != nil {
38- return nil , err
39- }
40- d .SetId (fmt .Sprintf ("teams/%s/external-groups" , d .Id ()))
41- return []* schema.ResourceData {d }, nil
42- },
21+ StateContext : resourceGithubEMUGroupMappingImport ,
4322 },
4423 Schema : map [string ]* schema.Schema {
4524 "team_slug" : {
@@ -60,110 +39,188 @@ func resourceGithubEMUGroupMapping() *schema.Resource {
6039 }
6140}
6241
63- func resourceGithubEMUGroupMappingCreate (d * schema.ResourceData , meta any ) error {
64- return resourceGithubEMUGroupMappingUpdate (d , meta )
65- }
42+ func resourceGithubEMUGroupMappingRead (ctx context.Context , d * schema.ResourceData , meta any ) diag.Diagnostics {
43+ tflog .Trace (ctx , "Reading EMU group mapping" , map [string ]any {
44+ "resource_id" : d .Id (),
45+ })
6646
67- func resourceGithubEMUGroupMappingRead (d * schema.ResourceData , meta any ) error {
6847 err := checkOrganization (meta )
6948 if err != nil {
70- return err
49+ return diag . FromErr ( err )
7150 }
7251 client := meta .(* Owner ).v3client
7352 orgName := meta .(* Owner ).name
7453
7554 id , ok := d .GetOk ("group_id" )
7655 if ! ok {
77- return fmt .Errorf ("could not get group id from provided value" )
56+ return diag .Errorf ("could not get group id from provided value" )
7857 }
7958 id64 , err := getInt64FromInterface (id )
8059 if err != nil {
81- return err
60+ return diag . FromErr ( err )
8261 }
8362
84- ctx := context .WithValue (context .Background (), ctxId , d .Id ())
63+ tflog .Debug (ctx , "Querying external group from GitHub API" , map [string ]any {
64+ "org_name" : orgName ,
65+ "group_id" : id64 ,
66+ })
8567
8668 group , resp , err := client .Teams .GetExternalGroup (ctx , orgName , id64 )
8769 if err != nil {
8870 if resp != nil && resp .StatusCode == 404 {
8971 // If the group is not found, remove it from state
72+ tflog .Info (ctx , "Removing EMU group mapping from state because it no longer exists in GitHub" , map [string ]any {
73+ "org_name" : orgName ,
74+ "group_id" : id64 ,
75+ "resource_id" : d .Id (),
76+ "status_code" : resp .StatusCode ,
77+ })
9078 d .SetId ("" )
9179 return nil
9280 }
93- return err
81+ return diag . FromErr ( err )
9482 }
9583
84+ tflog .Debug (ctx , "Successfully retrieved external group from GitHub API" , map [string ]any {
85+ "org_name" : orgName ,
86+ "group_id" : id64 ,
87+ "team_count" : len (group .Teams ),
88+ })
89+
9690 if len (group .Teams ) < 1 {
9791 // if there's not a team linked, that means it was removed outside of terraform
9892 // and we should remove it from our state
93+ tflog .Info (ctx , "Removing EMU group mapping from state because no teams are linked" , map [string ]any {
94+ "org_name" : orgName ,
95+ "group_id" : id64 ,
96+ "resource_id" : d .Id (),
97+ })
9998 d .SetId ("" )
10099 return nil
101100 }
102101
103- if err = d .Set ("etag" , resp .Header .Get ("ETag" )); err != nil {
104- return err
102+ etag := resp .Header .Get ("ETag" )
103+ tflog .Trace (ctx , "Setting state attribute: etag" , map [string ]any {
104+ "etag" : etag ,
105+ })
106+ if err = d .Set ("etag" , etag ); err != nil {
107+ return diag .FromErr (err )
105108 }
106- if err = d .Set ("group_id" , int (* group .GroupID )); err != nil {
107- return err
109+
110+ groupIDInt := int (group .GetGroupID ())
111+ tflog .Trace (ctx , "Setting state attribute: group_id" , map [string ]any {
112+ "group_id" : groupIDInt ,
113+ })
114+ if err = d .Set ("group_id" , groupIDInt ); err != nil {
115+ return diag .FromErr (err )
108116 }
109117 return nil
110118}
111119
112- func resourceGithubEMUGroupMappingUpdate (d * schema.ResourceData , meta any ) error {
120+ func resourceGithubEMUGroupMappingCreateOrUpdate (ctx context.Context , d * schema.ResourceData , meta any ) diag.Diagnostics {
121+ resourceID := d .Id ()
122+ tflog .Trace (ctx , "Creating or updating EMU group mapping" , map [string ]any {
123+ "resource_id" : resourceID ,
124+ })
125+
113126 err := checkOrganization (meta )
114127 if err != nil {
115- return err
128+ return diag . FromErr ( err )
116129 }
117130 client := meta .(* Owner ).v3client
118131 orgName := meta .(* Owner ).name
119- ctx := context .WithValue (context .Background (), ctxId , d .Id ())
120132
121133 teamSlug , ok := d .GetOk ("team_slug" )
122134 if ! ok {
123- return fmt .Errorf ("could not get team slug from provided value" )
135+ return diag .Errorf ("could not get team slug from provided value" )
124136 }
125137
126138 id , ok := d .GetOk ("group_id" )
127139 if ! ok {
128- return fmt .Errorf ("could not get group id from provided value" )
140+ return diag .Errorf ("could not get group id from provided value" )
129141 }
130142 id64 , err := getInt64FromInterface (id )
131143 if err != nil {
132- return err
144+ return diag . FromErr ( err )
133145 }
134146
147+ teamSlugStr := teamSlug .(string )
148+
135149 eg := & github.ExternalGroup {
136150 GroupID : & id64 ,
137151 }
138152
139- _ , _ , err = client .Teams .UpdateConnectedExternalGroup (ctx , orgName , teamSlug .(string ), eg )
153+ tflog .Debug (ctx , "Updating connected external group via GitHub API" , map [string ]any {
154+ "org_name" : orgName ,
155+ "team_slug" : teamSlugStr ,
156+ "group_id" : id64 ,
157+ })
158+
159+ _ , resp , err := client .Teams .UpdateConnectedExternalGroup (ctx , orgName , teamSlugStr , eg )
140160 if err != nil {
141- return err
161+ return diag . FromErr ( err )
142162 }
143163
144- d .SetId (fmt .Sprintf ("teams/%s/external-groups" , teamSlug ))
145- return resourceGithubEMUGroupMappingRead (d , meta )
164+ tflog .Debug (ctx , "Successfully updated connected external group" , map [string ]any {
165+ "org_name" : orgName ,
166+ "team_slug" : teamSlugStr ,
167+ "group_id" : id64 ,
168+ })
169+
170+ newResourceID := fmt .Sprintf ("teams/%s/external-groups" , teamSlugStr )
171+ tflog .Trace (ctx , "Setting resource ID" , map [string ]any {
172+ "resource_id" : newResourceID ,
173+ })
174+ d .SetId (newResourceID )
175+
176+ etag := resp .Header .Get ("ETag" )
177+ tflog .Trace (ctx , "Setting state attribute: etag" , map [string ]any {
178+ "etag" : etag ,
179+ })
180+ if err = d .Set ("etag" , etag ); err != nil {
181+ return diag .FromErr (err )
182+ }
183+
184+ tflog .Trace (ctx , "Resource created or updated successfully" , map [string ]any {
185+ "resource_id" : newResourceID ,
186+ })
187+ return nil
146188}
147189
148- func resourceGithubEMUGroupMappingDelete (d * schema.ResourceData , meta any ) error {
190+ func resourceGithubEMUGroupMappingDelete (ctx context.Context , d * schema.ResourceData , meta any ) diag.Diagnostics {
191+ tflog .Trace (ctx , "Deleting EMU group mapping" , map [string ]any {
192+ "resource_id" : d .Id (),
193+ })
194+
149195 err := checkOrganization (meta )
150196 if err != nil {
151- return err
197+ return diag . FromErr ( err )
152198 }
153199 client := meta .(* Owner ).v3client
154200 orgName := meta .(* Owner ).name
155201
156202 teamSlug , ok := d .GetOk ("team_slug" )
157203 if ! ok {
158- return fmt .Errorf ("could not parse team slug from provided value" )
204+ return diag .Errorf ("could not parse team slug from provided value" )
159205 }
160206
161- ctx := context .WithValue (context .Background (), ctxId , d .Id ())
207+ teamSlugStr := teamSlug .(string )
208+ tflog .Debug (ctx , "Removing connected external group from team via GitHub API" , map [string ]any {
209+ "org_name" : orgName ,
210+ "team_slug" : teamSlugStr ,
211+ "resource_id" : d .Id (),
212+ })
162213
163- _ , err = client .Teams .RemoveConnectedExternalGroup (ctx , orgName , teamSlug .( string ) )
214+ _ , err = client .Teams .RemoveConnectedExternalGroup (ctx , orgName , teamSlugStr )
164215 if err != nil {
165- return err
216+ return diag . FromErr ( err )
166217 }
218+
219+ tflog .Debug (ctx , "Successfully removed connected external group from team" , map [string ]any {
220+ "org_name" : orgName ,
221+ "team_slug" : teamSlugStr ,
222+ "resource_id" : d .Id (),
223+ })
167224 return nil
168225}
169226
@@ -185,3 +242,41 @@ func getInt64FromInterface(val any) (int64, error) {
185242 }
186243 return id64 , nil
187244}
245+
246+ func resourceGithubEMUGroupMappingImport (ctx context.Context , d * schema.ResourceData , meta any ) ([]* schema.ResourceData , error ) {
247+ importID := d .Id ()
248+ tflog .Trace (ctx , "Importing EMU group mapping with two-part ID" , map [string ]any {
249+ "import_id" : importID ,
250+ "strategy" : "two_part_id" ,
251+ })
252+
253+ groupIDString , teamSlug , err := parseTwoPartID (d .Id (), "group_id" , "team_slug" )
254+ if err != nil {
255+ return nil , err
256+ }
257+ groupID , err := strconv .Atoi (groupIDString )
258+ if err != nil {
259+ return nil , err
260+ }
261+
262+ tflog .Debug (ctx , "Parsed two-part import ID" , map [string ]any {
263+ "import_id" : importID ,
264+ "group_id" : groupID ,
265+ "team_slug" : teamSlug ,
266+ })
267+
268+ if err := d .Set ("group_id" , groupID ); err != nil {
269+ return nil , err
270+ }
271+
272+ if err := d .Set ("team_slug" , teamSlug ); err != nil {
273+ return nil , err
274+ }
275+
276+ resourceID := fmt .Sprintf ("teams/%s/external-groups" , teamSlug )
277+ tflog .Trace (ctx , "Setting resource ID" , map [string ]any {
278+ "resource_id" : resourceID ,
279+ })
280+ d .SetId (resourceID )
281+ return []* schema.ResourceData {d }, nil
282+ }
0 commit comments