Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
148 changes: 133 additions & 15 deletions cloudstack/resource_cloudstack_service_offering.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package cloudstack
import (
"fmt"
"log"
"strconv"

"github.com/apache/cloudstack-go/v2/cloudstack"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -97,6 +98,48 @@ func resourceCloudStackServiceOffering() *schema.Resource {
return
},
},
"customized": {
Description: "Whether service offering allows custom CPU/memory or not",
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Computed: true,
},
"min_cpu_number": {
Description: "Minimum number of CPU cores allowed",
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
"max_cpu_number": {
Description: "Maximum number of CPU cores allowed",
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
"min_memory": {
Description: "Minimum memory allowed (MB)",
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
"max_memory": {
Description: "Maximum memory allowed (MB)",
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
"encrypt_root": {
Description: "Encrypt the root disk for VMs using this service offering",
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},
"storage_tags": {
Description: "Storage tags to associate with the service offering",
Type: schema.TypeString,
Optional: true,
},
},
}
}
Expand All @@ -108,12 +151,15 @@ func resourceCloudStackServiceOfferingCreate(d *schema.ResourceData, meta interf

// Create a new parameter struct
p := cs.ServiceOffering.NewCreateServiceOfferingParams(display_text, name)
if v, ok := d.GetOk("cpu_number"); ok {
p.SetCpunumber(v.(int))

cpuNumber, cpuNumberOk := d.GetOk("cpu_number")
if cpuNumberOk {
p.SetCpunumber(cpuNumber.(int))
}

if v, ok := d.GetOk("cpu_speed"); ok {
p.SetCpuspeed(v.(int))
cpuSpeed, cpuSpeedOk := d.GetOk("cpu_speed")
if cpuSpeedOk {
p.SetCpuspeed(cpuSpeed.(int))
}

if v, ok := d.GetOk("host_tags"); ok {
Expand All @@ -124,8 +170,9 @@ func resourceCloudStackServiceOfferingCreate(d *schema.ResourceData, meta interf
p.SetLimitcpuuse(v.(bool))
}

if v, ok := d.GetOk("memory"); ok {
p.SetMemory(v.(int))
memory, memoryOk := d.GetOk("memory")
if memoryOk {
p.SetMemory(memory.(int))
}

if v, ok := d.GetOk("offer_ha"); ok {
Expand All @@ -136,6 +183,39 @@ func resourceCloudStackServiceOfferingCreate(d *schema.ResourceData, meta interf
p.SetStoragetype(v.(string))
}

customized := false
if v, ok := d.GetOk("customized"); ok {
customized = v.(bool)
}
if !cpuNumberOk && !cpuSpeedOk && !memoryOk {
customized = true
}
p.SetCustomized(customized)

if v, ok := d.GetOk("min_cpu_number"); ok {
p.SetMincpunumber(v.(int))
}

if v, ok := d.GetOk("max_cpu_number"); ok {
p.SetMaxcpunumber(v.(int))
}

if v, ok := d.GetOk("min_memory"); ok {
p.SetMinmemory(v.(int))
}

if v, ok := d.GetOk("max_memory"); ok {
p.SetMaxmemory(v.(int))
}

if v, ok := d.GetOk("encrypt_root"); ok {
p.SetEncryptroot(v.(bool))
}

if v, ok := d.GetOk("storage_tags"); ok {
p.SetTags(v.(string))
}

log.Printf("[DEBUG] Creating Service Offering %s", name)
s, err := cs.ServiceOffering.CreateServiceOffering(p)

Expand Down Expand Up @@ -168,15 +248,22 @@ func resourceCloudStackServiceOfferingRead(d *schema.ResourceData, meta interfac
d.SetId(s.Id)

fields := map[string]interface{}{
"name": s.Name,
"display_text": s.Displaytext,
"cpu_number": s.Cpunumber,
"cpu_speed": s.Cpuspeed,
"host_tags": s.Hosttags,
"limit_cpu_use": s.Limitcpuuse,
"memory": s.Memory,
"offer_ha": s.Offerha,
"storage_type": s.Storagetype,
"name": s.Name,
"display_text": s.Displaytext,
"cpu_number": s.Cpunumber,
"cpu_speed": s.Cpuspeed,
"host_tags": s.Hosttags,
"limit_cpu_use": s.Limitcpuuse,
"memory": s.Memory,
"offer_ha": s.Offerha,
"storage_type": s.Storagetype,
"customized": s.Iscustomized,
"min_cpu_number": getIntFromDetails(s.Serviceofferingdetails, "mincpunumber"),
"max_cpu_number": getIntFromDetails(s.Serviceofferingdetails, "maxcpunumber"),
"min_memory": getIntFromDetails(s.Serviceofferingdetails, "minmemory"),
"max_memory": getIntFromDetails(s.Serviceofferingdetails, "maxmemory"),
"encrypt_root": s.Encryptroot,
"storage_tags": s.Storagetags,
}

for k, v := range fields {
Expand Down Expand Up @@ -247,6 +334,24 @@ func resourceCloudStackServiceOfferingUpdate(d *schema.ResourceData, meta interf

}

if d.HasChange("storage_tags") {
log.Printf("[DEBUG] Tags changed for %s, starting update", name)

// Create a new parameter struct
p := cs.ServiceOffering.NewUpdateServiceOfferingParams(d.Id())

// Set the new tags
p.SetStoragetags(d.Get("storage_tags").(string))

// Update the host tags
_, err := cs.ServiceOffering.UpdateServiceOffering(p)
if err != nil {
return fmt.Errorf(
"Error updating the storage tags for service offering %s: %s", name, err)
}

}

return resourceCloudStackServiceOfferingRead(d, meta)
}

Expand All @@ -263,3 +368,16 @@ func resourceCloudStackServiceOfferingDelete(d *schema.ResourceData, meta interf

return nil
}

// getIntFromDetails extracts an integer value from the service offering details map.
func getIntFromDetails(details map[string]string, key string) interface{} {
if details == nil {
return nil
}
if val, ok := details[key]; ok {
if i, err := strconv.Atoi(val); err == nil {
return i
}
}
return nil
}
39 changes: 39 additions & 0 deletions cloudstack/resource_cloudstack_service_offering_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,42 @@ func testAccCheckCloudStackServiceOfferingExists(n string, so *cloudstack.Servic
return nil
}
}

func TestAccCloudStackServiceOffering_customized(t *testing.T) {
var so cloudstack.ServiceOffering
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCloudStackServiceOffering_customized,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudStackServiceOfferingExists("cloudstack_service_offering.custom", &so),
resource.TestCheckResourceAttr("cloudstack_service_offering.custom", "customized", "true"),
resource.TestCheckResourceAttr("cloudstack_service_offering.custom", "min_cpu_number", "1"),
resource.TestCheckResourceAttr("cloudstack_service_offering.custom", "max_cpu_number", "8"),
resource.TestCheckResourceAttr("cloudstack_service_offering.custom", "min_memory", "1024"),
resource.TestCheckResourceAttr("cloudstack_service_offering.custom", "max_memory", "16384"),
resource.TestCheckResourceAttr("cloudstack_service_offering.custom", "cpu_speed", "1000"),
resource.TestCheckResourceAttr("cloudstack_service_offering.custom", "encrypt_root", "true"),
resource.TestCheckResourceAttr("cloudstack_service_offering.custom", "storage_tags", "production,ssd"),
),
},
},
})
}

const testAccCloudStackServiceOffering_customized = `
resource "cloudstack_service_offering" "custom" {
name = "custom_service_offering"
display_text = "Custom Test"
customized = true
min_cpu_number = 1
max_cpu_number = 8
min_memory = 1024
max_memory = 16384
cpu_speed = 1000
encrypt_root = true
storage_tags = "production,ssd"
}
`
20 changes: 20 additions & 0 deletions website/docs/r/service_offering.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ The following arguments are supported:
* `storage_type` - (Optional) The storage type of the service offering. Values are `local` and `shared`.
Changing this forces a new resource to be created.

* `customized` - (Optional) Whether the service offering allows custom CPU and memory values. Set to `true` to enable users to specify CPU/memory within the min/max constraints for constrained offerings and any value for unconstrained offerings.
Changing this forces a new resource to be created.

* `min_cpu_number` - (Optional) Minimum number of CPU cores allowed for customized offerings.
Changing this forces a new resource to be created.

* `max_cpu_number` - (Optional) Maximum number of CPU cores allowed for customized offerings.
Changing this forces a new resource to be created.

* `min_memory` - (Optional) Minimum memory (in MB) allowed for customized offerings.
Changing this forces a new resource to be created.

* `max_memory` - (Optional) Maximum memory (in MB) allowed for customized offerings.
Changing this forces a new resource to be created.

* `encrypt_root` - (Optional) Whether to encrypt the root disk for VMs using this service offering.
Changing this forces a new resource to be created.

* `storage_tags` - (Optional) Storage tags to associate with the service offering.

## Attributes Reference

The following attributes are exported:
Expand Down
Loading