ServerGroup Resource

This commit adds a server group resource. Users can create server
groups with different policies. If a server is launched in a certain
group, the server will adhere to that policy. For example, servers
can be made to all launch on the same compute node or different compute
nodes.
This commit is contained in:
Joe Topjian 2015-05-05 16:38:15 +00:00
parent cb0374a7e3
commit b74e74fc16
4 changed files with 265 additions and 0 deletions

View File

@ -68,6 +68,7 @@ func Provider() terraform.ResourceProvider {
"openstack_compute_instance_v2": resourceComputeInstanceV2(),
"openstack_compute_keypair_v2": resourceComputeKeypairV2(),
"openstack_compute_secgroup_v2": resourceComputeSecGroupV2(),
"openstack_compute_servergroup_v2": resourceComputeServerGroupV2(),
"openstack_compute_floatingip_v2": resourceComputeFloatingIPV2(),
"openstack_fw_firewall_v1": resourceFWFirewallV1(),
"openstack_fw_policy_v1": resourceFWPolicyV1(),

View File

@ -0,0 +1,123 @@
package openstack
import (
"fmt"
"log"
"github.com/hashicorp/terraform/helper/schema"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/servergroups"
)
func resourceComputeServerGroupV2() *schema.Resource {
return &schema.Resource{
Create: resourceComputeServerGroupV2Create,
Read: resourceComputeServerGroupV2Read,
Update: nil,
Delete: resourceComputeServerGroupV2Delete,
Schema: map[string]*schema.Schema{
"region": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
DefaultFunc: envDefaultFuncAllowMissing("OS_REGION_NAME"),
},
"name": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"policies": &schema.Schema{
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"members": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}
func resourceComputeServerGroupV2Create(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
computeClient, err := config.computeV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack compute client: %s", err)
}
createOpts := &servergroups.CreateOpts{
Name: d.Get("name").(string),
Policies: resourceServerGroupPoliciesV2(d),
}
log.Printf("[DEBUG] Create Options: %#v", createOpts)
newSG, err := servergroups.Create(computeClient, createOpts).Extract()
if err != nil {
return fmt.Errorf("Error creating ServerGroup", err)
}
d.SetId(newSG.ID)
return resourceComputeServerGroupV2Read(d, meta)
}
func resourceComputeServerGroupV2Read(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
computeClient, err := config.computeV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack compute client: %s", err)
}
sg, err := servergroups.Get(computeClient, d.Id()).Extract()
if err != nil {
return CheckDeleted(d, err, "server group")
}
log.Printf("[DEBUG] Retrieved ServerGroup %s: %+v", d.Id(), sg)
// Set the name
d.Set("name", sg.Name)
// Set the policies
policies := []string{}
for _, p := range sg.Policies {
policies = append(policies, p)
}
d.Set("policies", policies)
// Set the members
members := []string{}
for _, m := range sg.Members {
members = append(members, m)
}
d.Set("members", members)
return nil
}
func resourceComputeServerGroupV2Delete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
computeClient, err := config.computeV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack compute client: %s", err)
}
log.Printf("[DEBUG] Deleting ServerGroup %s", d.Id())
if err := servergroups.Delete(computeClient, d.Id()).ExtractErr(); err != nil {
return fmt.Errorf("Error deleting ServerGroup: %s", err)
}
return nil
}
func resourceServerGroupPoliciesV2(d *schema.ResourceData) []string {
rawPolicies := d.Get("policies").([]interface{})
policies := make([]string, len(rawPolicies))
for i, raw := range rawPolicies {
policies[i] = raw.(string)
}
return policies
}

View File

@ -0,0 +1,88 @@
package openstack
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/servergroups"
)
func TestAccComputeV2ServerGroup_basic(t *testing.T) {
var serverGroup servergroups.ServerGroup
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeV2ServerGroupDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeV2ServerGroup_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeV2ServerGroupExists(t, "openstack_compute_servergroup_v2.mysg", &serverGroup),
),
},
},
})
}
func testAccCheckComputeV2ServerGroupDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
computeClient, err := config.computeV2Client(OS_REGION_NAME)
if err != nil {
return fmt.Errorf("(testAccCheckComputeV2ServerGroupDestroy) Error creating OpenStack compute client: %s", err)
}
for _, rs := range s.RootModule().Resources {
if rs.Type != "openstack_compute_servergroup_v2" {
continue
}
_, err := servergroups.Get(computeClient, rs.Primary.ID).Extract()
if err == nil {
return fmt.Errorf("ServerGroup still exists")
}
}
return nil
}
func testAccCheckComputeV2ServerGroupExists(t *testing.T, n string, kp *servergroups.ServerGroup) 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)
computeClient, err := config.computeV2Client(OS_REGION_NAME)
if err != nil {
return fmt.Errorf("(testAccCheckComputeV2ServerGroupExists) Error creating OpenStack compute client: %s", err)
}
found, err := servergroups.Get(computeClient, rs.Primary.ID).Extract()
if err != nil {
return err
}
if found.ID != rs.Primary.ID {
return fmt.Errorf("ServerGroup not found")
}
*kp = *found
return nil
}
}
var testAccComputeV2ServerGroup_basic = `
resource "openstack_compute_servergroup_v2" "mysg" {
name = "my server group"
policies = ["affinity"]
}`

View File

@ -0,0 +1,53 @@
---
layout: "openstack"
page_title: "OpenStack: openstack_compute_servergroup_v2"
sidebar_current: "docs-openstack-resource-compute-servergroup-v2"
description: |-
Manages a V2 Server Group resource within OpenStack.
---
# openstack\_compute\_servergroup_v2
Manages a V2 Server Group resource within OpenStack.
## Example Usage
```
resource "openstack_compute_servergroup_v2" "test-sg" {
name = "my-sg"
policies = ["anti-affinity"]
}
```
## Argument Reference
The following arguments are supported:
* `region` - (Required) The region in which to obtain the V2 Compute client.
If omitted, the `OS_REGION_NAME` environment variable is used. Changing
this creates a new server group.
* `name` - (Required) A unique name for the server group. Changing this creates
a new server group.
* `policies` - (Required) The set of policies for the server group. Only two
two policies are available right now, and both are mutually exclusive. See
the Policies section for more information. Changing this creates a new
server group.
## Policies
* `affinity` - All instances/servers launched in this group will be hosted on
the same compute node.
* `anti-affinity` - All instances/servers launched in this group will be
hosted on different compute nodes.
## Attributes Reference
The following attributes are exported:
* `region` - See Argument Reference above.
* `name` - See Argument Reference above.
* `policies` - See Argument Reference above.
* `members` - The instances that are part of this server group.