Skip to content

Commit

Permalink
Merge pull request #203 from niuzhenguo/add-bandwidth
Browse files Browse the repository at this point in the history
Add Shared Bandwidth V2 support
  • Loading branch information
niuzhenguo authored Sep 9, 2019
2 parents d4a5cda + 22834f6 commit 2750d4e
Show file tree
Hide file tree
Showing 14 changed files with 720 additions and 5 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/hashicorp/errwrap v1.0.0
github.com/hashicorp/go-cleanhttp v0.5.0
github.com/hashicorp/terraform v0.12.0
github.com/huaweicloud/golangsdk v0.0.0-20190902122622-e395391e1f19
github.com/huaweicloud/golangsdk v0.0.0-20190906094835-10f659f0ae54
github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a
github.com/mitchellh/go-homedir v1.0.0
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ github.com/hashicorp/vault v0.10.4/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bA
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huaweicloud/golangsdk v0.0.0-20190902122622-e395391e1f19 h1:FUlribrcVGqGR4irupy34lbps5BPTJMurJ+kt/zxDmM=
github.com/huaweicloud/golangsdk v0.0.0-20190902122622-e395391e1f19/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw=
github.com/huaweicloud/golangsdk v0.0.0-20190906094835-10f659f0ae54 h1:M4DStISEwrjmVtNkd/8UAaAOAkMa6HswIaCQMnQ02ns=
github.com/huaweicloud/golangsdk v0.0.0-20190906094835-10f659f0ae54/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a h1:FyS/ubzBR5xJlnJGRTwe7GUHpJOR4ukYK3y+LFNffuA=
github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a/go.mod h1:uoIMjNxUfXi48Ci40IXkPRbghZ1vbti6v9LCbNqRgHY=
Expand Down
3 changes: 2 additions & 1 deletion huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,12 @@ func Provider() terraform.ResourceProvider {
"huaweicloud_rds_instance_v1": resourceRdsInstance(),
"huaweicloud_nat_gateway_v2": resourceNatGatewayV2(),
"huaweicloud_nat_snat_rule_v2": resourceNatSnatRuleV2(),
"huaweicloud_vpc_eip_v1": resourceVpcEIPV1(),
"huaweicloud_sfs_file_system_v2": resourceSFSFileSystemV2(),
"huaweicloud_rts_stack_v1": resourceRTSStackV1(),
"huaweicloud_iam_agency_v3": resourceIAMAgencyV3(),
"huaweicloud_vpc_v1": resourceVirtualPrivateCloudV1(),
"huaweicloud_vpc_bandwidth_v2": resourceVpcBandWidthV2(),
"huaweicloud_vpc_eip_v1": resourceVpcEIPV1(),
"huaweicloud_vpc_peering_connection_v2": resourceVpcPeeringConnectionV2(),
"huaweicloud_vpc_peering_connection_accepter_v2": resourceVpcPeeringConnectionAccepterV2(),
"huaweicloud_vpc_route_v2": resourceVPCRouteV2(),
Expand Down
190 changes: 190 additions & 0 deletions huaweicloud/resource_huaweicloud_vpc_bandwidth_v2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package huaweicloud

import (
"fmt"
"log"
"time"

"github.com/huaweicloud/golangsdk"
bandwidthsv1 "github.com/huaweicloud/golangsdk/openstack/networking/v1/bandwidths"
"github.com/huaweicloud/golangsdk/openstack/networking/v2/bandwidths"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceVpcBandWidthV2() *schema.Resource {
return &schema.Resource{
Create: resourceVpcBandWidthV2Create,
Read: resourceVpcBandWidthV2Read,
Update: resourceVpcBandWidthV2Update,
Delete: resourceVpcBandWidthV2Delete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(10 * time.Minute),
Update: schema.DefaultTimeout(10 * time.Minute),
Delete: schema.DefaultTimeout(10 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: false,
},
"size": {
Type: schema.TypeInt,
Required: true,
ForceNew: false,
ValidateFunc: validateIntegerInRange(5, 2000),
},
"enterprise_project_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
},
}
}

func resourceVpcBandWidthV2Create(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(GetRegion(d, config))
networkingV1Client, err := config.networkingV1Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating networking client: %s", err)
}

size := d.Get("size").(int)
createOpts := bandwidths.CreateOpts{
Name: d.Get("name").(string),
Size: &size,
EnterpriseProjectId: d.Get("enterprise_project_id").(string),
}

log.Printf("[DEBUG] Create Options: %#v", createOpts)
b, err := bandwidths.Create(networkingClient, createOpts).Extract()
if err != nil {
return fmt.Errorf("Error creating Bandwidth: %s", err)
}

log.Printf("[DEBUG] Waiting for Bandwidth (%s) to become available.", b.ID)
stateConf := &resource.StateChangeConf{
Target: []string{"NORMAL"},
Pending: []string{"CREATING"},
Refresh: waitForBandwidth(networkingV1Client, b.ID),
Timeout: d.Timeout(schema.TimeoutCreate),
Delay: 3 * time.Second,
MinTimeout: 3 * time.Second,
}

_, err = stateConf.WaitForState()

if err != nil {
return fmt.Errorf(
"Error waiting for Bandwidth (%s) to become ACTIVE for creation: %s",
b.ID, err)
}
d.SetId(b.ID)

return resourceVpcBandWidthV2Read(d, meta)
}

