Skip to content

Conversation

@ErikElkins
Copy link
Contributor

@ErikElkins ErikElkins commented May 2, 2025

Resolves #2648


Before the change?

  • None

After the change?

  • Adding the github_enterprise_ip_allow_list_entry resource.

Pull request checklist

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)

Does this introduce a breaking change?

Please see our docs on breaking changes to help!

  • Yes
  • No

@github-project-automation github-project-automation bot moved this to 🆕 Triage in 🧰 Octokit Active May 2, 2025
@nickfloyd nickfloyd moved this from 🆕 Triage to 👀 In review in 🧰 Octokit Active Jun 3, 2025
@ErikElkins ErikElkins changed the title Adding github_enterprise_ip_allow_list_entry resource feat: Adding github_enterprise_ip_allow_list_entry resource Oct 25, 2025
@github-actions github-actions bot added the Type: Feature New feature or request label Jan 13, 2026
nickfloyd
nickfloyd previously approved these changes Jan 13, 2026
@nickfloyd nickfloyd added this to the v6.10.0 Release milestone Jan 13, 2026
@nickfloyd
Copy link
Member

@ErikElkins Apologies for the delay on getting to this PR. Would you be willing to fix the lint issue? Thank you!

Copy link
Collaborator

@stevehipwell stevehipwell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a REST API for this functionality?

}

// Helper function to get Enterprise ID from slug
func getEnterpriseID(ctx context.Context, client *githubv4.Client, enterpriseSlug string) (string, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK enterprise slug is the ID, the GraphQL ID shouldn't pollute TF.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i understand this correctly, you'd still want the resource to reference the slug (and not the GraphQL ID) like so:

resource "github_enterprise_ip_allow_list_entry" "example" {
  enterprise_slug = "my-enterprise-slug"
  ip              = "1.2.3.4"
}

If you pass enterprise_slug to the CreateIpAllowListEntry mutation it will fail with Error: Could not resolve to a node with the global id of 'my-enterprise-slug' (i tested with a real one). It looks to need the GraphQL ID, and not the slug. If we keep the lookup like this, we should be able to keep the GraphQL ID out of the terraform and have the lookup take place behind the scenes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.github.com/en/enterprise-cloud@latest/graphql/reference/input-objects#createipallowlistentryinput

I think it makes sense that it's not the enterprise_slug as AFAIK that Mutation also works for Organizations, which could have the same slug as the enterprise

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GraphQL ID may be required, but it shouldn't be the resource ID as that should be the slug. I'm not fully familiar with the GitHub GraphQL implementation but isn't the whole point of GraphQL that you can do everything with a single query; in which case why can't you use the slug to lookup the GraphQL ID in the same query?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you can combine multiple "requests" in a single GQL query, but directly dependant things aren't possible AFAIK.
But there one can then just use sequential queries. And one can't mix mutations and queries in a single request

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see a pending REST implementation. We may have to leak a GraphQL ID into the state after all. I'd suggest using <graphql-id>:<name> for the ID so if we get a REST implementation we can remove the GraphQL dependency.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't recommend using name as it's actually a description field and can contain long text.

And since name is mutable, it would change the ID even if the actual resource didn't change.

Existing IP entry in UI: image
Add entry in UI:
image
Edit entry in UI:
image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure IP isn't unique in the context of an enterprise?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we have had multiple duplicate IPs. We could treat it as unique even if the API allows duplicate IPS. One reason for allowing duplicate IPs would be ease of management.

For example the IPs in api.github.com/meta have duplicates between products. If I'd be syncing these blindly to the allowlist with the product name (which we are doing) then it needs to enable duplicate IPS 😬

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that it's relevant to this PR, but wouldn't you run them through distinct by default?

@github-project-automation github-project-automation bot moved this from 👀 In review to 🏗 In progress in 🧰 Octokit Active Jan 13, 2026
@ErikElkins
Copy link
Contributor Author

Yep! Let me jump in here.

@ErikElkins
Copy link
Contributor Author

ErikElkins commented Jan 13, 2026

Oh, i see the other PR. Should we just close this? EDIT: NEVERMIND

@ErikElkins
Copy link
Contributor Author

Is there a REST API for this functionality?

Doesn't look like they've added it since I opened the PR.

Copy link

@gateixeira gateixeira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @ErikElkins 👋

I was updating your PR to have the lint fixed and realized that the acceptance tests seem to also not pass. Can you please update the PR with the following? Feel free to validate on your end.

Copy link

@gateixeira gateixeira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ErikElkins thanks for the changes!

StateContext: schema.ImportStatePassthroughContext,
},

Schema: map[string]*schema.Schema{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a top-level Description field


d.SetId(string(mutation.CreateIpAllowListEntry.IpAllowListEntry.ID))

return resourceGithubEnterpriseIpAllowListEntryRead(ctx, d, meta)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the call to Read in Create. Instead set any computed values based on the response

return diag.FromErr(err)
}

return resourceGithubEnterpriseIpAllowListEntryRead(ctx, d, meta)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use tflog.Info instead of log.Printf

}

// Helper function to get Enterprise ID from slug
func getEnterpriseID(ctx context.Context, client *githubv4.Client, enterpriseSlug string) (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function seems to exist already in resource_github_enterprise_organization.go, could you re-use that?

Maybe it could be moved to util_v4.go?

)

func TestAccGithubEnterpriseIpAllowListEntry_basic(t *testing.T) {
t.Skip("Acceptance test requires a real GitHub Enterprise environment")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
t.Skip("Acceptance test requires a real GitHub Enterprise environment")

PreCheck: func() {
skipUnlessEnterprise(t)
},
Providers: testAccProviders,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Providers: testAccProviders,
ProviderFactories: providerFactories,

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)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
resource.TestCheckResourceAttr(resourceName, "is_active", fmt.Sprintf("%t", isActive)),
resource.TestCheckResourceAttr(resourceName, "is_active", strconv.FormatBool(isActive)),

}

func TestAccGithubEnterpriseIpAllowListEntry_update(t *testing.T) {
t.Skip("Acceptance test requires a real GitHub Enterprise environment")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
t.Skip("Acceptance test requires a real GitHub Enterprise environment")

PreCheck: func() {
skipUnlessEnterprise(t)
},
Providers: testAccProviders,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Providers: testAccProviders,
ProviderFactories: providerFactories,

@deiga
Copy link
Contributor

deiga commented Jan 16, 2026

@ErikElkins Are you able to continue finalizing this PR? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT]: IP Allow Lists for enterprises and organizations

5 participants