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

Add new resource loadbalancer #115

Merged
merged 24 commits into from
Dec 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Terraform v0.11.1
- [x] Vpc
- [x] Tag
- [x] VpcStatic
- [x] LoadBalancer



## Contributing
Expand Down
2 changes: 2 additions & 0 deletions qingcloud/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (
qingcloudResourceTypeVxNet = "vxnet"
qingcloudResourceTypeEIP = "eip"
qingcloudResourceTypeRouter = "router"
qingcloudResourceTypeLoadBalancer = "loadbalancer"

DEFAULT_ZONE = "pek3a"
DEFAULT_ENDPOINT = "https://api.qingcloud.com:443/iaas"
Expand All @@ -30,4 +31,5 @@ const (
resourceTagIds = "tag_ids"
resourceTagNames = "tag_names"
DEFAULT_TAG_COLOR = "#9f9bb7"
BasicNetworkID = "vxnet-0"
)
1 change: 0 additions & 1 deletion qingcloud/import_qingcloud_volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,3 @@ func TestAccQingcloudVolume_importBasic(t *testing.T) {
},
})
}

1 change: 1 addition & 0 deletions qingcloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func Provider() terraform.ResourceProvider {
"qingcloud_volume": resourceQingcloudVolume(),
"qingcloud_tag": resourceQingcloudTag(),
"qingcloud_vpc_static": resourceQingcloudVpcStatic(),
"qingcloud_loadbalancer": resourceQingcloudLoadBalancer(),
},
ConfigureFunc: providerConfigure,
}
Expand Down
22 changes: 22 additions & 0 deletions qingcloud/resource_help.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,25 @@ func getUpdateStringPointer(d *schema.ResourceData, key string) *string {
}
return qc.String(" ")
}

func getUpdateStringPointerInfo(d *schema.ResourceData, key string) (value *string, update bool) {
update = false
if d.HasChange(key) {
if d.Get(key).(string) != "" {
value = qc.String(d.Get(key).(string))
} else {
value = qc.String(" ")
}
update = !d.IsNewResource()
}
return
}

