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 }