Skip to content

Commit 5f7eee3

Browse files
committed
Add github_organization_network_configuration resource
- Implements CRUD operations for GitHub organization network configurations - Supports configuration of network settings for hosted compute (Actions) - Validates name format (alphanumeric, '.', '-', '_') and length (1-100 chars) - Enforces compute_service enum ('none', 'actions') - Requires exactly one network_settings_id - Includes comprehensive test suite with create, update, and import tests - Depends on go-github v77 (merged from PR integrations#2891) Resolves network configuration management for GitHub Actions hosted runners and other hosted compute services at the organization level.
1 parent 06076f2 commit 5f7eee3

File tree

3 files changed

+407
-0
lines changed

3 files changed

+407
-0
lines changed

github/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ func Provider() *schema.Provider {
168168
"github_organization_block": resourceOrganizationBlock(),
169169
"github_organization_custom_role": resourceGithubOrganizationCustomRole(),
170170
"github_organization_custom_properties": resourceGithubOrganizationCustomProperties(),
171+
"github_organization_network_configuration": resourceGithubOrganizationNetworkConfiguration(),
171172
"github_organization_project": resourceGithubOrganizationProject(),
172173
"github_organization_repository_role": resourceGithubOrganizationRepositoryRole(),
173174
"github_organization_role": resourceGithubOrganizationRole(),
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"log"
6+
"net/http"
7+
"regexp"
8+
9+
"github.com/google/go-github/v77/github"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
12+
)
13+
14+
func resourceGithubOrganizationNetworkConfiguration() *schema.Resource {
15+
return &schema.Resource{
16+
Create: resourceGithubOrganizationNetworkConfigurationCreate,
17+
Read: resourceGithubOrganizationNetworkConfigurationRead,
18+
Update: resourceGithubOrganizationNetworkConfigurationUpdate,
19+
Delete: resourceGithubOrganizationNetworkConfigurationDelete,
20+
Importer: &schema.ResourceImporter{
21+
StateContext: schema.ImportStatePassthroughContext,
22+
},
23+
24+
Schema: map[string]*schema.Schema{
25+
"name": {
26+
Type: schema.TypeString,
27+
Required: true,
28+
ValidateFunc: validation.All(
29+
validation.StringLenBetween(1, 100),
30+
validation.StringMatch(
31+
regexp.MustCompile(`^[a-zA-Z0-9._-]+$`),
32+
"name may only contain upper and lowercase letters a-z, numbers 0-9, '.', '-', and '_'",
33+
),
34+
),
35+
Description: "Name of the network configuration. Must be between 1 and 100 characters and may only contain upper and lowercase letters a-z, numbers 0-9, '.', '-', and '_'.",
36+
},
37+
"compute_service": {
38+
Type: schema.TypeString,
39+
Optional: true,
40+
Default: "none",
41+
ValidateFunc: validation.StringInSlice([]string{"none", "actions"}, false),
42+
Description: "The hosted compute service to use for the network configuration. Can be one of: 'none', 'actions'. Defaults to 'none'.",
43+
},
44+
"network_settings_ids": {
45+
Type: schema.TypeList,
46+
Required: true,
47+
MinItems: 1,
48+
MaxItems: 1,
49+
Elem: &schema.Schema{
50+
Type: schema.TypeString,
51+
},
52+
Description: "The identifier of the network settings to use for the network configuration. Exactly one network settings must be specified.",
53+
},
54+
"id": {
55+
Type: schema.TypeString,
56+
Computed: true,
57+
Description: "The network configuration ID.",
58+
},
59+
"created_on": {
60+
Type: schema.TypeString,
61+
Computed: true,
62+
Description: "Timestamp when the network configuration was created.",
63+
},
64+
},
65+
}
66+
}
67+
68+
func resourceGithubOrganizationNetworkConfigurationCreate(d *schema.ResourceData, meta interface{}) error {
69+
err := checkOrganization(meta)
70+
if err != nil {
71+
return err
72+
}
73+
74+
client := meta.(*Owner).v3client
75+
orgName := meta.(*Owner).name
76+
ctx := context.Background()
77+
78+
// Build request
79+
computeService := github.ComputeService(d.Get("compute_service").(string))
80+
81+
networkSettingsIDs := []string{}
82+
for _, id := range d.Get("network_settings_ids").([]interface{}) {
83+
networkSettingsIDs = append(networkSettingsIDs, id.(string))
84+
}
85+
86+
req := github.NetworkConfigurationRequest{
87+
Name: github.String(d.Get("name").(string)),
88+
ComputeService: &computeService,
89+
NetworkSettingsIDs: networkSettingsIDs,
90+
}
91+
92+
log.Printf("[DEBUG] Creating network configuration: %s", d.Get("name").(string))
93+
configuration, _, err := client.Organizations.CreateNetworkConfiguration(ctx, orgName, req)
94+
if err != nil {
95+
return err
96+
}
97+
98+
d.SetId(configuration.GetID())
99+
return resourceGithubOrganizationNetworkConfigurationRead(d, meta)
100+
}
101+
102+
func resourceGithubOrganizationNetworkConfigurationRead(d *schema.ResourceData, meta interface{}) error {
103+
err := checkOrganization(meta)
104+
if err != nil {
105+
return err
106+
}
107+
108+
client := meta.(*Owner).v3client
109+
orgName := meta.(*Owner).name
110+
networkID := d.Id()
111+
ctx := context.WithValue(context.Background(), ctxId, networkID)
112+
113+
log.Printf("[DEBUG] Reading network configuration: %s", networkID)
114+
configuration, resp, err := client.Organizations.GetNetworkConfiguration(ctx, orgName, networkID)
115+
if err != nil {
116+
if ghErr, ok := err.(*github.ErrorResponse); ok {
117+
if ghErr.Response.StatusCode == http.StatusNotFound {
118+
log.Printf("[WARN] Removing network configuration %s from state because it no longer exists in GitHub", networkID)
119+
d.SetId("")
120+
return nil
121+
}
122+
}
123+
return err
124+
}
125+
126+
if resp.StatusCode == http.StatusNotModified {
127+
return nil
128+
}
129+
130+
d.Set("name", configuration.GetName())
131+
if configuration.ComputeService != nil {
132+
d.Set("compute_service", string(*configuration.ComputeService))
133+
}
134+
d.Set("network_settings_ids", configuration.NetworkSettingsIDs)
135+
if configuration.CreatedOn != nil {
136+
d.Set("created_on", configuration.CreatedOn.Format("2006-01-02T15:04:05Z07:00"))
137+
}
138+
139+
return nil
140+
}
141+
142+
func resourceGithubOrganizationNetworkConfigurationUpdate(d *schema.ResourceData, meta interface{}) error {
143+
err := checkOrganization(meta)
144+
if err != nil {
145+
return err
146+
}
147+
148+
client := meta.(*Owner).v3client
149+
orgName := meta.(*Owner).name
150+
networkID := d.Id()
151+
ctx := context.WithValue(context.Background(), ctxId, networkID)
152+
153+
// Build request with changed fields
154+
computeService := github.ComputeService(d.Get("compute_service").(string))
155+
156+
networkSettingsIDs := []string{}
157+
for _, id := range d.Get("network_settings_ids").([]interface{}) {
158+
networkSettingsIDs = append(networkSettingsIDs, id.(string))
159+
}
160+
161+
req := github.NetworkConfigurationRequest{
162+
Name: github.String(d.Get("name").(string)),
163+
ComputeService: &computeService,
164+
NetworkSettingsIDs: networkSettingsIDs,
165+
}
166+
167+
log.Printf("[DEBUG] Updating network configuration: %s", networkID)
168+
_, _, err = client.Organizations.UpdateNetworkConfiguration(ctx, orgName, networkID, req)
169+
if err != nil {
170+
return err
171+
}
172+
173+
return resourceGithubOrganizationNetworkConfigurationRead(d, meta)
174+
}
175+
176+
func resourceGithubOrganizationNetworkConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
177+
err := checkOrganization(meta)
178+
if err != nil {
179+
return err
180+
}
181+
182+
client := meta.(*Owner).v3client
183+
orgName := meta.(*Owner).name
184+
networkID := d.Id()
185+
ctx := context.Background()
186+
187+
log.Printf("[DEBUG] Deleting network configuration: %s", networkID)
188+
_, err = client.Organizations.DeleteNetworkConfigurations(ctx, orgName, networkID)
189+
if err != nil {
190+
if ghErr, ok := err.(*github.ErrorResponse); ok {
191+
if ghErr.Response.StatusCode == http.StatusNotFound {
192+
return nil
193+
}
194+
}
195+
return err
196+
}
197+
198+
return nil
199+
}

0 commit comments

Comments
 (0)