func getUpdateIntPointerInfo(d *schema.ResourceData, key string) (value *int, update bool) {
update = false
if d.HasChange(key) {
value = qc.Int(d.Get(key).(int))
update = !d.IsNewResource()
}
return
}
4 changes: 2 additions & 2 deletions qingcloud/resource_qingcloud_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func resourceQingcloudInstance() *schema.Resource {
resourceInstanceManagedVxnetID: &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "vxnet-0",
Default: BasicNetworkID,
},
resourceInstancePrivateIP: &schema.Schema{
Type: schema.TypeString,
Expand Down Expand Up @@ -182,7 +182,7 @@ func resourceQingcloudInstanceRead(d *schema.ResourceData, meta interface{}) err
d.Set(resourceInstanceManagedVxnetID, qc.StringValue(vxnet.VxNetID))
d.Set(resourceInstancePrivateIP, qc.StringValue(vxnet.PrivateIP))
} else {
d.Set(resourceInstanceManagedVxnetID, "vxnet-0")
d.Set(resourceInstanceManagedVxnetID, BasicNetworkID)
d.Set(resourceInstancePrivateIP, qc.StringValue(vxnet.PrivateIP))
}
}
Expand Down
2 changes: 1 addition & 1 deletion qingcloud/resource_qingcloud_instance_help.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func instanceUpdateChangeManagedVxNet(d *schema.ResourceData, meta interface{})
return fmt.Errorf("can not use selfManaged ip as Managed ip")
}
joinVxnetInput := new(qc.JoinVxNetInput)
if newV.(string) != "vxnet-0" && d.HasChange(resourceInstancePrivateIP) && d.Get(resourceInstancePrivateIP).(string) != "" {
if newV.(string) != BasicNetworkID && d.HasChange(resourceInstancePrivateIP) && d.Get(resourceInstancePrivateIP).(string) != "" {
newV = fmt.Sprintf("%s|%s", newV.(string), d.Get(resourceInstancePrivateIP).(string))
}
joinVxnetInput.Instances = []*string{qc.String(d.Id())}
Expand Down
219 changes: 219 additions & 0 deletions qingcloud/resource_qingcloud_loadbalancer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package qingcloud

import (
"fmt"

"github.com/hashicorp/terraform/helper/schema"
qc "github.com/yunify/qingcloud-sdk-go/service"
)

const (
resourceLoadBalancerType = "type"
resourceLoadBalancerPrivateIPs = "private_ips"
resourceLoadBalancerEipIDs = "eip_ids"
resourceLoadBalancerNodeCount = "node_count"
resourceLoadBalancerSecurityGroupID = "security_group_id"
resourceLoadBalancerVxnetID = "vxnet_id"
resourceLoadBalancerHttpHeaderSize = "http_header_size"
)

func resourceQingcloudLoadBalancer() *schema.Resource {

return &schema.Resource{
Create: resourceQingcloudLoadBalancerCreate,
Read: resourceQingcloudLoadBalancerRead,
Update: resourceQingcloudLoadBalancerUpdate,
Delete: resourceQingcloudLoadBalancerDelete,
Schema: map[string]*schema.Schema{
resourceName: &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
resourceDescription: &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
resourceLoadBalancerType: &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 0,
ValidateFunc: withinArrayInt(0, 1, 2, 3, 4, 5),
},
resourceLoadBalancerPrivateIPs: &schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Computed: true,
},
resourceLoadBalancerEipIDs: &schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
resourceLoadBalancerNodeCount: &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
resourceLoadBalancerSecurityGroupID: &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
resourceLoadBalancerVxnetID: &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: BasicNetworkID,
ForceNew: true,
},
resourceLoadBalancerHttpHeaderSize: &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 15,
ValidateFunc: withinArrayIntRange(1, 127),
},
resourceTagIds: tagIdsSchema(),
resourceTagNames: tagNamesSchema(),
},
}
}
func resourceQingcloudLoadBalancerUpdate(d *schema.ResourceData, meta interface{}) error {
if err := waitLoadBalancerLease(d, meta); err != nil {
return err
}
d.Partial(true)
if err := modifyLoadBalancerAttributes(d, meta); err != nil {
return err
}
d.SetPartial(resourceLoadBalancerPrivateIPs)
d.SetPartial(resourceLoadBalancerHttpHeaderSize)
d.SetPartial(resourceLoadBalancerSecurityGroupID)
d.SetPartial(resourceLoadBalancerNodeCount)
d.SetPartial(resourceName)
d.SetPartial(resourceDescription)
if d.HasChange(resourceLoadBalancerEipIDs) {
if err := updateLoadbalancerEips(d, meta); err != nil {
return err
}
}
d.SetPartial(resourceLoadBalancerEipIDs)
if d.HasChange(resourceLoadBalancerType) && !d.IsNewResource() {
if err := resizeLoadBalancer(qc.String(d.Id()), qc.Int(d.Get(resourceLoadBalancerType).(int)), meta); err != nil {
return err
}
}
d.SetPartial(resourceLoadBalancerType)
if err := resourceUpdateTag(d, meta, qingcloudResourceTypeLoadBalancer); err != nil {
return err
}
d.Partial(false)
return resourceQingcloudLoadBalancerRead(d, meta)
}

