-
Notifications
You must be signed in to change notification settings - Fork 961
feat: Adding github_enterprise_ip_allow_list_entry resource #2649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
stevehipwell
merged 35 commits into
integrations:main
from
ErikElkins:feat/enterprise-ip-allow-list
Apr 13, 2026
+442
−15
Merged
Changes from 6 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
943df18
Adding github_enterprise_ip_allow_list_entry resource
ErikElkins eb02154
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins 935e689
Merge branch 'main' into feat/enterprise-ip-allow-list
nickfloyd 83a0055
Update github/resource_github_enterprise_ip_allow_list_entry.go
ErikElkins c3735ac
Update github/resource_github_enterprise_ip_allow_list_entry.go
ErikElkins e1b06a2
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins 833f3f1
Update github/resource_github_enterprise_ip_allow_list_entry.go
ErikElkins 60c686b
Update github/resource_github_enterprise_ip_allow_list_entry_test.go
ErikElkins f667dcc
Update github/resource_github_enterprise_ip_allow_list_entry_test.go
ErikElkins 06b2e43
Code review fixes
ErikElkins f8d8807
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins aed945b
Fixes from code review
ErikElkins a032d9d
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins b076b2a
Fixing code review comments
ErikElkins d5a1915
Update resource_github_enterprise_ip_allow_list_entry.go
ErikElkins 2511b0b
Update resource_github_enterprise_ip_allow_list_entry.go
ErikElkins 4c9ac44
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins d593d56
Update github/resource_github_enterprise_ip_allow_list_entry_test.go
ErikElkins 10de6a7
Update github/resource_github_enterprise_ip_allow_list_entry.go
ErikElkins 4474a4f
Code review changes
ErikElkins 01d61fc
Fixing config in test
ErikElkins 03d79ef
Flattening update test
ErikElkins 4e50668
Adding error handling
ErikElkins 252cfe4
Simplifying import function
ErikElkins 0369b10
Fix docs
ErikElkins 8918bb8
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins 2eb508d
Fixing code review changes
ErikElkins 85b1956
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins 5dd8ef6
Fixing lint
ErikElkins 08aa432
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins c5e2e12
Adding error handling for missing global ID
ErikElkins 43a86af
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins 1c87cc4
Removing two old functions
ErikElkins 1a2c79e
Fixing lint
ErikElkins f1dece8
Merge branch 'main' into feat/enterprise-ip-allow-list
ErikElkins File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
217 changes: 217 additions & 0 deletions
217
github/resource_github_enterprise_ip_allow_list_entry.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,217 @@ | ||
| package github | ||
|
|
||
| import ( | ||
| "context" | ||
| "log" | ||
| "strings" | ||
|
|
||
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
| "github.com/shurcooL/githubv4" | ||
| ) | ||
|
|
||
| func resourceGithubEnterpriseIpAllowListEntry() *schema.Resource { | ||
| return &schema.Resource{ | ||
| CreateContext: resourceGithubEnterpriseIpAllowListEntryCreate, | ||
| ReadContext: resourceGithubEnterpriseIpAllowListEntryRead, | ||
| UpdateContext: resourceGithubEnterpriseIpAllowListEntryUpdate, | ||
| DeleteContext: resourceGithubEnterpriseIpAllowListEntryDelete, | ||
| Importer: &schema.ResourceImporter{ | ||
| StateContext: schema.ImportStatePassthroughContext, | ||
| }, | ||
|
|
||
| Schema: map[string]*schema.Schema{ | ||
|
ErikElkins marked this conversation as resolved.
|
||
| "enterprise_slug": { | ||
| Type: schema.TypeString, | ||
| Required: true, | ||
|
ErikElkins marked this conversation as resolved.
|
||
| Description: "The slug of the enterprise to apply the IP allow list entry to.", | ||
| }, | ||
| "ip": { | ||
| Type: schema.TypeString, | ||
| Required: true, | ||
|
ErikElkins marked this conversation as resolved.
|
||
| Description: "An IP address or range of IP addresses in CIDR notation.", | ||
| }, | ||
|
stevehipwell marked this conversation as resolved.
|
||
| "name": { | ||
| Type: schema.TypeString, | ||
| Optional: true, | ||
| Description: "An optional name for the IP allow list entry.", | ||
| }, | ||
| "is_active": { | ||
| Type: schema.TypeBool, | ||
| Optional: true, | ||
| Default: true, | ||
| Description: "Whether the entry is currently active.", | ||
| }, | ||
|
ErikElkins marked this conversation as resolved.
|
||
| }, | ||
| } | ||
| } | ||
|
|
||
| func resourceGithubEnterpriseIpAllowListEntryCreate(d *schema.ResourceData, meta interface{}) error { | ||
| client := meta.(*Owner).v4client | ||
|
|
||
| // First, get the enterprise ID as we need it for the mutation | ||
| enterpriseSlug := d.Get("enterprise_slug").(string) | ||
| enterpriseID, err := getEnterpriseID(ctx, client, enterpriseSlug) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Then create the IP allow list entry | ||
| var mutation struct { | ||
| CreateIpAllowListEntry struct { | ||
| IpAllowListEntry struct { | ||
| ID githubv4.String | ||
| AllowListValue githubv4.String | ||
| Name githubv4.String | ||
| IsActive githubv4.Boolean | ||
| CreatedAt githubv4.String | ||
| UpdatedAt githubv4.String | ||
| } | ||
| } `graphql:"createIpAllowListEntry(input: $input)"` | ||
| } | ||
|
|
||
| name := d.Get("name").(string) | ||
| input := githubv4.CreateIpAllowListEntryInput{ | ||
| OwnerID: githubv4.ID(enterpriseID), | ||
| AllowListValue: githubv4.String(d.Get("ip").(string)), | ||
| IsActive: githubv4.Boolean(d.Get("is_active").(bool)), | ||
| } | ||
|
|
||
| if name != "" { | ||
| input.Name = githubv4.NewString(githubv4.String(name)) | ||
| } | ||
|
|
||
| err = client.Mutate(ctx, &mutation, input, nil) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| d.SetId(string(mutation.CreateIpAllowListEntry.IpAllowListEntry.ID)) | ||
|
|
||
| return resourceGithubEnterpriseIpAllowListEntryRead(d, meta) | ||
| } | ||
|
|
||
| func resourceGithubEnterpriseIpAllowListEntryRead(d *schema.ResourceData, meta interface{}) error { | ||
| client := meta.(*Owner).v4client | ||
| ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
|
|
||
| var query struct { | ||
| Node struct { | ||
| IpAllowListEntry struct { | ||
| ID githubv4.String | ||
| AllowListValue githubv4.String | ||
| Name githubv4.String | ||
| IsActive githubv4.Boolean | ||
| CreatedAt githubv4.String | ||
| UpdatedAt githubv4.String | ||
| Owner struct { | ||
| Enterprise struct { | ||
| Slug githubv4.String | ||
| } `graphql:"... on Enterprise"` | ||
| } | ||
| } `graphql:"... on IpAllowListEntry"` | ||
| } `graphql:"node(id: $id)"` | ||
| } | ||
|
|
||
| variables := map[string]interface{}{ | ||
| "id": githubv4.ID(d.Id()), | ||
| } | ||
|
|
||
| err := client.Query(ctx, &query, variables) | ||
| if err != nil { | ||
| if strings.Contains(err.Error(), "Could not resolve to a node with the global id") { | ||
| log.Printf("[INFO] Removing IP allow list entry (%s) from state because it no longer exists in GitHub", d.Id()) | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| d.SetId("") | ||
| return nil | ||
| } | ||
| return err | ||
| } | ||
|
|
||
| entry := query.Node.IpAllowListEntry | ||
|
|
||
| d.Set("ip", entry.AllowListValue) | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| d.Set("name", entry.Name) | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| d.Set("is_active", entry.IsActive) | ||
| d.Set("created_at", entry.CreatedAt) | ||
| d.Set("updated_at", entry.UpdatedAt) | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| d.Set("enterprise_slug", entry.Owner.Enterprise.Slug) | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func resourceGithubEnterpriseIpAllowListEntryUpdate(d *schema.ResourceData, meta interface{}) error { | ||
| client := meta.(*Owner).v4client | ||
| ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
|
|
||
| var mutation struct { | ||
| UpdateIpAllowListEntry struct { | ||
| IpAllowListEntry struct { | ||
| ID githubv4.String | ||
| AllowListValue githubv4.String | ||
| Name githubv4.String | ||
| IsActive githubv4.Boolean | ||
| UpdatedAt githubv4.String | ||
| } | ||
| } `graphql:"updateIpAllowListEntry(input: $input)"` | ||
| } | ||
|
|
||
| name := d.Get("name").(string) | ||
| input := githubv4.UpdateIpAllowListEntryInput{ | ||
| IPAllowListEntryID: githubv4.ID(d.Id()), | ||
| AllowListValue: githubv4.String(d.Get("ip").(string)), | ||
| IsActive: githubv4.Boolean(d.Get("is_active").(bool)), | ||
| } | ||
|
|
||
| if name != "" { | ||
| input.Name = githubv4.NewString(githubv4.String(name)) | ||
| } | ||
|
|
||
| err := client.Mutate(ctx, &mutation, input, nil) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| return resourceGithubEnterpriseIpAllowListEntryRead(d, meta) | ||
| } | ||
|
|
||
| func resourceGithubEnterpriseIpAllowListEntryDelete(d *schema.ResourceData, meta interface{}) error { | ||
| client := meta.(*Owner).v4client | ||
| ctx := context.WithValue(context.Background(), ctxId, d.Id()) | ||
|
|
||
| var mutation struct { | ||
| DeleteIpAllowListEntry struct { | ||
| ClientMutationID githubv4.String | ||
| } `graphql:"deleteIpAllowListEntry(input: $input)"` | ||
| } | ||
|
|
||
| input := githubv4.DeleteIpAllowListEntryInput{ | ||
| IPAllowListEntryID: githubv4.ID(d.Id()), | ||
| } | ||
|
|
||
| err := client.Mutate(ctx, &mutation, input, nil) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| d.SetId("") | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| return nil | ||
| } | ||
|
|
||
| // Helper function to get Enterprise ID from slug | ||
| func getEnterpriseID(ctx context.Context, client *githubv4.Client, enterpriseSlug string) (string, error) { | ||
|
ErikElkins marked this conversation as resolved.
Outdated
ErikElkins marked this conversation as resolved.
Outdated
|
||
| var query struct { | ||
| Enterprise struct { | ||
| ID githubv4.ID | ||
| } `graphql:"enterprise(slug: $slug)"` | ||
| } | ||
|
|
||
| variables := map[string]interface{}{ | ||
| "slug": githubv4.String(enterpriseSlug), | ||
| } | ||
|
|
||
| err := client.Query(ctx, &query, variables) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
|
ErikElkins marked this conversation as resolved.
|
||
|
|
||
| return query.Enterprise.ID.(string), nil | ||
| } | ||
101 changes: 101 additions & 0 deletions
101
github/resource_github_enterprise_ip_allow_list_entry_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| package github | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "testing" | ||
|
|
||
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
| ) | ||
|
|
||
| func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| t.Skip("Acceptance test requires a real GitHub Enterprise environment") | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
|
|
||
| resourceName := "github_enterprise_ip_allow_list_entry.test" | ||
| enterpriseSlug := "test-enterprise" | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| ip := "192.168.1.0/24" | ||
| name := "Test Entry" | ||
| isActive := true | ||
|
|
||
| resource.Test(t, resource.TestCase{ | ||
| PreCheck: func() { | ||
| testAccPreCheck(t) | ||
| testAccPreCheckEnterprise(t) | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| }, | ||
| Providers: testAccProviders, | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| Steps: []resource.TestStep{ | ||
| { | ||
| Config: testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, ip, name, isActive), | ||
| Check: resource.ComposeTestCheckFunc( | ||
| resource.TestCheckResourceAttr(resourceName, "enterprise_slug", enterpriseSlug), | ||
| resource.TestCheckResourceAttr(resourceName, "ip", ip), | ||
| resource.TestCheckResourceAttr(resourceName, "name", name), | ||
| resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", isActive)), | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| ), | ||
| }, | ||
| { | ||
| ResourceName: resourceName, | ||
| ImportState: true, | ||
| ImportStateVerify: true, | ||
| }, | ||
| }, | ||
| }) | ||
| } | ||
|
|
||
| func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { | ||
|
stevehipwell marked this conversation as resolved.
Outdated
|
||
| t.Skip("Acceptance test requires a real GitHub Enterprise environment") | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
|
|
||
| resourceName := "github_enterprise_ip_allow_list_entry.test" | ||
| enterpriseSlug := "test-enterprise" | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| ip := "192.168.1.0/24" | ||
| name := "Test Entry" | ||
| isActive := true | ||
|
|
||
| updatedIP := "10.0.0.0/16" | ||
| updatedName := "Updated Entry" | ||
| updatedIsActive := false | ||
|
|
||
| resource.Test(t, resource.TestCase{ | ||
| PreCheck: func() { | ||
| testAccPreCheck(t) | ||
| testAccPreCheckEnterprise(t) | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| }, | ||
| Providers: testAccProviders, | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| Steps: []resource.TestStep{ | ||
| { | ||
| Config: testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, ip, name, isActive), | ||
| Check: resource.ComposeTestCheckFunc( | ||
| resource.TestCheckResourceAttr(resourceName, "enterprise_slug", enterpriseSlug), | ||
| resource.TestCheckResourceAttr(resourceName, "ip", ip), | ||
| resource.TestCheckResourceAttr(resourceName, "name", name), | ||
| resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", isActive)), | ||
| ), | ||
| }, | ||
| { | ||
| Config: testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, updatedIP, updatedName, updatedIsActive), | ||
| Check: resource.ComposeTestCheckFunc( | ||
| resource.TestCheckResourceAttr(resourceName, "enterprise_slug", enterpriseSlug), | ||
| resource.TestCheckResourceAttr(resourceName, "ip", updatedIP), | ||
| resource.TestCheckResourceAttr(resourceName, "name", updatedName), | ||
| resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", updatedIsActive)), | ||
| ), | ||
| }, | ||
| }, | ||
| }) | ||
| } | ||
|
|
||
| func testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, ip, name string, isActive bool) string { | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| return fmt.Sprintf(` | ||
| resource "github_enterprise_ip_allow_list_entry" "test" { | ||
| enterprise_slug = "%s" | ||
| ip = "%s" | ||
| name = "%s" | ||
| is_active = %t | ||
| } | ||
| `, enterpriseSlug, ip, name, isActive) | ||
| } | ||
|
|
||
| func testAccPreCheckEnterprise(t *testing.T) { | ||
|
ErikElkins marked this conversation as resolved.
Outdated
|
||
| if v := testAccProvider.Meta().(*Owner).name; v == "" { | ||
| t.Fatal("The GITHUB_ENTERPRISE_SLUG environment variable must be set for enterprise tests") | ||
| } | ||
| } | ||
38 changes: 38 additions & 0 deletions
38
website/docs/r/enterprise_ip_allow_list_entry.html.markdown
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| --- | ||
| layout: "github" | ||
| page_title: "GitHub: github_enterprise_ip_allow_list_entry" | ||
| description: |- | ||
| Creates and manages IP allow list entries within a GitHub Enterprise | ||
| --- | ||
|
|
||
| # github_enterprise_ip_allow_list_entry | ||
|
|
||
| This resource allows you to create and manage IP allow list entries for a GitHub Enterprise account. IP allow list entries define IP addresses or ranges that are permitted to access private resources in the enterprise. | ||
|
|
||
| ## Example Usage | ||
|
|
||
| ```hcl | ||
| resource "github_enterprise_ip_allow_list_entry" "test" { | ||
| enterprise_slug = "my-enterprise" | ||
| ip = "192.168.1.0/20" | ||
| name = "My IP Range Name" | ||
| is_active = true | ||
| } | ||
| ``` | ||
|
|
||
| ## Argument Reference | ||
|
|
||
| The following arguments are supported: | ||
|
|
||
| * `enterprise_slug` - (Required) The slug of the enterprise. | ||
| * `ip` - (Required) An IP address or range of IP addresses in CIDR notation. | ||
| * `name` - (Optional) A descriptive name for the IP allow list entry. | ||
| * `is_active` - (Optional) Whether the entry is currently active. Default: true. | ||
|
|
||
| ## Import | ||
|
|
||
| This resource can be imported using the ID of the IP allow list entry: | ||
|
|
||
| ```bash | ||
| $ terraform import github_enterprise_ip_allow_list_entry.test IALE_kwHOC1234567890a | ||
| ``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.