Skip to content

Commit 4e58ce9

Browse files
feat: add enterprise teams resources and data sources
Add support for managing GitHub Enterprise Teams (enterprise-level teams): Resources: - github_enterprise_team: create/update/delete enterprise teams - github_enterprise_team_membership: manage team members - github_enterprise_team_organizations: assign teams to organizations Data sources: - github_enterprise_team: lookup by slug or ID - github_enterprise_teams: list all enterprise teams - github_enterprise_team_membership: check user membership - github_enterprise_team_organizations: list assigned orgs Note: These endpoints require GitHub Enterprise Cloud with a classic PAT that has enterprise admin permissions.
1 parent 972ef3b commit 4e58ce9

19 files changed

Lines changed: 2078 additions & 0 deletions
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strconv"
7+
"strings"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
)
11+
12+
func dataSourceGithubEnterpriseTeam() *schema.Resource {
13+
return &schema.Resource{
14+
Read: dataSourceGithubEnterpriseTeamRead,
15+
16+
Schema: map[string]*schema.Schema{
17+
"enterprise_slug": {
18+
Type: schema.TypeString,
19+
Required: true,
20+
Description: "The slug of the enterprise.",
21+
},
22+
"slug": {
23+
Type: schema.TypeString,
24+
Optional: true,
25+
Computed: true,
26+
ConflictsWith: []string{"team_id"},
27+
Description: "The slug of the enterprise team.",
28+
},
29+
"team_id": {
30+
Type: schema.TypeInt,
31+
Optional: true,
32+
Computed: true,
33+
ConflictsWith: []string{"slug"},
34+
Description: "The numeric ID of the enterprise team.",
35+
},
36+
"name": {
37+
Type: schema.TypeString,
38+
Computed: true,
39+
Description: "The name of the enterprise team.",
40+
},
41+
"description": {
42+
Type: schema.TypeString,
43+
Computed: true,
44+
Description: "A description of the enterprise team.",
45+
},
46+
"organization_selection_type": {
47+
Type: schema.TypeString,
48+
Computed: true,
49+
Description: "Specifies which organizations in the enterprise should have access to this team.",
50+
},
51+
"group_id": {
52+
Type: schema.TypeString,
53+
Computed: true,
54+
Description: "The ID of the IdP group to assign team membership with.",
55+
},
56+
},
57+
}
58+
}
59+
60+
func dataSourceGithubEnterpriseTeamRead(d *schema.ResourceData, meta any) error {
61+
client := meta.(*Owner).v3client
62+
enterpriseSlug := strings.TrimSpace(d.Get("enterprise_slug").(string))
63+
if enterpriseSlug == "" {
64+
return fmt.Errorf("enterprise_slug must not be empty")
65+
}
66+
67+
ctx := context.Background()
68+
69+
var te *enterpriseTeam
70+
if v, ok := d.GetOk("team_id"); ok {
71+
teamID := int64(v.(int))
72+
if teamID != 0 {
73+
found, err := findEnterpriseTeamByID(ctx, client, enterpriseSlug, teamID)
74+
if err != nil {
75+
return err
76+
}
77+
if found == nil {
78+
return fmt.Errorf("could not find enterprise team %d in enterprise %s", teamID, enterpriseSlug)
79+
}
80+
te = found
81+
}
82+
}
83+
84+
if te == nil {
85+
teamSlug := strings.TrimSpace(d.Get("slug").(string))
86+
if teamSlug == "" {
87+
return fmt.Errorf("one of slug or team_id must be set")
88+
}
89+
found, _, err := getEnterpriseTeamBySlug(ctx, client, enterpriseSlug, teamSlug)
90+
if err != nil {
91+
return err
92+
}
93+
te = found
94+
}
95+
96+
d.SetId(buildSlashTwoPartID(enterpriseSlug, strconv.FormatInt(te.ID, 10)))
97+
_ = d.Set("enterprise_slug", enterpriseSlug)
98+
_ = d.Set("slug", te.Slug)
99+
_ = d.Set("team_id", int(te.ID))
100+
_ = d.Set("name", te.Name)
101+
if te.Description != nil {
102+
_ = d.Set("description", *te.Description)
103+
} else {
104+
_ = d.Set("description", "")
105+
}
106+
orgSel := te.OrganizationSelectionType
107+
if orgSel == "" {
108+
orgSel = "disabled"
109+
}
110+
_ = d.Set("organization_selection_type", orgSel)
111+
if te.GroupID != nil {
112+
_ = d.Set("group_id", *te.GroupID)
113+
} else {
114+
_ = d.Set("group_id", "")
115+
}
116+
117+
return nil
118+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
)
10+
11+
func dataSourceGithubEnterpriseTeamMembership() *schema.Resource {
12+
return &schema.Resource{
13+
Read: dataSourceGithubEnterpriseTeamMembershipRead,
14+
15+
Schema: map[string]*schema.Schema{
16+
"enterprise_slug": {
17+
Type: schema.TypeString,
18+
Required: true,
19+
Description: "The slug of the enterprise.",
20+
},
21+
"enterprise_team": {
22+
Type: schema.TypeString,
23+
Required: true,
24+
Description: "The slug or ID of the enterprise team.",
25+
},
26+
"username": {
27+
Type: schema.TypeString,
28+
Required: true,
29+
Description: "The GitHub username.",
30+
},
31+
"role": {
32+
Type: schema.TypeString,
33+
Computed: true,
34+
Description: "The role of the user in the enterprise team, if returned by the API.",
35+
},
36+
"state": {
37+
Type: schema.TypeString,
38+
Computed: true,
39+
Description: "The membership state, if returned by the API.",
40+
},
41+
"etag": {
42+
Type: schema.TypeString,
43+
Computed: true,
44+
Description: "ETag of the membership response.",
45+
},
46+
},
47+
}
48+
}
49+
50+
func dataSourceGithubEnterpriseTeamMembershipRead(d *schema.ResourceData, meta any) error {
51+
client := meta.(*Owner).v3client
52+
enterpriseSlug := strings.TrimSpace(d.Get("enterprise_slug").(string))
53+
enterpriseTeam := strings.TrimSpace(d.Get("enterprise_team").(string))
54+
username := strings.TrimSpace(d.Get("username").(string))
55+
if enterpriseSlug == "" {
56+
return fmt.Errorf("enterprise_slug must not be empty")
57+
}
58+
if enterpriseTeam == "" {
59+
return fmt.Errorf("enterprise_team must not be empty")
60+
}
61+
if username == "" {
62+
return fmt.Errorf("username must not be empty")
63+
}
64+
65+
ctx := context.Background()
66+
m, resp, err := getEnterpriseTeamMembershipDetails(ctx, client, enterpriseSlug, enterpriseTeam, username)
67+
if err != nil {
68+
return err
69+
}
70+
71+
d.SetId(buildSlashThreePartID(enterpriseSlug, enterpriseTeam, username))
72+
_ = d.Set("enterprise_slug", enterpriseSlug)
73+
_ = d.Set("enterprise_team", enterpriseTeam)
74+
_ = d.Set("username", username)
75+
if m != nil {
76+
_ = d.Set("role", m.Role)
77+
_ = d.Set("state", m.State)
78+
}
79+
if resp != nil {
80+
_ = d.Set("etag", resp.Header.Get("ETag"))
81+
}
82+
return nil
83+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
)
10+
11+
func dataSourceGithubEnterpriseTeamOrganizations() *schema.Resource {
12+
return &schema.Resource{
13+
Read: dataSourceGithubEnterpriseTeamOrganizationsRead,
14+
15+
Schema: map[string]*schema.Schema{
16+
"enterprise_slug": {
17+
Type: schema.TypeString,
18+
Required: true,
19+
Description: "The slug of the enterprise.",
20+
},
21+
"enterprise_team": {
22+
Type: schema.TypeString,
23+
Required: true,
24+
Description: "The slug or ID of the enterprise team.",
25+
},
26+
"organization_slugs": {
27+
Type: schema.TypeSet,
28+
Computed: true,
29+
Description: "Set of organization slugs that the enterprise team is assigned to.",
30+
Elem: &schema.Schema{Type: schema.TypeString},
31+
Set: schema.HashString,
32+
},
33+
},
34+
}
35+
}
36+
37+
func dataSourceGithubEnterpriseTeamOrganizationsRead(d *schema.ResourceData, meta any) error {
38+
client := meta.(*Owner).v3client
39+
enterpriseSlug := strings.TrimSpace(d.Get("enterprise_slug").(string))
40+
enterpriseTeam := strings.TrimSpace(d.Get("enterprise_team").(string))
41+
if enterpriseSlug == "" {
42+
return fmt.Errorf("enterprise_slug must not be empty")
43+
}
44+
if enterpriseTeam == "" {
45+
return fmt.Errorf("enterprise_team must not be empty")
46+
}
47+
48+
ctx := context.Background()
49+
orgs, err := listEnterpriseTeamOrganizations(ctx, client, enterpriseSlug, enterpriseTeam)
50+
if err != nil {
51+
return err
52+
}
53+
54+
slugs := make([]string, 0, len(orgs))
55+
for _, org := range orgs {
56+
if org.Login != "" {
57+
slugs = append(slugs, org.Login)
58+
}
59+
}
60+
61+
d.SetId(buildSlashTwoPartID(enterpriseSlug, enterpriseTeam))
62+
_ = d.Set("enterprise_slug", enterpriseSlug)
63+
_ = d.Set("enterprise_team", enterpriseTeam)
64+
_ = d.Set("organization_slugs", slugs)
65+
return nil
66+
}

0 commit comments

Comments
 (0)