func resourceQingcloudLoadBalancerCreate(d *schema.ResourceData, meta interface{}) error {
clt := meta.(*QingCloudClient).loadbalancer
input := new(qc.CreateLoadBalancerInput)
input.LoadBalancerName, _ = getNamePointer(d)
input.VxNet = getSetStringPointer(d, resourceLoadBalancerVxnetID)
input.SecurityGroup = getSetStringPointer(d, resourceLoadBalancerSecurityGroupID)
input.HTTPHeaderSize = qc.Int(d.Get(resourceLoadBalancerHttpHeaderSize).(int))
if d.Get(resourceLoadBalancerNodeCount).(int) != 0 && qc.StringValue(input.VxNet) == BasicNetworkID {
input.NodeCount = qc.Int(d.Get(resourceLoadBalancerNodeCount).(int))
}
input.LoadBalancerType = qc.Int(d.Get(resourceLoadBalancerType).(int))
if _, ok := d.GetOk(resourceLoadBalancerPrivateIPs); ok {
privateIPs := d.Get(resourceLoadBalancerPrivateIPs).(*schema.Set).List()
if len(privateIPs) != 1 || d.Get(resourceLoadBalancerVxnetID).(string) == BasicNetworkID {
return fmt.Errorf("error private_ips info")
}
input.PrivateIP = qc.String(privateIPs[0].(string))
}
if qc.StringValue(input.VxNet) == BasicNetworkID {
var eips []*string
for _, value := range d.Get(resourceLoadBalancerEipIDs).(*schema.Set).List() {
eips = append(eips, qc.String(value.(string)))
}
input.EIPs = eips
}
var output *qc.CreateLoadBalancerOutput
var err error
simpleRetry(func() error {
output, err = clt.CreateLoadBalancer(input)
return isServerBusy(err)
})
if err != nil {
return err
}
d.SetId(qc.StringValue(output.LoadBalancerID))
if _, err = LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
return err
}
return resourceQingcloudLoadBalancerUpdate(d, meta)
}

func resourceQingcloudLoadBalancerRead(d *schema.ResourceData, meta interface{}) error {
clt := meta.(*QingCloudClient).loadbalancer
input := new(qc.DescribeLoadBalancersInput)
input.LoadBalancers = []*string{qc.String(d.Id())}
input.Verbose = qc.Int(1)
var output *qc.DescribeLoadBalancersOutput
var err error
simpleRetry(func() error {
output, err = clt.DescribeLoadBalancers(input)
return isServerBusy(err)
})
if err != nil {
return err
}
if isLoadBalancerDeleted(output.LoadBalancerSet) {
d.SetId("")
return nil
}
lb := output.LoadBalancerSet[0]
d.Set(resourceName, qc.StringValue(lb.LoadBalancerName))
d.Set(resourceDescription, qc.StringValue(lb.Description))
d.Set(resourceLoadBalancerType, qc.IntValue(lb.LoadBalancerType))
d.Set(resourceLoadBalancerVxnetID, qc.StringValue(lb.VxNetID))
d.Set(resourceLoadBalancerPrivateIPs, qc.StringValueSlice(lb.PrivateIPs))
d.Set(resourceLoadBalancerSecurityGroupID, qc.StringValue(lb.SecurityGroupID))
d.Set(resourceLoadBalancerNodeCount, qc.IntValue(lb.NodeCount))
var eipIDs []string
if d.Get(resourceLoadBalancerVxnetID) == BasicNetworkID {
for _, eip := range lb.Cluster {
eipIDs = append(eipIDs, qc.StringValue(eip.EIPID))
}
} else {
for _, eip := range lb.EIPs {
eipIDs = append(eipIDs, qc.StringValue(eip.EIPID))
}
}
d.Set(resourceLoadBalancerEipIDs, eipIDs)
resourceSetTag(d, lb.Tags)
return nil
}

func resourceQingcloudLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error {
clt := meta.(*QingCloudClient).loadbalancer
if _, err := LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
return err
}
if err := waitLoadBalancerLease(d, meta); err != nil {
return err
}
input := new(qc.DeleteLoadBalancersInput)
input.LoadBalancers = []*string{qc.String(d.Id())}
var output *qc.DeleteLoadBalancersOutput
var err error
simpleRetry(func() error {
output, err = clt.DeleteLoadBalancers(input)
return isServerBusy(err)
})
if err != nil {
return err
}
if _, err := LoadBalancerTransitionStateRefresh(clt, qc.String(d.Id())); err != nil {
return err
}
d.SetId("")
return nil
}
Loading