github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/cloudflare/firewall.go (about)

     1  // Copyright 2019 The Terraformer Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package cloudflare
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/GoogleCloudPlatform/terraformer/terraformutils"
    22  	cf "github.com/cloudflare/cloudflare-go"
    23  )
    24  
    25  type FirewallGenerator struct {
    26  	CloudflareService
    27  }
    28  
    29  func (*FirewallGenerator) createZoneLockdownsResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) {
    30  	resources := []terraformutils.Resource{}
    31  	page := 1
    32  
    33  	for {
    34  		zonelockdowns, err := api.ListZoneLockdowns(zoneID, page)
    35  		if err != nil {
    36  			return resources, err
    37  		}
    38  		for _, zonelockdown := range zonelockdowns.Result {
    39  			resources = append(resources, terraformutils.NewResource(
    40  				zonelockdown.ID,
    41  				fmt.Sprintf("%s_%s", zoneName, zonelockdown.ID),
    42  				"cloudflare_zone_lockdown",
    43  				"cloudflare",
    44  				map[string]string{
    45  					"zone_id": zoneID,
    46  					"zone":    zoneName,
    47  				},
    48  				[]string{},
    49  				map[string]interface{}{},
    50  			))
    51  		}
    52  
    53  		if zonelockdowns.TotalPages > page {
    54  			page++
    55  		} else {
    56  			break
    57  		}
    58  	}
    59  
    60  	return resources, nil
    61  }
    62  
    63  func (g *FirewallGenerator) createAccountAccessRuleResources(api *cf.API) ([]terraformutils.Resource, error) {
    64  	resources := []terraformutils.Resource{}
    65  	rules, err := api.ListAccountAccessRules(api.AccountID, cf.AccessRule{}, 1)
    66  	if err != nil {
    67  		return resources, err
    68  	}
    69  
    70  	totalPages := rules.TotalPages
    71  	for _, rule := range rules.Result {
    72  		resources = append(resources, terraformutils.NewSimpleResource(
    73  			rule.ID,
    74  			rule.ID,
    75  			"cloudflare_access_rule",
    76  			"cloudflare",
    77  			[]string{},
    78  		))
    79  	}
    80  
    81  	for page := 2; page <= totalPages; page++ {
    82  		rules, err := api.ListAccountAccessRules(api.AccountID, cf.AccessRule{}, page)
    83  		if err != nil {
    84  			return resources, err
    85  		}
    86  		for _, rule := range rules.Result {
    87  			resources = append(resources, terraformutils.NewSimpleResource(
    88  				rule.ID,
    89  				rule.ID,
    90  				"cloudflare_access_rule",
    91  				"cloudflare",
    92  				[]string{},
    93  			))
    94  		}
    95  	}
    96  
    97  	return resources, nil
    98  }
    99  
   100  func (*FirewallGenerator) createZoneAccessRuleResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) {
   101  	resources := []terraformutils.Resource{}
   102  	rules, err := api.ListZoneAccessRules(zoneID, cf.AccessRule{}, 1)
   103  	if err != nil {
   104  		return resources, err
   105  	}
   106  
   107  	totalPages := rules.TotalPages
   108  	for _, r := range rules.Result {
   109  		if strings.Compare(r.Scope.Type, "organization") != 0 {
   110  			resources = append(resources, terraformutils.NewResource(
   111  				r.ID,
   112  				fmt.Sprintf("%s_%s", zoneName, r.ID),
   113  				"cloudflare_access_rule",
   114  				"cloudflare",
   115  				map[string]string{
   116  					"zone_id": zoneID,
   117  				},
   118  				[]string{},
   119  				map[string]interface{}{},
   120  			))
   121  		}
   122  	}
   123  
   124  	for page := 2; page <= totalPages; page++ {
   125  		rules, err := api.ListZoneAccessRules(zoneID, cf.AccessRule{}, page)
   126  		if err != nil {
   127  			return resources, err
   128  		}
   129  		for _, r := range rules.Result {
   130  			if strings.Compare(r.Scope.Type, "organization") != 0 {
   131  				resources = append(resources, terraformutils.NewResource(
   132  					r.ID,
   133  					fmt.Sprintf("%s_%s", zoneName, r.ID),
   134  					"cloudflare_access_rule",
   135  					"cloudflare",
   136  					map[string]string{
   137  						"zone_id": zoneID,
   138  					},
   139  					[]string{},
   140  					map[string]interface{}{},
   141  				))
   142  			}
   143  		}
   144  	}
   145  
   146  	return resources, nil
   147  }
   148  
   149  func (*FirewallGenerator) createFilterResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) {
   150  	resources := []terraformutils.Resource{}
   151  	filters, err := api.Filters(zoneID, cf.PaginationOptions{})
   152  	if err != nil {
   153  		return resources, err
   154  	}
   155  
   156  	for _, filter := range filters {
   157  		resources = append(resources, terraformutils.NewResource(
   158  			filter.ID,
   159  			fmt.Sprintf("%s_%s", zoneName, filter.ID),
   160  			"cloudflare_filter",
   161  			"cloudflare",
   162  			map[string]string{
   163  				"zone_id": zoneID,
   164  			},
   165  			[]string{},
   166  			map[string]interface{}{},
   167  		))
   168  	}
   169  
   170  	return resources, nil
   171  }
   172  
   173  func (*FirewallGenerator) createFirewallRuleResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) {
   174  	resources := []terraformutils.Resource{}
   175  
   176  	fwrules, err := api.FirewallRules(zoneID, cf.PaginationOptions{})
   177  	if err != nil {
   178  		return resources, err
   179  	}
   180  	for _, rule := range fwrules {
   181  		resources = append(resources, terraformutils.NewResource(
   182  			rule.ID,
   183  			fmt.Sprintf("%s_%s", zoneName, rule.ID),
   184  			"cloudflare_firewall_rule",
   185  			"cloudflare",
   186  			map[string]string{
   187  				"zone_id": zoneID,
   188  			},
   189  			[]string{},
   190  			map[string]interface{}{},
   191  		))
   192  	}
   193  
   194  	return resources, nil
   195  }
   196  
   197  func (g *FirewallGenerator) createRateLimitResources(api *cf.API, zoneID, zoneName string) ([]terraformutils.Resource, error) {
   198  	var resources []terraformutils.Resource
   199  
   200  	rateLimits, err := api.ListAllRateLimits(zoneID)
   201  	if err != nil {
   202  		return resources, err
   203  	}
   204  	for _, rateLimit := range rateLimits {
   205  		resources = append(resources, terraformutils.NewSimpleResource(
   206  			rateLimit.ID,
   207  			fmt.Sprintf("%s_%s", zoneID, rateLimit.ID),
   208  			"cloudflare_rate_limit",
   209  			"cloudflare",
   210  			[]string{}))
   211  	}
   212  
   213  	return resources, nil
   214  }
   215  
   216  func (g *FirewallGenerator) InitResources() error {
   217  	api, err := g.initializeAPI()
   218  	if err != nil {
   219  		return err
   220  	}
   221  
   222  	if len(api.AccountID) > 0 {
   223  		resources, err := g.createAccountAccessRuleResources(api)
   224  		if err != nil {
   225  			return err
   226  		}
   227  		g.Resources = append(g.Resources, resources...)
   228  
   229  	}
   230  
   231  	zones, err := api.ListZones()
   232  	if err != nil {
   233  		return err
   234  	}
   235  
   236  	funcs := []func(*cf.API, string, string) ([]terraformutils.Resource, error){
   237  		g.createFirewallRuleResources,
   238  		g.createFilterResources,
   239  		g.createZoneAccessRuleResources,
   240  		g.createZoneLockdownsResources,
   241  		g.createRateLimitResources,
   242  	}
   243  
   244  	for _, zone := range zones {
   245  		for _, f := range funcs {
   246  			// Getting all firewall filters
   247  			tmpRes, err := f(api, zone.ID, zone.Name)
   248  			if err != nil {
   249  				return err
   250  			}
   251  			g.Resources = append(g.Resources, tmpRes...)
   252  		}
   253  	}
   254  
   255  	return nil
   256  }
   257  
   258  func (g *FirewallGenerator) PostConvertHook() error {
   259  	for i, resourceRecord := range g.Resources {
   260  		// If Zone Name exists, delete ZoneID
   261  		if _, zoneIDExist := resourceRecord.Item["zone_id"]; zoneIDExist {
   262  			delete(g.Resources[i].Item, "zone")
   263  		}
   264  
   265  		if resourceRecord.InstanceInfo.Type == "cloudflare_firewall_rule" {
   266  			if resourceRecord.Item["priority"].(string) == "0" {
   267  				delete(g.Resources[i].Item, "priority")
   268  			}
   269  		}
   270  
   271  		// Reference to 'cloudflare_filter' resource in 'cloudflare_firewall_rule'
   272  		if resourceRecord.InstanceInfo.Type == "cloudflare_filter" {
   273  			continue
   274  		}
   275  		filterID := resourceRecord.Item["filter_id"]
   276  		for _, filterResource := range g.Resources {
   277  			if filterResource.InstanceInfo.Type != "cloudflare_filter" {
   278  				continue
   279  			}
   280  			if filterID == filterResource.InstanceState.ID {
   281  				g.Resources[i].Item["filter_id"] = "${cloudflare_filter." + filterResource.ResourceName + ".id}"
   282  			}
   283  		}
   284  	}
   285  
   286  	return nil
   287  }