From 943df18b09da024d5deece11651a9a1acbf08a4c Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Fri, 2 May 2025 09:02:47 -0500 Subject: [PATCH 01/22] Adding github_enterprise_ip_allow_list_entry resource --- github/provider.go | 1 + ...e_github_enterprise_ip_allow_list_entry.go | 218 ++++++++++++++++++ ...hub_enterprise_ip_allow_list_entry_test.go | 101 ++++++++ ...terprise_ip_allow_list_entry.html.markdown | 38 +++ 4 files changed, 358 insertions(+) create mode 100644 github/resource_github_enterprise_ip_allow_list_entry.go create mode 100644 github/resource_github_enterprise_ip_allow_list_entry_test.go create mode 100644 website/docs/r/enterprise_ip_allow_list_entry.html.markdown diff --git a/github/provider.go b/github/provider.go index 8f44c95098..49f0d541eb 100644 --- a/github/provider.go +++ b/github/provider.go @@ -195,6 +195,7 @@ func Provider() *schema.Provider { "github_user_ssh_key": resourceGithubUserSshKey(), "github_enterprise_organization": resourceGithubEnterpriseOrganization(), "github_enterprise_actions_runner_group": resourceGithubActionsEnterpriseRunnerGroup(), + "github_enterprise_ip_allow_list_entry": resourceGithubEnterpriseIpAllowListEntry(), }, DataSourcesMap: map[string]*schema.Resource{ diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go new file mode 100644 index 0000000000..65ebb98373 --- /dev/null +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -0,0 +1,218 @@ +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{ + Create: resourceGithubEnterpriseIpAllowListEntryCreate, + Read: resourceGithubEnterpriseIpAllowListEntryRead, + Update: resourceGithubEnterpriseIpAllowListEntryUpdate, + Delete: resourceGithubEnterpriseIpAllowListEntryDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "enterprise_slug": { + Type: schema.TypeString, + Required: true, + Description: "The slug of the enterprise to apply the IP allow list entry to.", + }, + "ip": { + Type: schema.TypeString, + Required: true, + Description: "An IP address or range of IP addresses in CIDR notation.", + }, + "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.", + }, + }, + } +} + +func resourceGithubEnterpriseIpAllowListEntryCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Owner).v4client + ctx := context.WithValue(context.Background(), ctxId, d.Id()) + + // 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()) + d.SetId("") + return nil + } + return err + } + + entry := query.Node.IpAllowListEntry + + d.Set("ip", entry.AllowListValue) + d.Set("name", entry.Name) + d.Set("is_active", entry.IsActive) + d.Set("created_at", entry.CreatedAt) + d.Set("updated_at", entry.UpdatedAt) + d.Set("enterprise_slug", entry.Owner.Enterprise.Slug) + + 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("") + return nil +} + +// Helper function to get Enterprise ID from slug +func getEnterpriseID(ctx context.Context, client *githubv4.Client, enterpriseSlug string) (string, error) { + 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 + } + + return query.Enterprise.ID.(string), nil +} diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go new file mode 100644 index 0000000000..59ff1f15db --- /dev/null +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -0,0 +1,101 @@ +package github + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { + t.Skip("Acceptance test requires a real GitHub Enterprise environment") + + resourceName := "github_enterprise_ip_allow_list_entry.test" + enterpriseSlug := "test-enterprise" + ip := "192.168.1.0/24" + name := "Test Entry" + isActive := true + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckEnterprise(t) + }, + Providers: testAccProviders, + 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)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { + t.Skip("Acceptance test requires a real GitHub Enterprise environment") + + resourceName := "github_enterprise_ip_allow_list_entry.test" + enterpriseSlug := "test-enterprise" + 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) + }, + Providers: testAccProviders, + 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 { + 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) { + if v := testAccProvider.Meta().(*Owner).name; v == "" { + t.Fatal("The GITHUB_ENTERPRISE_SLUG environment variable must be set for enterprise tests") + } +} diff --git a/website/docs/r/enterprise_ip_allow_list_entry.html.markdown b/website/docs/r/enterprise_ip_allow_list_entry.html.markdown new file mode 100644 index 0000000000..45817dffba --- /dev/null +++ b/website/docs/r/enterprise_ip_allow_list_entry.html.markdown @@ -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 +``` \ No newline at end of file From 83a0055fe3052701a0af2383d4a81f8f7364aeef Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Tue, 13 Jan 2026 14:29:01 -0600 Subject: [PATCH 02/22] Update github/resource_github_enterprise_ip_allow_list_entry.go Co-authored-by: Steve Hipwell --- github/resource_github_enterprise_ip_allow_list_entry.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 65ebb98373..0e230c3575 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -11,10 +11,10 @@ import ( func resourceGithubEnterpriseIpAllowListEntry() *schema.Resource { return &schema.Resource{ - Create: resourceGithubEnterpriseIpAllowListEntryCreate, - Read: resourceGithubEnterpriseIpAllowListEntryRead, - Update: resourceGithubEnterpriseIpAllowListEntryUpdate, - Delete: resourceGithubEnterpriseIpAllowListEntryDelete, + CreateContext: resourceGithubEnterpriseIpAllowListEntryCreate, + ReadContext: resourceGithubEnterpriseIpAllowListEntryRead, + UpdateContext: resourceGithubEnterpriseIpAllowListEntryUpdate, + DeleteContext: resourceGithubEnterpriseIpAllowListEntryDelete, Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, From c3735acd37f9590781264f6e2bbb151bc06e6ea7 Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Tue, 13 Jan 2026 14:29:20 -0600 Subject: [PATCH 03/22] Update github/resource_github_enterprise_ip_allow_list_entry.go Co-authored-by: Steve Hipwell --- github/resource_github_enterprise_ip_allow_list_entry.go | 1 - 1 file changed, 1 deletion(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 0e230c3575..45a70ace3e 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -47,7 +47,6 @@ func resourceGithubEnterpriseIpAllowListEntry() *schema.Resource { func resourceGithubEnterpriseIpAllowListEntryCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*Owner).v4client - ctx := context.WithValue(context.Background(), ctxId, d.Id()) // First, get the enterprise ID as we need it for the mutation enterpriseSlug := d.Get("enterprise_slug").(string) From 833f3f1510d8c7db3a1e82442635b7e711909355 Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Tue, 13 Jan 2026 14:52:46 -0600 Subject: [PATCH 04/22] Update github/resource_github_enterprise_ip_allow_list_entry.go Co-authored-by: gateixeira <4645845+gateixeira@users.noreply.github.com> --- .../resource_github_enterprise_ip_allow_list_entry.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 45a70ace3e..9ee5c479df 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -41,6 +41,16 @@ func resourceGithubEnterpriseIpAllowListEntry() *schema.Resource { Default: true, Description: "Whether the entry is currently active.", }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "Timestamp of when the entry was created.", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "Timestamp of when the entry was last updated.", + }, }, } } From 60c686beaaff662063ce5eaed4f3c6b6748c5bef Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Tue, 13 Jan 2026 14:52:56 -0600 Subject: [PATCH 05/22] Update github/resource_github_enterprise_ip_allow_list_entry_test.go Co-authored-by: gateixeira <4645845+gateixeira@users.noreply.github.com> --- github/resource_github_enterprise_ip_allow_list_entry_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index 59ff1f15db..8a8dcf80d1 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -18,8 +18,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckEnterprise(t) + skipUnlessEnterprise(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ From f667dcc3a32dbc9ff69332010e146db600f091bf Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Tue, 13 Jan 2026 14:53:12 -0600 Subject: [PATCH 06/22] Update github/resource_github_enterprise_ip_allow_list_entry_test.go Co-authored-by: gateixeira <4645845+gateixeira@users.noreply.github.com> --- github/resource_github_enterprise_ip_allow_list_entry_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index 8a8dcf80d1..e530ed7217 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -55,8 +55,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckEnterprise(t) + skipUnlessEnterprise(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ From 06b2e43d4498ab84e3f629a2dd4678d8c4a42054 Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Tue, 13 Jan 2026 15:31:09 -0600 Subject: [PATCH 07/22] Code review fixes --- ...e_github_enterprise_ip_allow_list_entry.go | 26 +++++++++---------- ...hub_enterprise_ip_allow_list_entry_test.go | 10 ++----- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 9ee5c479df..035e27a957 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -5,6 +5,7 @@ import ( "log" "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/shurcooL/githubv4" ) @@ -55,14 +56,14 @@ func resourceGithubEnterpriseIpAllowListEntry() *schema.Resource { } } -func resourceGithubEnterpriseIpAllowListEntryCreate(d *schema.ResourceData, meta interface{}) error { +func resourceGithubEnterpriseIpAllowListEntryCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { 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 + return diag.FromErr(err) } // Then create the IP allow list entry @@ -92,17 +93,16 @@ func resourceGithubEnterpriseIpAllowListEntryCreate(d *schema.ResourceData, meta err = client.Mutate(ctx, &mutation, input, nil) if err != nil { - return err + return diag.FromErr(err) } d.SetId(string(mutation.CreateIpAllowListEntry.IpAllowListEntry.ID)) - return resourceGithubEnterpriseIpAllowListEntryRead(d, meta) + return resourceGithubEnterpriseIpAllowListEntryRead(ctx, d, meta) } -func resourceGithubEnterpriseIpAllowListEntryRead(d *schema.ResourceData, meta interface{}) error { +func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*Owner).v4client - ctx := context.WithValue(context.Background(), ctxId, d.Id()) var query struct { Node struct { @@ -133,7 +133,7 @@ func resourceGithubEnterpriseIpAllowListEntryRead(d *schema.ResourceData, meta i d.SetId("") return nil } - return err + return diag.FromErr(err) } entry := query.Node.IpAllowListEntry @@ -148,9 +148,8 @@ func resourceGithubEnterpriseIpAllowListEntryRead(d *schema.ResourceData, meta i return nil } -func resourceGithubEnterpriseIpAllowListEntryUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceGithubEnterpriseIpAllowListEntryUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*Owner).v4client - ctx := context.WithValue(context.Background(), ctxId, d.Id()) var mutation struct { UpdateIpAllowListEntry struct { @@ -177,15 +176,14 @@ func resourceGithubEnterpriseIpAllowListEntryUpdate(d *schema.ResourceData, meta err := client.Mutate(ctx, &mutation, input, nil) if err != nil { - return err + return diag.FromErr(err) } - return resourceGithubEnterpriseIpAllowListEntryRead(d, meta) + return resourceGithubEnterpriseIpAllowListEntryRead(ctx, d, meta) } -func resourceGithubEnterpriseIpAllowListEntryDelete(d *schema.ResourceData, meta interface{}) error { +func resourceGithubEnterpriseIpAllowListEntryDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { client := meta.(*Owner).v4client - ctx := context.WithValue(context.Background(), ctxId, d.Id()) var mutation struct { DeleteIpAllowListEntry struct { @@ -199,7 +197,7 @@ func resourceGithubEnterpriseIpAllowListEntryDelete(d *schema.ResourceData, meta err := client.Mutate(ctx, &mutation, input, nil) if err != nil { - return err + return diag.FromErr(err) } d.SetId("") diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index e530ed7217..91117c70ca 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -18,7 +18,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { - skipUnlessEnterprise(t) + skipUnlessEnterprise(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ @@ -55,7 +55,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { - skipUnlessEnterprise(t) + skipUnlessEnterprise(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ @@ -91,9 +91,3 @@ resource "github_enterprise_ip_allow_list_entry" "test" { } `, enterpriseSlug, ip, name, isActive) } - -func testAccPreCheckEnterprise(t *testing.T) { - if v := testAccProvider.Meta().(*Owner).name; v == "" { - t.Fatal("The GITHUB_ENTERPRISE_SLUG environment variable must be set for enterprise tests") - } -} From aed945b4efcd35849988a0c7b8dd6f98fc2e6169 Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Sat, 24 Jan 2026 08:14:57 -0600 Subject: [PATCH 08/22] Fixes from code review --- ...e_github_enterprise_ip_allow_list_entry.go | 31 +++++-------------- ...hub_enterprise_ip_allow_list_entry_test.go | 11 +++---- ...resource_github_enterprise_organization.go | 16 +--------- github/util_v4.go | 21 +++++++++++++ 4 files changed, 33 insertions(+), 46 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 035e27a957..b1ab39baef 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -2,9 +2,9 @@ package github import ( "context" - "log" "strings" + "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/shurcooL/githubv4" @@ -12,6 +12,7 @@ import ( func resourceGithubEnterpriseIpAllowListEntry() *schema.Resource { return &schema.Resource{ + Description: "Manage a GitHub Enterprise IP Allow List Entry.", CreateContext: resourceGithubEnterpriseIpAllowListEntryCreate, ReadContext: resourceGithubEnterpriseIpAllowListEntryRead, UpdateContext: resourceGithubEnterpriseIpAllowListEntryUpdate, @@ -98,7 +99,7 @@ func resourceGithubEnterpriseIpAllowListEntryCreate(ctx context.Context, d *sche d.SetId(string(mutation.CreateIpAllowListEntry.IpAllowListEntry.ID)) - return resourceGithubEnterpriseIpAllowListEntryRead(ctx, d, meta) + return nil } func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { @@ -129,7 +130,9 @@ func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema 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()) + tflog.Info(ctx, "[INFO] Removing IP allow list entry (%s) from state because it no longer exists in GitHub", map[string]any{ + "id": d.Id(), + }) d.SetId("") return nil } @@ -179,7 +182,7 @@ func resourceGithubEnterpriseIpAllowListEntryUpdate(ctx context.Context, d *sche return diag.FromErr(err) } - return resourceGithubEnterpriseIpAllowListEntryRead(ctx, d, meta) + return nil } func resourceGithubEnterpriseIpAllowListEntryDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { @@ -203,23 +206,3 @@ func resourceGithubEnterpriseIpAllowListEntryDelete(ctx context.Context, d *sche d.SetId("") return nil } - -// Helper function to get Enterprise ID from slug -func getEnterpriseID(ctx context.Context, client *githubv4.Client, enterpriseSlug string) (string, error) { - 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 - } - - return query.Enterprise.ID.(string), nil -} diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index 91117c70ca..0ab9b5aaa9 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -2,14 +2,13 @@ package github import ( "fmt" + "strconv" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { - t.Skip("Acceptance test requires a real GitHub Enterprise environment") - resourceName := "github_enterprise_ip_allow_list_entry.test" enterpriseSlug := "test-enterprise" ip := "192.168.1.0/24" @@ -20,7 +19,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { PreCheck: func() { skipUnlessEnterprise(t) }, - Providers: testAccProviders, + ProviderFactories: providerFactories, Steps: []resource.TestStep{ { Config: testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, ip, name, isActive), @@ -28,7 +27,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { 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)), + resource.TestCheckResourceAttr(resourceName, "is_active", strconv.FormatBool(isActive)), ), }, { @@ -41,8 +40,6 @@ func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { } func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { - t.Skip("Acceptance test requires a real GitHub Enterprise environment") - resourceName := "github_enterprise_ip_allow_list_entry.test" enterpriseSlug := "test-enterprise" ip := "192.168.1.0/24" @@ -57,7 +54,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { PreCheck: func() { skipUnlessEnterprise(t) }, - Providers: testAccProviders, + ProviderFactories: providerFactories, Steps: []resource.TestStep{ { Config: testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, ip, name, isActive), diff --git a/github/resource_github_enterprise_organization.go b/github/resource_github_enterprise_organization.go index 7a4a8e4448..2ab1e7c38f 100644 --- a/github/resource_github_enterprise_organization.go +++ b/github/resource_github_enterprise_organization.go @@ -268,7 +268,7 @@ func resourceGithubEnterpriseOrganizationImport(data *schema.ResourceData, meta v4 := meta.(*Owner).v4client ctx := context.Background() - enterpriseId, err := getEnterpriseId(ctx, v4, parts[0]) + enterpriseId, err := getEnterpriseID(ctx, v4, parts[0]) if err != nil { return nil, err } @@ -287,20 +287,6 @@ func resourceGithubEnterpriseOrganizationImport(data *schema.ResourceData, meta return []*schema.ResourceData{data}, nil } -func getEnterpriseId(ctx context.Context, v4 *githubv4.Client, enterpriseSlug string) (string, error) { - var query struct { - Enterprise struct { - ID githubv4.String - } `graphql:"enterprise(slug: $enterpriseSlug)"` - } - - err := v4.Query(ctx, &query, map[string]any{"enterpriseSlug": githubv4.String(enterpriseSlug)}) - if err != nil { - return "", err - } - return string(query.Enterprise.ID), nil -} - func getOrganizationId(ctx context.Context, v4 *githubv4.Client, orgName string) (string, error) { var query struct { Organization struct { diff --git a/github/util_v4.go b/github/util_v4.go index f5756c6899..027a9d9885 100644 --- a/github/util_v4.go +++ b/github/util_v4.go @@ -1,6 +1,8 @@ package github import ( + "context" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/shurcooL/githubv4" ) @@ -48,3 +50,22 @@ func githubv4IDSliceEmpty(ss []string) []githubv4.ID { func githubv4NewStringSlice(v []githubv4.String) *[]githubv4.String { return &v } func githubv4NewIDSlice(v []githubv4.ID) *[]githubv4.ID { return &v } + +func getEnterpriseID(ctx context.Context, client *githubv4.Client, enterpriseSlug string) (string, error) { + 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 + } + + return query.Enterprise.ID.(string), nil +} From b076b2a31b8001938e99d525ff7cd8f30370e668 Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Tue, 10 Feb 2026 15:08:51 -0600 Subject: [PATCH 09/22] Fixing code review comments --- ...source_github_enterprise_ip_allow_list_entry.go | 11 +++++++++++ ...e_github_enterprise_ip_allow_list_entry_test.go | 14 ++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index b1ab39baef..50c2e63296 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -99,6 +99,13 @@ func resourceGithubEnterpriseIpAllowListEntryCreate(ctx context.Context, d *sche d.SetId(string(mutation.CreateIpAllowListEntry.IpAllowListEntry.ID)) + if err := d.Set("created_at", mutation.CreateIpAllowListEntry.IpAllowListEntry.CreatedAt); err != nil { + return diag.FromErr(err) + } + if err := d.Set("updated_at", mutation.CreateIpAllowListEntry.IpAllowListEntry.UpdatedAt); err != nil { + return diag.FromErr(err) + } + return nil } @@ -182,6 +189,10 @@ func resourceGithubEnterpriseIpAllowListEntryUpdate(ctx context.Context, d *sche return diag.FromErr(err) } + if err := d.Set("updated_at", mutation.UpdateIpAllowListEntry.IpAllowListEntry.UpdatedAt); err != nil { + return diag.FromErr(err) + } + return nil } diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index 0ab9b5aaa9..25dffac7d6 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -10,7 +10,6 @@ import ( func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { resourceName := "github_enterprise_ip_allow_list_entry.test" - enterpriseSlug := "test-enterprise" ip := "192.168.1.0/24" name := "Test Entry" isActive := true @@ -22,9 +21,9 @@ func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { ProviderFactories: providerFactories, Steps: []resource.TestStep{ { - Config: testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, ip, name, isActive), + Config: testAccGithubEnterpriseIpAllowListEntryConfig(testAccConf.enterpriseSlug, ip, name, isActive), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "enterprise_slug", enterpriseSlug), + resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), resource.TestCheckResourceAttr(resourceName, "ip", ip), resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, "is_active", strconv.FormatBool(isActive)), @@ -41,7 +40,6 @@ func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { resourceName := "github_enterprise_ip_allow_list_entry.test" - enterpriseSlug := "test-enterprise" ip := "192.168.1.0/24" name := "Test Entry" isActive := true @@ -57,18 +55,18 @@ func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { ProviderFactories: providerFactories, Steps: []resource.TestStep{ { - Config: testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, ip, name, isActive), + Config: testAccGithubEnterpriseIpAllowListEntryConfig(testAccConf.enterpriseSlug, ip, name, isActive), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "enterprise_slug", enterpriseSlug), + resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.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), + Config: testAccGithubEnterpriseIpAllowListEntryConfig(testAccConf.enterpriseSlug, updatedIP, updatedName, updatedIsActive), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "enterprise_slug", enterpriseSlug), + resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), resource.TestCheckResourceAttr(resourceName, "ip", updatedIP), resource.TestCheckResourceAttr(resourceName, "name", updatedName), resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", updatedIsActive)), From d5a1915e892e418e6a31e7ac2bdda44d4c7752a2 Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Fri, 13 Feb 2026 19:33:08 -0600 Subject: [PATCH 10/22] Update resource_github_enterprise_ip_allow_list_entry.go Co-authored-by: Timo Sand --- github/resource_github_enterprise_ip_allow_list_entry.go | 1 - 1 file changed, 1 deletion(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 50c2e63296..6a24ee6d9a 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -214,6 +214,5 @@ func resourceGithubEnterpriseIpAllowListEntryDelete(ctx context.Context, d *sche return diag.FromErr(err) } - d.SetId("") return nil } From 2511b0b6292dbacd345c4270e32ca20362a068d7 Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Fri, 13 Feb 2026 19:33:19 -0600 Subject: [PATCH 11/22] Update resource_github_enterprise_ip_allow_list_entry.go Co-authored-by: Timo Sand --- github/resource_github_enterprise_ip_allow_list_entry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 6a24ee6d9a..98b13d1f92 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -137,7 +137,7 @@ func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema err := client.Query(ctx, &query, variables) if err != nil { if strings.Contains(err.Error(), "Could not resolve to a node with the global id") { - tflog.Info(ctx, "[INFO] Removing IP allow list entry (%s) from state because it no longer exists in GitHub", map[string]any{ + tflog.Info(ctx, "Removing IP allow list entry from state because it no longer exists in GitHub", map[string]any{ "id": d.Id(), }) d.SetId("") From d593d565acab0c59102752718f30ee553a4526c6 Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Fri, 20 Feb 2026 08:14:01 -0600 Subject: [PATCH 12/22] Update github/resource_github_enterprise_ip_allow_list_entry_test.go Co-authored-by: Steve Hipwell --- github/resource_github_enterprise_ip_allow_list_entry_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index 25dffac7d6..74333f73f3 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -8,7 +8,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) { +func TestAccGithubEnterpriseIpAllowListEntry(t *testing.T) { + t.Run("basic", func(t *testing.T) { resourceName := "github_enterprise_ip_allow_list_entry.test" ip := "192.168.1.0/24" name := "Test Entry" From 10de6a7e2fcd114943209b7115b01bb7f153bfae Mon Sep 17 00:00:00 2001 From: Erik Elkins Date: Fri, 20 Feb 2026 08:14:14 -0600 Subject: [PATCH 13/22] Update github/resource_github_enterprise_ip_allow_list_entry.go Co-authored-by: Steve Hipwell --- github/resource_github_enterprise_ip_allow_list_entry.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 98b13d1f92..d31ce7dd8e 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -149,7 +149,9 @@ func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema entry := query.Node.IpAllowListEntry d.Set("ip", entry.AllowListValue) - d.Set("name", entry.Name) + if err := d.Set("name", entry.Name); err != nil { + return diag.FromErr(err) + } d.Set("is_active", entry.IsActive) d.Set("created_at", entry.CreatedAt) d.Set("updated_at", entry.UpdatedAt) From 4474a4f3f939b37c77c5ebc1111e3055136b1670 Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Fri, 20 Feb 2026 08:49:09 -0600 Subject: [PATCH 14/22] Code review changes --- ...e_github_enterprise_ip_allow_list_entry.go | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index d31ce7dd8e..97b70e21f4 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -18,18 +18,20 @@ func resourceGithubEnterpriseIpAllowListEntry() *schema.Resource { UpdateContext: resourceGithubEnterpriseIpAllowListEntryUpdate, DeleteContext: resourceGithubEnterpriseIpAllowListEntryDelete, Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, + StateContext: resourceGithubEnterpriseIpAllowListEntryImport, }, Schema: map[string]*schema.Schema{ "enterprise_slug": { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "The slug of the enterprise to apply the IP allow list entry to.", }, "ip": { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "An IP address or range of IP addresses in CIDR notation.", }, "name": { @@ -147,15 +149,12 @@ func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema } entry := query.Node.IpAllowListEntry - - d.Set("ip", entry.AllowListValue) if err := d.Set("name", entry.Name); err != nil { return diag.FromErr(err) } d.Set("is_active", entry.IsActive) d.Set("created_at", entry.CreatedAt) d.Set("updated_at", entry.UpdatedAt) - d.Set("enterprise_slug", entry.Owner.Enterprise.Slug) return nil } @@ -218,3 +217,41 @@ func resourceGithubEnterpriseIpAllowListEntryDelete(ctx context.Context, d *sche return nil } + +func resourceGithubEnterpriseIpAllowListEntryImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { + client := meta.(*Owner).v4client + + var query struct { + Node struct { + IpAllowListEntry struct { + ID githubv4.String + AllowListValue 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 { + return nil, err + } + + entry := query.Node.IpAllowListEntry + + if err := d.Set("enterprise_slug", string(entry.Owner.Enterprise.Slug)); err != nil { + return nil, err + } + if err := d.Set("ip", string(entry.AllowListValue)); err != nil { + return nil, err + } + + return []*schema.ResourceData{d}, nil +} From 01d61fc0ce39494c2e80ca6398ea7f355567dead Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Fri, 20 Feb 2026 09:09:23 -0600 Subject: [PATCH 15/22] Fixing config in test --- ...hub_enterprise_ip_allow_list_entry_test.go | 82 ++++++++++--------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index 74333f73f3..730ea33e27 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -5,37 +5,47 @@ import ( "strconv" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccGithubEnterpriseIpAllowListEntry(t *testing.T) { t.Run("basic", func(t *testing.T) { - resourceName := "github_enterprise_ip_allow_list_entry.test" - ip := "192.168.1.0/24" - name := "Test Entry" - isActive := true + resourceName := "github_enterprise_ip_allow_list_entry.test" + ip := "192.168.1.0/24" + name := "Test Entry" + isActive := true - resource.Test(t, resource.TestCase{ - PreCheck: func() { - skipUnlessEnterprise(t) - }, - ProviderFactories: providerFactories, - Steps: []resource.TestStep{ - { - Config: testAccGithubEnterpriseIpAllowListEntryConfig(testAccConf.enterpriseSlug, ip, name, isActive), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), - resource.TestCheckResourceAttr(resourceName, "ip", ip), - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "is_active", strconv.FormatBool(isActive)), - ), + config := ` +resource "github_enterprise_ip_allow_list_entry" "test" { + enterprise_slug = "%s" + ip = "%s" + name = "%s" + is_active = %t +} +` + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + skipUnlessEnterprise(t) }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(config, testAccConf.enterpriseSlug, ip, name, isActive), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), + resource.TestCheckResourceAttr(resourceName, "ip", ip), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "is_active", strconv.FormatBool(isActive)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, - }, + }) }) } @@ -49,6 +59,15 @@ func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { updatedName := "Updated Entry" updatedIsActive := false + config := ` +resource "github_enterprise_ip_allow_list_entry" "test" { + enterprise_slug = "%s" + ip = "%s" + name = "%s" + is_active = %t +} +` + resource.Test(t, resource.TestCase{ PreCheck: func() { skipUnlessEnterprise(t) @@ -56,7 +75,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { ProviderFactories: providerFactories, Steps: []resource.TestStep{ { - Config: testAccGithubEnterpriseIpAllowListEntryConfig(testAccConf.enterpriseSlug, ip, name, isActive), + Config: fmt.Sprintf(config, testAccConf.enterpriseSlug, ip, name, isActive), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), resource.TestCheckResourceAttr(resourceName, "ip", ip), @@ -65,7 +84,7 @@ func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { ), }, { - Config: testAccGithubEnterpriseIpAllowListEntryConfig(testAccConf.enterpriseSlug, updatedIP, updatedName, updatedIsActive), + Config: fmt.Sprintf(config, testAccConf.enterpriseSlug, updatedIP, updatedName, updatedIsActive), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), resource.TestCheckResourceAttr(resourceName, "ip", updatedIP), @@ -76,14 +95,3 @@ func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { }, }) } - -func testAccGithubEnterpriseIpAllowListEntryConfig(enterpriseSlug, ip, name string, isActive bool) string { - 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) -} From 03d79ef6757493e6e41dafd8f0acb334f1212c63 Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Fri, 20 Feb 2026 09:11:10 -0600 Subject: [PATCH 16/22] Flattening update test --- ...hub_enterprise_ip_allow_list_entry_test.go | 78 ++++++++++--------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index 730ea33e27..bcf174d93c 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -50,48 +50,50 @@ resource "github_enterprise_ip_allow_list_entry" "test" { } func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { - resourceName := "github_enterprise_ip_allow_list_entry.test" - ip := "192.168.1.0/24" - name := "Test Entry" - isActive := true + t.Run("update", func(t *testing.T) { + resourceName := "github_enterprise_ip_allow_list_entry.test" + ip := "192.168.1.0/24" + name := "Test Entry" + isActive := true - updatedIP := "10.0.0.0/16" - updatedName := "Updated Entry" - updatedIsActive := false + updatedIP := "10.0.0.0/16" + updatedName := "Updated Entry" + updatedIsActive := false - config := ` -resource "github_enterprise_ip_allow_list_entry" "test" { - enterprise_slug = "%s" - ip = "%s" - name = "%s" - is_active = %t -} -` + config := ` + resource "github_enterprise_ip_allow_list_entry" "test" { + enterprise_slug = "%s" + ip = "%s" + name = "%s" + is_active = %t + } + ` - resource.Test(t, resource.TestCase{ - PreCheck: func() { - skipUnlessEnterprise(t) - }, - ProviderFactories: providerFactories, - Steps: []resource.TestStep{ - { - Config: fmt.Sprintf(config, testAccConf.enterpriseSlug, ip, name, isActive), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), - resource.TestCheckResourceAttr(resourceName, "ip", ip), - resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", isActive)), - ), + resource.Test(t, resource.TestCase{ + PreCheck: func() { + skipUnlessEnterprise(t) }, - { - Config: fmt.Sprintf(config, testAccConf.enterpriseSlug, updatedIP, updatedName, updatedIsActive), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), - resource.TestCheckResourceAttr(resourceName, "ip", updatedIP), - resource.TestCheckResourceAttr(resourceName, "name", updatedName), - resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", updatedIsActive)), - ), + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(config, testAccConf.enterpriseSlug, ip, name, isActive), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), + resource.TestCheckResourceAttr(resourceName, "ip", ip), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", isActive)), + ), + }, + { + Config: fmt.Sprintf(config, testAccConf.enterpriseSlug, updatedIP, updatedName, updatedIsActive), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "enterprise_slug", testAccConf.enterpriseSlug), + resource.TestCheckResourceAttr(resourceName, "ip", updatedIP), + resource.TestCheckResourceAttr(resourceName, "name", updatedName), + resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", updatedIsActive)), + ), + }, }, - }, + }) }) } From 4e50668e8009cd2a1cfdbbb5004e2ea497ca8aa6 Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Fri, 20 Feb 2026 11:50:17 -0600 Subject: [PATCH 17/22] Adding error handling --- ...resource_github_enterprise_ip_allow_list_entry.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 97b70e21f4..0b35c94e4d 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -152,9 +152,15 @@ func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema if err := d.Set("name", entry.Name); err != nil { return diag.FromErr(err) } - d.Set("is_active", entry.IsActive) - d.Set("created_at", entry.CreatedAt) - d.Set("updated_at", entry.UpdatedAt) + if err := d.Set("is_active", entry.IsActive); err != nil { + return diag.FromErr(err) + } + if err := d.Set("created_at", entry.CreatedAt); err != nil { + return diag.FromErr(err) + } + if err := d.Set("updated_at", entry.UpdatedAt); err != nil { + return diag.FromErr(err) + } return nil } From 252cfe46b95a110cde4a7238e52427dda4238682 Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Fri, 20 Feb 2026 12:39:06 -0600 Subject: [PATCH 18/22] Simplifying import function --- ...e_github_enterprise_ip_allow_list_entry.go | 34 ++++--------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 0b35c94e4d..24287227c0 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -152,6 +152,9 @@ func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema if err := d.Set("name", entry.Name); err != nil { return diag.FromErr(err) } + if err := d.Set("ip", entry.AllowListValue); err != nil { + return diag.FromErr(err) + } if err := d.Set("is_active", entry.IsActive); err != nil { return diag.FromErr(err) } @@ -225,39 +228,16 @@ func resourceGithubEnterpriseIpAllowListEntryDelete(ctx context.Context, d *sche } func resourceGithubEnterpriseIpAllowListEntryImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { - client := meta.(*Owner).v4client - - var query struct { - Node struct { - IpAllowListEntry struct { - ID githubv4.String - AllowListValue 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) + // : + enterprise_slug, ip_allow_list_entry_id, err := parseID2(d.Id()) if err != nil { return nil, err } - entry := query.Node.IpAllowListEntry - - if err := d.Set("enterprise_slug", string(entry.Owner.Enterprise.Slug)); err != nil { - return nil, err - } - if err := d.Set("ip", string(entry.AllowListValue)); err != nil { + if err := d.Set("enterprise_slug", enterprise_slug); err != nil { return nil, err } + d.SetId(ip_allow_list_entry_id) return []*schema.ResourceData{d}, nil } From 0369b10fc359ceb4480d096c83d97240c5d08dcf Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Fri, 20 Feb 2026 12:40:48 -0600 Subject: [PATCH 19/22] Fix docs --- website/docs/r/enterprise_ip_allow_list_entry.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/enterprise_ip_allow_list_entry.html.markdown b/website/docs/r/enterprise_ip_allow_list_entry.html.markdown index 45817dffba..5a29437cb3 100644 --- a/website/docs/r/enterprise_ip_allow_list_entry.html.markdown +++ b/website/docs/r/enterprise_ip_allow_list_entry.html.markdown @@ -31,8 +31,8 @@ The following arguments are supported: ## Import -This resource can be imported using the ID of the IP allow list entry: +This resource can be imported using the enterprise slug and ID of the IP allow list entry: ```bash -$ terraform import github_enterprise_ip_allow_list_entry.test IALE_kwHOC1234567890a +$ terraform import github_enterprise_ip_allow_list_entry.test enterprise-slug:IALE_kwHOC1234567890a ``` \ No newline at end of file From 2eb508d0aaa32cbebb6072747c7d281d4af2a8d4 Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Mon, 23 Feb 2026 08:04:12 -0600 Subject: [PATCH 20/22] Fixing code review changes --- ...e_github_enterprise_ip_allow_list_entry.go | 50 +++++++++++++++++-- ...hub_enterprise_ip_allow_list_entry_test.go | 3 -- ...terprise_ip_allow_list_entry.html.markdown | 4 +- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 24287227c0..e98de29fe7 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -228,16 +228,58 @@ func resourceGithubEnterpriseIpAllowListEntryDelete(ctx context.Context, d *sche } func resourceGithubEnterpriseIpAllowListEntryImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { - // : - enterprise_slug, ip_allow_list_entry_id, err := parseID2(d.Id()) + client := meta.(*Owner).v4client + + 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 { return nil, err } - if err := d.Set("enterprise_slug", enterprise_slug); err != nil { + entry := query.Node.IpAllowListEntry + + if err := d.Set("enterprise_slug", string(entry.Owner.Enterprise.Slug)); err != nil { + return nil, err + } + if err := d.Set("ip", string(entry.AllowListValue)); err != nil { + return nil, err + } + if err := d.Set("name", entry.Name); err != nil { + return nil, err + } + if err := d.Set("ip", entry.AllowListValue); err != nil { + return nil, err + } + if err := d.Set("is_active", entry.IsActive); err != nil { + return nil, err + } + if err := d.Set("created_at", entry.CreatedAt); err != nil { + return nil, err + } + if err := d.Set("updated_at", entry.UpdatedAt); err != nil { return nil, err } - d.SetId(ip_allow_list_entry_id) return []*schema.ResourceData{d}, nil } diff --git a/github/resource_github_enterprise_ip_allow_list_entry_test.go b/github/resource_github_enterprise_ip_allow_list_entry_test.go index bcf174d93c..ba7f63467a 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry_test.go +++ b/github/resource_github_enterprise_ip_allow_list_entry_test.go @@ -47,9 +47,6 @@ resource "github_enterprise_ip_allow_list_entry" "test" { }, }) }) -} - -func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) { t.Run("update", func(t *testing.T) { resourceName := "github_enterprise_ip_allow_list_entry.test" ip := "192.168.1.0/24" diff --git a/website/docs/r/enterprise_ip_allow_list_entry.html.markdown b/website/docs/r/enterprise_ip_allow_list_entry.html.markdown index 5a29437cb3..45817dffba 100644 --- a/website/docs/r/enterprise_ip_allow_list_entry.html.markdown +++ b/website/docs/r/enterprise_ip_allow_list_entry.html.markdown @@ -31,8 +31,8 @@ The following arguments are supported: ## Import -This resource can be imported using the enterprise slug and ID of the IP allow list entry: +This resource can be imported using the ID of the IP allow list entry: ```bash -$ terraform import github_enterprise_ip_allow_list_entry.test enterprise-slug:IALE_kwHOC1234567890a +$ terraform import github_enterprise_ip_allow_list_entry.test IALE_kwHOC1234567890a ``` \ No newline at end of file From 5dd8ef616c101f910582b83480c60f29e4ed9349 Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Mon, 23 Feb 2026 11:31:20 -0600 Subject: [PATCH 21/22] Fixing lint --- github/resource_github_enterprise_ip_allow_list_entry.go | 7 ++----- github/util_v4.go | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index e98de29fe7..4bb5b10c08 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -132,7 +132,7 @@ func resourceGithubEnterpriseIpAllowListEntryRead(ctx context.Context, d *schema } `graphql:"node(id: $id)"` } - variables := map[string]interface{}{ + variables := map[string]any{ "id": githubv4.ID(d.Id()), } @@ -248,7 +248,7 @@ func resourceGithubEnterpriseIpAllowListEntryImport(ctx context.Context, d *sche } `graphql:"node(id: $id)"` } - variables := map[string]interface{}{ + variables := map[string]any{ "id": githubv4.ID(d.Id()), } @@ -268,9 +268,6 @@ func resourceGithubEnterpriseIpAllowListEntryImport(ctx context.Context, d *sche if err := d.Set("name", entry.Name); err != nil { return nil, err } - if err := d.Set("ip", entry.AllowListValue); err != nil { - return nil, err - } if err := d.Set("is_active", entry.IsActive); err != nil { return nil, err } diff --git a/github/util_v4.go b/github/util_v4.go index dad46ae9f6..93654a6e74 100644 --- a/github/util_v4.go +++ b/github/util_v4.go @@ -60,7 +60,7 @@ func getEnterpriseID(ctx context.Context, client *githubv4.Client, enterpriseSlu } `graphql:"enterprise(slug: $slug)"` } - variables := map[string]interface{}{ + variables := map[string]any{ "slug": githubv4.String(enterpriseSlug), } From c5e2e12ae79204f012e6c934abe656089aea561d Mon Sep 17 00:00:00 2001 From: ErikElkins Date: Tue, 24 Feb 2026 15:14:41 -0600 Subject: [PATCH 22/22] Adding error handling for missing global ID --- github/resource_github_enterprise_ip_allow_list_entry.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/github/resource_github_enterprise_ip_allow_list_entry.go b/github/resource_github_enterprise_ip_allow_list_entry.go index 4bb5b10c08..11e6759d92 100644 --- a/github/resource_github_enterprise_ip_allow_list_entry.go +++ b/github/resource_github_enterprise_ip_allow_list_entry.go @@ -220,7 +220,8 @@ func resourceGithubEnterpriseIpAllowListEntryDelete(ctx context.Context, d *sche } err := client.Mutate(ctx, &mutation, input, nil) - if err != nil { + // GraphQL will return a 200 OK if it couldn't find the global ID + if err != nil && !strings.Contains(err.Error(), "Could not resolve to a node with the global id") { return diag.FromErr(err) }