func resourceVpcBandWidthV2Update(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating networking client: %s", err)
}

var bandwidthOpts bandwidths.Bandwidth

if d.HasChange("name") {
bandwidthOpts.Name = d.Get("name").(string)
}
if d.HasChange("size") {
bandwidthOpts.Size = d.Get("size").(int)
}

if bandwidthOpts != (bandwidths.Bandwidth{}) {
updateOpts := bandwidths.UpdateOpts{
Bandwidth: bandwidthOpts,
}
_, err := bandwidths.Update(networkingClient, d.Id(), updateOpts)
if err != nil {
return fmt.Errorf("Error updating Huaweicloud BandWidth (%s): %s", d.Id(), err)
}
}

return resourceVpcBandWidthV2Read(d, meta)
}

func resourceVpcBandWidthV2Read(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV1Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating networking client: %s", err)
}

b, err := bandwidthsv1.Get(networkingClient, d.Id()).Extract()
if err != nil {
return CheckDeleted(d, err, "bandwidth")
}

d.Set("name", b.Name)
d.Set("size", b.Size)
d.Set("enterprise_project_id", b.EnterpriseProjectID)

return nil
}

func resourceVpcBandWidthV2Delete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(GetRegion(d, config))
networkingV1Client, err := config.networkingV1Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating networking client: %s", err)
}

err = bandwidths.Delete(networkingClient, d.Id()).ExtractErr()
if err != nil {
return fmt.Errorf("Error deleting HuaweiCloud Bandwidth: %s", err)
}

stateConf := &resource.StateChangeConf{
Pending: []string{"ACTIVE"},
Target: []string{"DELETED"},
Refresh: waitForBandwidth(networkingV1Client, d.Id()),
Timeout: d.Timeout(schema.TimeoutDelete),
Delay: 3 * time.Second,
MinTimeout: 3 * time.Second,
}

_, err = stateConf.WaitForState()
if err != nil {
return fmt.Errorf("Error deleting Bandwidth: %s", err)
}

d.SetId("")

return nil
}

func waitForBandwidth(networkingClient *golangsdk.ServiceClient, Id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
b, err := bandwidthsv1.Get(networkingClient, Id).Extract()
if err != nil {
if _, ok := err.(golangsdk.ErrDefault404); ok {
return b, "DELETED", nil
}
return nil, "", err
}

log.Printf("[DEBUG] HuaweiCloud Bandwidth (%s) current status: %s", b.ID, b.Status)
return b, b.Status, nil
}
}
106 changes: 106 additions & 0 deletions huaweicloud/resource_huaweicloud_vpc_bandwidth_v2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package huaweicloud

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"

