-
Notifications
You must be signed in to change notification settings - Fork 626
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GATE-1848: Adds support for gateway location API
- Loading branch information
1 parent
c14c5ca
commit 6a65612
Showing
3 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
package cloudflare | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"strings" | ||
|
||
"github.com/cloudflare/cloudflare-go" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
func resourceCloudflareTeamsLocation() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceCloudflareTeamsLocationCreate, | ||
Read: resourceCloudflareTeamsLocationRead, | ||
Update: resourceCloudflareTeamsLocationUpdate, | ||
Delete: resourceCloudflareTeamsLocationDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: resourceCloudflareTeamsLocationImport, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"account_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"networks": { | ||
Type: schema.TypeSet, | ||
Optional: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"network": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"client_default": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
}, | ||
"policy_ids": { | ||
Type: schema.TypeList, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Computed: true, | ||
}, | ||
"ip": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"doh_subdomain": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"anonymized_logs_enabled": { | ||
Type: schema.TypeBool, | ||
Computed: true, | ||
}, | ||
"ipv4_destination": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceCloudflareTeamsLocationRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*cloudflare.API) | ||
accountID := d.Get("account_id").(string) | ||
|
||
location, err := client.TeamsLocation(context.Background(), accountID, d.Id()) | ||
if err != nil { | ||
if strings.Contains(err.Error(), "HTTP status 400") { | ||
log.Printf("[INFO] Teams Location %s no longer exists", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
return fmt.Errorf("error finding Teams Location %q: %s", d.Id(), err) | ||
} | ||
|
||
if err := d.Set("name", location.Name); err != nil { | ||
return fmt.Errorf("error parsing Location name") | ||
} | ||
if err := d.Set("networks", flattenTeamsLocationNetworks(location.Networks)); err != nil { | ||
return fmt.Errorf("error parsing Location networks") | ||
} | ||
if err := d.Set("policy_ids", location.PolicyIDs); err != nil { | ||
return fmt.Errorf("error parsing Location policy IDs") | ||
} | ||
if err := d.Set("ip", location.Ip); err != nil { | ||
return fmt.Errorf("error parsing Location IP") | ||
} | ||
if err := d.Set("doh_subdomain", location.Subdomain); err != nil { | ||
return fmt.Errorf("error parsing Location DOH subdomain") | ||
} | ||
if err := d.Set("anonymized_logs_enabled", location.AnonymizedLogsEnabled); err != nil { | ||
return fmt.Errorf("error parsing Location anonimized log enablement") | ||
} | ||
if err := d.Set("ipv4_destination", location.IPv4Destination); err != nil { | ||
return fmt.Errorf("error parsing Location IPv4 destination") | ||
} | ||
if err := d.Set("client_default", location.ClientDefault); err != nil { | ||
return fmt.Errorf("error parsing Location client default") | ||
} | ||
|
||
return nil | ||
} | ||
func resourceCloudflareTeamsLocationCreate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*cloudflare.API) | ||
|
||
accountID := d.Get("account_id").(string) | ||
networks, err := inflateTeamsLocationNetworks(d.Get("networks")) | ||
if err != nil { | ||
return errors.Wrap(err, fmt.Sprintf("error creating Teams Location for account %q: %s, %v", accountID, err, networks)) | ||
} | ||
|
||
newTeamLocation := cloudflare.TeamsLocation{ | ||
Name: d.Get("name").(string), | ||
Networks: networks, | ||
ClientDefault: d.Get("client_default").(bool), | ||
} | ||
|
||
log.Printf("[DEBUG] Creating Cloudflare Teams Location from struct: %+v", newTeamLocation) | ||
|
||
location, err := client.CreateTeamsLocation(context.Background(), accountID, newTeamLocation) | ||
if err != nil { | ||
return fmt.Errorf("error creating Teams Location for account %q: %s, %v", accountID, err, networks) | ||
} | ||
|
||
d.SetId(location.ID) | ||
return resourceCloudflareTeamsLocationRead(d, meta) | ||
|
||
} | ||
func resourceCloudflareTeamsLocationUpdate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*cloudflare.API) | ||
accountID := d.Get("account_id").(string) | ||
networks, err := inflateTeamsLocationNetworks(d.Get("networks")) | ||
if err != nil { | ||
return errors.Wrap(err, fmt.Sprintf("error updating Teams Location for account %q: %s, %v", accountID, err, networks)) | ||
} | ||
updatedTeamsLocation := cloudflare.TeamsLocation{ | ||
ID: d.Id(), | ||
Name: d.Get("name").(string), | ||
ClientDefault: d.Get("client_default").(bool), | ||
Networks: networks, | ||
} | ||
log.Printf("[DEBUG] Updating Cloudflare Teams Location from struct: %+v", updatedTeamsLocation) | ||
|
||
teamsLocation, err := client.UpdateTeamsLocation(context.Background(), accountID, updatedTeamsLocation) | ||
if err != nil { | ||
return fmt.Errorf("error updating Teams Location for account %q: %s", accountID, err) | ||
} | ||
if teamsLocation.ID == "" { | ||
return fmt.Errorf("failed to find Teams Location ID in update response; resource was empty") | ||
} | ||
return resourceCloudflareTeamsLocationRead(d, meta) | ||
} | ||
|
||
func resourceCloudflareTeamsLocationDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*cloudflare.API) | ||
id := d.Id() | ||
accountID := d.Get("account_id").(string) | ||
|
||
log.Printf("[DEBUG] Deleting Cloudflare Teams Location using ID: %s", id) | ||
|
||
err := client.DeleteTeamsLocation(context.Background(), accountID, id) | ||
if err != nil { | ||
return fmt.Errorf("error deleting Teams Location for account %q: %s", accountID, err) | ||
} | ||
|
||
return resourceCloudflareTeamsLocationRead(d, meta) | ||
} | ||
|
||
func resourceCloudflareTeamsLocationImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
attributes := strings.SplitN(d.Id(), "/", 2) | ||
|
||
if len(attributes) != 2 { | ||
return nil, fmt.Errorf("invalid id (\"%s\") specified, should be in format \"accountID/teamsLocationID\"", d.Id()) | ||
} | ||
|
||
accountID, teamsLocationID := attributes[0], attributes[1] | ||
|
||
log.Printf("[DEBUG] Importing Cloudflare Teams Location: id %s for account %s", teamsLocationID, accountID) | ||
|
||
d.Set("account_id", accountID) | ||
d.SetId(teamsLocationID) | ||
|
||
err := resourceCloudflareTeamsLocationRead(d, meta) | ||
|
||
return []*schema.ResourceData{d}, err | ||
|
||
} | ||
|
||
func inflateTeamsLocationNetworks(networks interface{}) ([]cloudflare.TeamsLocationNetwork, error) { | ||
var networkStructs []cloudflare.TeamsLocationNetwork | ||
if networks != nil { | ||
networkSet, ok := networks.(*schema.Set) | ||
if !ok { | ||
return nil, fmt.Errorf("error parsing network list") | ||
} | ||
for _, i := range networkSet.List() { | ||
network, ok := i.(map[string]interface{}) | ||
if !ok { | ||
return nil, fmt.Errorf("error parsing network") | ||
} | ||
networkStructs = append(networkStructs, cloudflare.TeamsLocationNetwork{ | ||
ID: network["id"].(string), | ||
Network: network["network"].(string), | ||
}) | ||
} | ||
} | ||
return networkStructs, nil | ||
} | ||
|
||
func flattenTeamsLocationNetworks(networks []cloudflare.TeamsLocationNetwork) []interface{} { | ||
var flattenedNetworks []interface{} | ||
for _, net := range networks { | ||
flattenedNetworks = append(flattenedNetworks, map[string]interface{}{ | ||
"id": net.ID, | ||
"network": net.Network, | ||
}) | ||
} | ||
return flattenedNetworks | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package cloudflare | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/cloudflare/cloudflare-go" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/terraform" | ||
) | ||
|
||
func TestAccCloudflareTeamsLocationBasic(t *testing.T) { | ||
rnd := generateRandomResourceName() | ||
name := fmt.Sprintf("cloudflare_teams_location.%s", rnd) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { | ||
testAccessAccPreCheck(t) | ||
}, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckCloudflareTeamsLocationDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCloudflareTeamsLocationConfigBasic(rnd, accountID), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(name, "account_id", accountID), | ||
resource.TestCheckResourceAttr(name, "name", rnd), | ||
resource.TestCheckResourceAttr(name, "client_default", "false"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCloudflareTeamsLocationConfigBasic(rnd, accountID string) string { | ||
return fmt.Sprintf(` | ||
resource "cloudflare_teams_location" "%[1]s" { | ||
name = "%[1]s" | ||
account_id = "%[2]s" | ||
} | ||
`, rnd, accountID) | ||
} | ||
|
||
func testAccCheckCloudflareTeamsLocationDestroy(s *terraform.State) error { | ||
client := testAccProvider.Meta().(*cloudflare.API) | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "cloudflare_teams_location" { | ||
continue | ||
} | ||
|
||
_, err := client.TeamsLocation(context.Background(), rs.Primary.Attributes["account_id"], rs.Primary.ID) | ||
if err == nil { | ||
return fmt.Errorf("teams Location still exists") | ||
} | ||
} | ||
|
||
return nil | ||
} |