Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support subnetwork flow logs. #1385

Merged
merged 3 commits into from
May 2, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 41 additions & 12 deletions google/resource_compute_subnetwork.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ package google
import (
"fmt"
"log"

"net"
"strings"
"time"

"github.com/apparentlymart/go-cidr/cidr"
"github.com/hashicorp/terraform/helper/customdiff"
"github.com/hashicorp/terraform/helper/schema"
computeBeta "google.golang.org/api/compute/v0.beta"
"google.golang.org/api/compute/v1"
"net"
"time"
)

var (
SubnetworkBaseApiVersion = v1
SubnetworkVersionedFeatures = []Feature{
{Version: v0beta, Item: "secondary_ip_range"},
{Version: v0beta, Item: "enable_flow_logs"},
}
)

Expand Down Expand Up @@ -112,6 +112,11 @@ func resourceComputeSubnetwork() *schema.Resource {
},
},

"enable_flow_logs": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},

"self_link": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Expand All @@ -125,6 +130,7 @@ func resourceComputeSubnetwork() *schema.Resource {
}

func resourceComputeSubnetworkCreate(d *schema.ResourceData, meta interface{}) error {
computeApiVersion := getComputeApiVersion(d, SubnetworkBaseApiVersion, SubnetworkVersionedFeatures)
config := meta.(*Config)
network, err := ParseNetworkFieldValue(d.Get("network").(string), d, config)
if err != nil {
Expand All @@ -142,18 +148,32 @@ func resourceComputeSubnetworkCreate(d *schema.ResourceData, meta interface{}) e
}

// Build the subnetwork parameters
subnetwork := &compute.Subnetwork{
subnetwork := &computeBeta.Subnetwork{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
IpCidrRange: d.Get("ip_cidr_range").(string),
PrivateIpGoogleAccess: d.Get("private_ip_google_access").(bool),
SecondaryIpRanges: expandSecondaryRanges(d.Get("secondary_ip_range").([]interface{})),
SecondaryIpRanges: expandSecondaryRangesV0Beta(d.Get("secondary_ip_range").([]interface{})),
Network: network.RelativeLink(),
EnableFlowLogs: d.Get("enable_flow_logs").(bool),
}

log.Printf("[DEBUG] Subnetwork insert request: %#v", subnetwork)

op, err := config.clientCompute.Subnetworks.Insert(project, region, subnetwork).Do()
subnetworkV1 := &compute.Subnetwork{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What're your thoughts on moving this struct creation into here as well as everything specific to subnetworkV1?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was that supposed to link to https://github.com/terraform-providers/terraform-provider-google/pull/1385/files#diff-c00013899b923b404c727949952f35ffR172 ?

The reason I didn't do that is because I need the struct accessible so I can generate the ID using it.

err = Convert(subnetwork, subnetworkV1)
if err != nil {
return err
}
subnetworkV1.ForceSendFields = subnetwork.ForceSendFields

var op interface{}
switch computeApiVersion {
case v1:
op, err = config.clientCompute.Subnetworks.Insert(project, region, subnetworkV1).Do()
case v0beta:
op, err = config.clientComputeBeta.Subnetworks.Insert(project, region, subnetwork).Do()
}

if err != nil {
return fmt.Errorf("Error creating subnetwork: %s", err)
Expand All @@ -164,8 +184,9 @@ func resourceComputeSubnetworkCreate(d *schema.ResourceData, meta interface{}) e
// "When creating a new subnetwork, its name has to be unique in that project for that region, even across networks.
// The same name can appear twice in a project, as long as each one is in a different region."
// https://cloud.google.com/compute/docs/subnetworks
subnetworkV1.Region = region
subnetwork.Region = region
d.SetId(createSubnetID(subnetwork))
d.SetId(createSubnetID(subnetworkV1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we set the id based on which subnet version (beta or release api) the request was sent to? Or is the id not generated from the api?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ID is (by design) the same between beta and v1; it's just the project and subnetwork, if I recall correctly. Basically, createSubnetID is a helper function for fmt.Sprintf("%s/%s/%s", subnetworkV1.Project, subnetworkV1.Region, subnetworkV1.Name) or what have you. So it's entirely generated from user input.


err = computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutCreate).Minutes()), "Creating Subnetwork")
if err != nil {
Expand Down Expand Up @@ -243,6 +264,7 @@ func resourceComputeSubnetworkReadV0Beta(d *schema.ResourceData, meta interface{
d.Set("secondary_ip_range", flattenSecondaryRangesV0Beta(subnetwork.SecondaryIpRanges))
d.Set("project", project)
d.Set("region", region)
d.Set("enable_flow_logs", subnetwork.EnableFlowLogs)
d.Set("self_link", ConvertSelfLinkToV1(subnetwork.SelfLink))
d.Set("fingerprint", subnetwork.Fingerprint)

Expand Down Expand Up @@ -306,24 +328,31 @@ func resourceComputeSubnetworkUpdate(d *schema.ResourceData, meta interface{}) e
d.SetPartial("ip_cidr_range")
}

if d.HasChange("secondary_ip_range") && computeApiVersion == v0beta {
if (d.HasChange("secondary_ip_range") || d.HasChange("enable_flow_logs")) && computeApiVersion == v0beta {
v0BetaSubnetwork := &computeBeta.Subnetwork{
SecondaryIpRanges: expandSecondaryRangesV0Beta(d.Get("secondary_ip_range").([]interface{})),
Fingerprint: d.Get("fingerprint").(string),
Fingerprint: d.Get("fingerprint").(string),
}
if d.HasChange("secondary_ip_range") {
v0BetaSubnetwork.SecondaryIpRanges = expandSecondaryRangesV0Beta(d.Get("secondary_ip_range").([]interface{}))
}
if d.HasChange("enable_flow_logs") {
v0BetaSubnetwork.EnableFlowLogs = d.Get("enable_flow_logs").(bool)
v0BetaSubnetwork.ForceSendFields = append(v0BetaSubnetwork.ForceSendFields, "EnableFlowLogs")
}

op, err := config.clientComputeBeta.Subnetworks.Patch(
project, region, d.Get("name").(string), v0BetaSubnetwork).Do()
if err != nil {
return fmt.Errorf("Error updating subnetwork SecondaryIpRanges: %s", err)
return fmt.Errorf("Error updating subnetwork %q: %s", d.Id(), err)
}

err = computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutUpdate).Minutes()), "Updating Subnetwork SecondaryIpRanges")
err = computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutUpdate).Minutes()), "Updating Subnetwork")
if err != nil {
return err
}

d.SetPartial("secondary_ip_range")
d.SetPartial("enable_flow_logs")
}

