providers/cloudflare/firewall.go (235 lines of code) (raw):

// Copyright 2019 The Terraformer Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cloudflare import ( "fmt" "strings" "github.com/GoogleCloudPlatform/terraformer/terraformutils" cf "github.com/cloudflare/cloudflare-go" ) type FirewallGenerator struct { CloudflareService } func (*FirewallGenerator) createZoneLockdownsResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) { resources := []terraformutils.Resource{} page := 1 for { zonelockdowns, err := api.ListZoneLockdowns(zoneID, page) if err != nil { return resources, err } for _, zonelockdown := range zonelockdowns.Result { resources = append(resources, terraformutils.NewResource( zonelockdown.ID, fmt.Sprintf("%s_%s", zoneName, zonelockdown.ID), "cloudflare_zone_lockdown", "cloudflare", map[string]string{ "zone_id": zoneID, "zone": zoneName, }, []string{}, map[string]interface{}{}, )) } if zonelockdowns.TotalPages > page { page++ } else { break } } return resources, nil } func (g *FirewallGenerator) createAccountAccessRuleResources(api *cf.API) ([]terraformutils.Resource, error) { resources := []terraformutils.Resource{} rules, err := api.ListAccountAccessRules(api.AccountID, cf.AccessRule{}, 1) if err != nil { return resources, err } totalPages := rules.TotalPages for _, rule := range rules.Result { resources = append(resources, terraformutils.NewSimpleResource( rule.ID, rule.ID, "cloudflare_access_rule", "cloudflare", []string{}, )) } for page := 2; page <= totalPages; page++ { rules, err := api.ListAccountAccessRules(api.AccountID, cf.AccessRule{}, page) if err != nil { return resources, err } for _, rule := range rules.Result { resources = append(resources, terraformutils.NewSimpleResource( rule.ID, rule.ID, "cloudflare_access_rule", "cloudflare", []string{}, )) } } return resources, nil } func (*FirewallGenerator) createZoneAccessRuleResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) { resources := []terraformutils.Resource{} rules, err := api.ListZoneAccessRules(zoneID, cf.AccessRule{}, 1) if err != nil { return resources, err } totalPages := rules.TotalPages for _, r := range rules.Result { if strings.Compare(r.Scope.Type, "organization") != 0 { resources = append(resources, terraformutils.NewResource( r.ID, fmt.Sprintf("%s_%s", zoneName, r.ID), "cloudflare_access_rule", "cloudflare", map[string]string{ "zone_id": zoneID, }, []string{}, map[string]interface{}{}, )) } } for page := 2; page <= totalPages; page++ { rules, err := api.ListZoneAccessRules(zoneID, cf.AccessRule{}, page) if err != nil { return resources, err } for _, r := range rules.Result { if strings.Compare(r.Scope.Type, "organization") != 0 { resources = append(resources, terraformutils.NewResource( r.ID, fmt.Sprintf("%s_%s", zoneName, r.ID), "cloudflare_access_rule", "cloudflare", map[string]string{ "zone_id": zoneID, }, []string{}, map[string]interface{}{}, )) } } } return resources, nil } func (*FirewallGenerator) createFilterResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) { resources := []terraformutils.Resource{} filters, err := api.Filters(zoneID, cf.PaginationOptions{}) if err != nil { return resources, err } for _, filter := range filters { resources = append(resources, terraformutils.NewResource( filter.ID, fmt.Sprintf("%s_%s", zoneName, filter.ID), "cloudflare_filter", "cloudflare", map[string]string{ "zone_id": zoneID, }, []string{}, map[string]interface{}{}, )) } return resources, nil } func (*FirewallGenerator) createFirewallRuleResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) { resources := []terraformutils.Resource{} fwrules, err := api.FirewallRules(zoneID, cf.PaginationOptions{}) if err != nil { return resources, err } for _, rule := range fwrules { resources = append(resources, terraformutils.NewResource( rule.ID, fmt.Sprintf("%s_%s", zoneName, rule.ID), "cloudflare_firewall_rule", "cloudflare", map[string]string{ "zone_id": zoneID, }, []string{}, map[string]interface{}{}, )) } return resources, nil } func (g *FirewallGenerator) createRateLimitResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) { var resources []terraformutils.Resource rateLimits, err := api.ListAllRateLimits(zoneID) if err != nil { return resources, err } for _, rateLimit := range rateLimits { resources = append(resources, terraformutils.NewSimpleResource( rateLimit.ID, fmt.Sprintf("%s_%s", zoneID, rateLimit.ID), "cloudflare_rate_limit", "cloudflare", []string{})) } return resources, nil } func (g *FirewallGenerator) InitResources() error { api, err := g.initializeAPI() if err != nil { return err } if len(api.AccountID) > 0 { resources, err := g.createAccountAccessRuleResources(api) if err != nil { return err } g.Resources = append(g.Resources, resources...) } zones, err := api.ListZones() if err != nil { return err } funcs := []func(*cf.API, string, string) ([]terraformutils.Resource, error){ g.createFirewallRuleResources, g.createFilterResources, g.createZoneAccessRuleResources, g.createZoneLockdownsResources, g.createRateLimitResources, } for _, zone := range zones { for _, f := range funcs { // Getting all firewall filters tmpRes, err := f(api, zone.ID, zone.Name) if err != nil { return err } g.Resources = append(g.Resources, tmpRes...) } } return nil } func (g *FirewallGenerator) PostConvertHook() error { for i, resourceRecord := range g.Resources { // If Zone Name exists, delete ZoneID if _, zoneIDExist := resourceRecord.Item["zone_id"]; zoneIDExist { delete(g.Resources[i].Item, "zone") } if resourceRecord.InstanceInfo.Type == "cloudflare_firewall_rule" { if resourceRecord.Item["priority"].(string) == "0" { delete(g.Resources[i].Item, "priority") } } // Reference to 'cloudflare_filter' resource in 'cloudflare_firewall_rule' if resourceRecord.InstanceInfo.Type == "cloudflare_filter" { continue } filterID := resourceRecord.Item["filter_id"] for _, filterResource := range g.Resources { if filterResource.InstanceInfo.Type != "cloudflare_filter" { continue } if filterID == filterResource.InstanceState.ID { g.Resources[i].Item["filter_id"] = "${cloudflare_filter." + filterResource.ResourceName + ".id}" } } } return nil }