"github.com/huaweicloud/golangsdk/openstack/networking/v1/bandwidths"
)

func TestAccVpcBandWidthV2_basic(t *testing.T) {
var bandwidth bandwidths.BandWidth

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckVpcBandWidthV2Destroy,
Steps: []resource.TestStep{
{
Config: testAccVpcBandWidthV2_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckVpcBandWidthV2Exists("huaweicloud_vpc_bandwidth_v2.bandwidth_1", &bandwidth),
resource.TestCheckResourceAttr(
"huaweicloud_vpc_bandwidth_v2.bandwidth_1", "name", "bandwidth_1"),
),
},
{
Config: testAccVpcBandWidthV2_update,
Check: resource.ComposeTestCheckFunc(
testAccCheckVpcBandWidthV2Exists("huaweicloud_vpc_bandwidth_v2.bandwidth_1", &bandwidth),
resource.TestCheckResourceAttr(
"huaweicloud_vpc_bandwidth_v2.bandwidth_1", "name", "bandwidth_1_updated"),
resource.TestCheckResourceAttr(
"huaweicloud_vpc_bandwidth_v2.bandwidth_1", "size", "6"),
),
},
},
})
}

func testAccCheckVpcBandWidthV2Destroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
networkingClient, err := config.networkingV1Client(OS_REGION_NAME)
if err != nil {
return fmt.Errorf("Error creating huaweicloud networking client: %s", err)
}

for _, rs := range s.RootModule().Resources {
if rs.Type != "huaweicloud_vpc_bandwidth_v2" {
continue
}

_, err := bandwidths.Get(networkingClient, rs.Primary.ID).Extract()
if err == nil {
return fmt.Errorf("BandWidth still exists")
}
}

return nil
}

func testAccCheckVpcBandWidthV2Exists(n string, bandwidth *bandwidths.BandWidth) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}

config := testAccProvider.Meta().(*Config)
networkingClient, err := config.networkingV1Client(OS_REGION_NAME)
if err != nil {
return fmt.Errorf("Error creating huaweicloud networking client: %s", err)
}

found, err := bandwidths.Get(networkingClient, rs.Primary.ID).Extract()
if err != nil {
return err
}

if found.ID != rs.Primary.ID {
return fmt.Errorf("bandwidth not found")
}

*bandwidth = found

return nil
}
}

const testAccVpcBandWidthV2_basic = `
resource "huaweicloud_vpc_bandwidth_v2" "bandwidth_1" {
name = "bandwidth_1"
size = 5
}`

const testAccVpcBandWidthV2_update = `
resource "huaweicloud_vpc_bandwidth_v2" "bandwidth_1" {
name = "bandwidth_1_updated"
size = 6
}`
13 changes: 13 additions & 0 deletions huaweicloud/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"regexp"
"strings"
"time"

"github.com/hashicorp/terraform/helper/schema"
)

func ValidateStringList(v interface{}, k string, l []string) (ws []string, errors []error) {
Expand Down Expand Up @@ -287,3 +289,14 @@ func validateECSTagValue(v interface{}, k string) (ws []string, errors []error)
}
return
}

func validateIntegerInRange(min, max int) schema.SchemaValidateFunc {
return func(v interface{}, k string) (ws []string, errors []error) {
value := v.(int)
if value < min || value > max {
errors = append(errors, fmt.Errorf(
"%q cannot be lower than %d and larger than %d. Current value is %d.", k, min, max, value))
}
return
}
}
6 changes: 6 additions & 0 deletions vendor/github.com/huaweicloud/golangsdk/openstack/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2750d4e

Please sign in to comment.