d.Partial(false)
Expand Down
53 changes: 53 additions & 0 deletions google/resource_compute_subnetwork_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,42 @@ func TestAccComputeSubnetwork_secondaryIpRanges(t *testing.T) {
})
}

func TestAccComputeSubnetwork_flowLogs(t *testing.T) {
t.Parallel()

var subnetwork compute.Subnetwork

cnName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
subnetworkName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeSubnetworkDestroy,
Steps: []resource.TestStep{
{
Config: testAccComputeSubnetwork_flowLogs(cnName, subnetworkName, true),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeSubnetworkExists(
"google_compute_subnetwork.network-with-flow-logs", &subnetwork),
resource.TestCheckResourceAttr("google_compute_subnetwork.network-with-flow-logs",
"enable_flow_logs", "true"),
),
},
// no import, as import currently doesn't work for beta
{
Config: testAccComputeSubnetwork_flowLogs(cnName, subnetworkName, false),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeSubnetworkExists(
"google_compute_subnetwork.network-with-flow-logs", &subnetwork),
resource.TestCheckResourceAttr("google_compute_subnetwork.network-with-flow-logs",
"enable_flow_logs", "false"),
),
},
},
})
}

func testAccCheckComputeSubnetworkDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)

Expand Down Expand Up @@ -357,3 +393,20 @@ resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges"
}
`, cnName, subnetworkName)
}

func testAccComputeSubnetwork_flowLogs(cnName, subnetworkName string, enableLogs bool) string {
return fmt.Sprintf(`
resource "google_compute_network" "custom-test" {
name = "%s"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "network-with-flow-logs" {
name = "%s"
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
network = "${google_compute_network.custom-test.self_link}"
enable_flow_logs = %v
}
`, cnName, subnetworkName, enableLogs)
}