diff --git a/github/data_source_github_ip_ranges.go b/github/data_source_github_ip_ranges.go index 307dd2298c..3eae60f52f 100644 --- a/github/data_source_github_ip_ranges.go +++ b/github/data_source_github_ip_ranges.go @@ -1,6 +1,9 @@ package github import ( + "fmt" + "net" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) @@ -39,6 +42,66 @@ func dataSourceGithubIpRanges() *schema.Resource { Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "hooks_ipv4": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "git_ipv4": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "pages_ipv4": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "importer_ipv4": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "actions_ipv4": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "dependabot_ipv4": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "hooks_ipv6": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "git_ipv6": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "pages_ipv6": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "importer_ipv6": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "actions_ipv6": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "dependabot_ipv6": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, }, } } @@ -51,27 +114,92 @@ func dataSourceGithubIpRangesRead(d *schema.ResourceData, meta interface{}) erro return err } - if len(api.Hooks)+len(api.Git)+len(api.Pages)+len(api.Importer) > 0 { + cidrHooksIpv4, cidrHooksIpv6, err := splitIpv4Ipv6Cidrs(&api.Hooks) + if err != nil { + return fmt.Errorf("Failed parsing github hooks cidrs") + } + + cidrGitIpv4, cidrGitIpv6, err := splitIpv4Ipv6Cidrs(&api.Git) + if err != nil { + return fmt.Errorf("Failed parsing github git cidrs") + } + + cidrPagesIpv4, cidrPagesIpv6, err := splitIpv4Ipv6Cidrs(&api.Pages) + if err != nil { + return fmt.Errorf("Failed parsing github pages cidrs") + } + + cidrImporterIpv4, cidrImporterIpv6, err := splitIpv4Ipv6Cidrs(&api.Importer) + if err != nil { + return fmt.Errorf("Failed parsing github importer cidrs") + } + + cidrActionsIpv4, cidrActionsIpv6, err := splitIpv4Ipv6Cidrs(&api.Actions) + if err != nil { + return fmt.Errorf("Failed parsing github actions cidrs") + } + + cidrDependabotIpv4, cidrDependabotIpv6, err := splitIpv4Ipv6Cidrs(&api.Dependabot) + if err != nil { + return fmt.Errorf("Failed parsing github dependabot cidrs") + } + + if len(api.Hooks)+len(api.Git)+len(api.Pages)+len(api.Importer)+len(api.Actions)+len(api.Dependabot) > 0 { d.SetId("github-ip-ranges") } if len(api.Hooks) > 0 { d.Set("hooks", api.Hooks) + d.Set("hooks_ipv4", cidrHooksIpv4) + d.Set("hooks_ipv6", cidrHooksIpv6) } if len(api.Git) > 0 { d.Set("git", api.Git) + d.Set("git_ipv4", cidrGitIpv4) + d.Set("git_ipv6", cidrGitIpv6) } if len(api.Pages) > 0 { d.Set("pages", api.Pages) + d.Set("pages_ipv4", cidrPagesIpv4) + d.Set("pages_ipv6", cidrPagesIpv6) } if len(api.Importer) > 0 { d.Set("importer", api.Importer) + d.Set("importer_ipv4", cidrImporterIpv4) + d.Set("importer_ipv6", cidrImporterIpv6) } if len(api.Actions) > 0 { d.Set("actions", api.Actions) + d.Set("actions_ipv4", cidrActionsIpv4) + d.Set("actions_ipv6", cidrActionsIpv6) } if len(api.Dependabot) > 0 { d.Set("dependabot", api.Dependabot) + d.Set("dependabot_ipv4", cidrDependabotIpv4) + d.Set("dependabot_ipv6", cidrDependabotIpv6) } return nil } + +func splitIpv4Ipv6Cidrs(cidrs *[]string) (*[]string, *[]string, error) { + cidrIpv4 := []string{} + cidrIpv6 := []string{} + + for _, cidr := range *cidrs { + cidrHost, _, err := net.ParseCIDR(cidr) + if err != nil { + return nil, nil, fmt.Errorf("Failed parsing cidr %s", cidr) + } + ip := net.ParseIP(string(cidrHost)) + if ip == nil { + return nil, nil, fmt.Errorf("Failed parsing cidr host %s from cidr %s", cidrHost, cidr) + } + if ip.To4() != nil { + cidrIpv4 = append(cidrIpv4, cidr) + } else { + cidrIpv6 = append(cidrIpv6, cidr) + } + } + + return &cidrIpv4, &cidrIpv6, nil +} diff --git a/github/data_source_github_ip_ranges_test.go b/github/data_source_github_ip_ranges_test.go index 224b85d0e5..b70fd61c37 100644 --- a/github/data_source_github_ip_ranges_test.go +++ b/github/data_source_github_ip_ranges_test.go @@ -19,6 +19,18 @@ func TestAccGithubIpRangesDataSource(t *testing.T) { resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "importer.#"), resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "actions.#"), resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "dependabot.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "hooks_ipv4.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "git_ipv4.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "pages_ipv4.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "importer_ipv4.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "actions_ipv4.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "dependabot_ipv4.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "hooks_ipv6.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "git_ipv6.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "pages_ipv6.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "importer_ipv6.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "actions_ipv6.#"), + resource.TestCheckResourceAttrSet("data.github_ip_ranges.test", "dependabot_ipv6.#"), ) testCase := func(t *testing.T, mode string) {