vishesh92 commented on code in PR #113: URL: https://github.com/apache/cloudstack-terraform-provider/pull/113#discussion_r1662924675
########## cloudstack/resource_cloudstack_service_offering.go: ########## @@ -20,246 +20,735 @@ package cloudstack import ( + "context" "fmt" - "log" - "github.com/apache/cloudstack-go/v2/cloudstack" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-framework-validators/boolvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" ) -func resourceCloudStackServiceOffering() *schema.Resource { - return &schema.Resource{ - Create: resourceCloudStackServiceOfferingCreate, - Read: resourceCloudStackServiceOfferingRead, - Update: resourceCloudStackServiceOfferingUpdate, - Delete: resourceCloudStackServiceOfferingDelete, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - }, - "display_text": { - Type: schema.TypeString, - Required: true, - }, - "cpu_number": { +func NewCloudstackServiceOfferingResource() resource.Resource { + return &resourceCloudstackServiceOffering{} +} + +type resourceCloudstackServiceOffering struct { + ResourceWithConfigure +} + +type resourceCloudStackServiceOfferingModel struct { + Name types.String `tfsdk:"name"` + DisplayText types.String `tfsdk:"display_text"` + Customized types.Bool `tfsdk:"customized"` + CpuNumber types.Int64 `tfsdk:"cpu_number"` + CpuNumberMin types.Int64 `tfsdk:"cpu_number_min"` + CpuNumberMax types.Int64 `tfsdk:"cpu_number_max"` + CpuSpeed types.Int64 `tfsdk:"cpu_speed"` + Memory types.Int64 `tfsdk:"memory"` + MemoryMin types.Int64 `tfsdk:"memory_min"` + MemoryMax types.Int64 `tfsdk:"memory_max"` + HostTags types.String `tfsdk:"host_tags"` + NetworkRate types.Int64 `tfsdk:"network_rate"` + OfferHa types.Bool `tfsdk:"offer_ha"` + DynamicScaling types.Bool `tfsdk:"dynamic_scaling"` + LimitCpuUse types.Bool `tfsdk:"limit_cpu_use"` + Volatile types.Bool `tfsdk:"volatile"` + DeploymentPlanner types.String `tfsdk:"deployment_planner"` + ZoneId types.List `tfsdk:"zone_id"` + DiskOfferingId types.String `tfsdk:"disk_offering_id"` + StorageType types.String `tfsdk:"storage_type"` + ProvisioningType types.String `tfsdk:"provisioning_type"` + WriteCacheType types.String `tfsdk:"write_cache_type"` + QosType types.String `tfsdk:"qos_type"` + DiskReadRateBps types.Int64 `tfsdk:"disk_read_rate_bps"` + DiskWriteRateBps types.Int64 `tfsdk:"disk_write_rate_bps"` + DiskReadRateIops types.Int64 `tfsdk:"disk_read_rate_iops"` + DiskWriteRateIops types.Int64 `tfsdk:"disk_write_rate_iops"` + CustomIops types.Bool `tfsdk:"custom_iops"` + MinIops types.Int64 `tfsdk:"min_iops"` + MaxIops types.Int64 `tfsdk:"max_iops"` + HypervisorSnapshotReserve types.Int64 `tfsdk:"hypervisor_snapshot_reserve"` + RootDiskSize types.Int64 `tfsdk:"root_disk_size"` + StorageTags types.String `tfsdk:"storage_tags"` + Encrypt types.Bool `tfsdk:"encrypt"` + DiskOfferingStrictness types.Bool `tfsdk:"disk_offering_strictness"` + Id types.String `tfsdk:"id"` +} + +func (r *resourceCloudstackServiceOffering) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = fmt.Sprintf("%s_service_offering", req.ProviderTypeName) +} + +func (r *resourceCloudstackServiceOffering) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Description: "The name of the service offering", + Required: true, + }, + "display_text": schema.StringAttribute{ + Description: "The display text of the service offering", + Required: true, + }, + "customized": schema.BoolAttribute{ + Description: "Is the service offering customized", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Default: booldefault.StaticBool(false), + Validators: []validator.Bool{ + boolvalidator.ConflictsWith(path.MatchRoot("cpu_number"), path.MatchRoot("memory")), + }, + }, + "cpu_number": schema.Int64Attribute{ Description: "Number of CPU cores", - Type: schema.TypeInt, Optional: true, - ForceNew: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("cpu_number_min"), path.MatchRoot("cpu_number_max")), + }, + }, + "cpu_number_min": schema.Int64Attribute{ + Description: "Minimum number of CPU cores", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.AlsoRequires(path.MatchRoot("cpu_number_max")), + int64validator.AtMostSumOf(path.MatchRoot("cpu_number_max")), + int64validator.ConflictsWith(path.MatchRoot("cpu_number")), + }, + }, + "cpu_number_max": schema.Int64Attribute{ + Description: "Maximum number of CPU cores", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.AlsoRequires(path.MatchRoot("cpu_number_min")), + int64validator.AtLeastSumOf(path.MatchRoot("cpu_number_min")), + int64validator.ConflictsWith(path.MatchRoot("cpu_number")), + }, }, - "cpu_speed": { + "cpu_speed": schema.Int64Attribute{ Description: "Speed of CPU in Mhz", - Type: schema.TypeInt, + Required: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "memory": schema.Int64Attribute{ + Description: "The total memory of the service offering in MB", Optional: true, - ForceNew: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("memory_min"), path.MatchRoot("memory_max")), + }, }, - "host_tags": { + "memory_min": schema.Int64Attribute{ + Description: "Minimum memory of the service offering in MB", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.AlsoRequires(path.MatchRoot("memory_max")), + int64validator.AtMostSumOf(path.MatchRoot("memory_max")), + int64validator.ConflictsWith(path.MatchRoot("memory")), + }, + }, + "memory_max": schema.Int64Attribute{ + Description: "Maximum memory of the service offering in MB", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.AlsoRequires(path.MatchRoot("memory_min")), + int64validator.AtLeastSumOf(path.MatchRoot("memory_min")), + int64validator.ConflictsWith(path.MatchRoot("memory")), + }, + }, + "host_tags": schema.StringAttribute{ Description: "The host tag for this service offering", - Type: schema.TypeString, Optional: true, + Computed: true, + }, + "network_rate": schema.Int64Attribute{ + Description: "Data transfer rate in megabits per second", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "offer_ha": schema.BoolAttribute{ + Description: "The HA for the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Default: booldefault.StaticBool(false), + }, + "dynamic_scaling": schema.BoolAttribute{ + Description: "Enable dynamic scaling of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Default: booldefault.StaticBool(false), }, - "limit_cpu_use": { + "limit_cpu_use": schema.BoolAttribute{ Description: "Restrict the CPU usage to committed service offering", - Type: schema.TypeBool, Optional: true, - ForceNew: true, - Default: false, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Default: booldefault.StaticBool(false), }, - "memory": { - Description: "The total memory of the service offering in MB", - Type: schema.TypeInt, + "volatile": schema.BoolAttribute{ + Description: "Service offering is volatile", Optional: true, - ForceNew: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Default: booldefault.StaticBool(false), }, - "offer_ha": { - Description: "The HA for the service offering", - Type: schema.TypeBool, + "deployment_planner": schema.StringAttribute{ + Description: "The deployment planner for the service offering", Optional: true, - ForceNew: true, - Default: false, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("FirstFitPlanner", "UserDispersingPlanner", "UserConcentratedPodPlanner", "ImplicitDedicationPlanner", "BareMetalPlanner"), + }, }, - "storage_type": { + "zone_id": schema.ListAttribute{ + Description: "The ID of the zone(s)", + Optional: true, + Computed: true, + ElementType: types.StringType, + PlanModifiers: []planmodifier.List{ + listplanmodifier.RequiresReplace(), + }, + }, + "disk_offering_id": schema.StringAttribute{ + Description: "The ID of the disk offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "storage_type": schema.StringAttribute{ Description: "The storage type of the service offering. Values are local and shared", - Type: schema.TypeString, Optional: true, - ForceNew: true, - Default: "shared", - ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) { - v := val.(string) - - if v == "local" || v == "shared" { - return - } - - errs = append(errs, fmt.Errorf("storage type should be either local or shared, got %s", v)) - - return + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("local", "shared"), + stringvalidator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + Default: stringdefault.StaticString("shared"), + }, + "provisioning_type": schema.StringAttribute{ + Description: "The provisioning type of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("thin", "sparse", "fat"), + stringvalidator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + Default: stringdefault.StaticString("thin"), + }, + "write_cache_type": schema.StringAttribute{ + Description: "The write cache type of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("none", "writeback", "writethrough"), + stringvalidator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + Default: stringdefault.StaticString("none"), + }, + "qos_type": schema.StringAttribute{ + Description: "The QoS type of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("none", "hypervisor", "storage"), + stringvalidator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + Default: stringdefault.StaticString("none"), + }, + "disk_read_rate_bps": schema.Int64Attribute{ + Description: "The read rate of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + }, + "disk_write_rate_bps": schema.Int64Attribute{ + Description: "The write rate of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + }, + "disk_read_rate_iops": schema.Int64Attribute{ + Description: "The read rate of the service offering in IOPS", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + }, + "disk_write_rate_iops": schema.Int64Attribute{ + Description: "The write rate of the service offering in IOPS", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + }, + "custom_iops": schema.BoolAttribute{ + Description: "Custom IOPS", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Default: booldefault.StaticBool(false), + Validators: []validator.Bool{ + boolvalidator.ConflictsWith(path.MatchRoot("disk_offering_id")), + boolvalidator.ConflictsWith(path.MatchRoot("disk_read_rate_iops"), path.MatchRoot("disk_write_rate_iops")), + boolvalidator.ConflictsWith(path.MatchRoot("disk_read_rate_bps"), path.MatchRoot("disk_write_rate_bps")), + }, + }, + "min_iops": schema.Int64Attribute{ + Description: "The minimum IOPS of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("disk_offering_id")), + int64validator.ConflictsWith(path.MatchRoot("disk_read_rate_iops"), path.MatchRoot("disk_write_rate_iops")), + int64validator.ConflictsWith(path.MatchRoot("disk_read_rate_bps"), path.MatchRoot("disk_write_rate_bps")), + int64validator.ConflictsWith(path.MatchRoot("custom_iops")), + }, + }, + "max_iops": schema.Int64Attribute{ + Description: "The maximum IOPS of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("disk_offering_id")), + int64validator.ConflictsWith(path.MatchRoot("disk_read_rate_iops"), path.MatchRoot("disk_write_rate_iops")), + int64validator.ConflictsWith(path.MatchRoot("disk_read_rate_bps"), path.MatchRoot("disk_write_rate_bps")), + int64validator.ConflictsWith(path.MatchRoot("custom_iops")), + }, + }, + "hypervisor_snapshot_reserve": schema.Int64Attribute{ + Description: "The hypervisor snapshot reserve of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("disk_offering_id")), + int64validator.ConflictsWith(path.MatchRoot("disk_read_rate_iops"), path.MatchRoot("disk_write_rate_iops")), + int64validator.ConflictsWith(path.MatchRoot("disk_read_rate_bps"), path.MatchRoot("disk_write_rate_bps")), + }, + }, + "root_disk_size": schema.Int64Attribute{ + Description: "The size of the root disk in GB", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + Validators: []validator.Int64{ + int64validator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + }, + "storage_tags": schema.StringAttribute{ + Description: "The storage tags of the service offering", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Validators: []validator.String{ + stringvalidator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + }, + "encrypt": schema.BoolAttribute{ + Description: "Encrypt the service offering storage", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Default: booldefault.StaticBool(false), + Validators: []validator.Bool{ + boolvalidator.ConflictsWith(path.MatchRoot("disk_offering_id")), + }, + }, + "disk_offering_strictness": schema.BoolAttribute{ + Description: "Disk offering strictness", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + Default: booldefault.StaticBool(false), + }, + "id": schema.StringAttribute{ + Description: "The ID of the service offering", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), }, }, }, } } -func resourceCloudStackServiceOfferingCreate(d *schema.ResourceData, meta interface{}) error { - cs := meta.(*cloudstack.CloudStackClient) - name := d.Get("name").(string) - display_text := d.Get("display_text").(string) +func (r *resourceCloudstackServiceOffering) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var data resourceCloudStackServiceOfferingModel + + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + p := r.client.ServiceOffering.NewCreateServiceOfferingParams(data.DisplayText.ValueString(), data.Name.ValueString()) + + if !data.Customized.ValueBool() { + if !data.CpuNumber.IsNull() && !data.CpuNumber.IsUnknown() { + p.SetCpunumber(int(data.CpuNumber.ValueInt64())) + } + + if !data.Memory.IsNull() && !data.Memory.IsUnknown() { + p.SetMemory(int(data.Memory.ValueInt64())) + } - // Create a new parameter struct - p := cs.ServiceOffering.NewCreateServiceOfferingParams(display_text, name) - if v, ok := d.GetOk("cpu_number"); ok { - p.SetCpunumber(v.(int)) + data.CpuNumberMax = types.Int64Null() + data.CpuNumberMin = types.Int64Null() + data.MemoryMax = types.Int64Null() + data.MemoryMin = types.Int64Null() + } else { + if !data.CpuNumberMin.IsNull() && !data.CpuNumberMin.IsUnknown() { + p.SetMincpunumber(int(data.CpuNumberMin.ValueInt64())) + } + + if !data.CpuNumberMax.IsNull() && !data.CpuNumberMax.IsUnknown() { + p.SetMaxcpunumber(int(data.CpuNumberMax.ValueInt64())) + } + + if !data.MemoryMin.IsNull() && !data.MemoryMin.IsUnknown() { + p.SetMinmemory(int(data.MemoryMin.ValueInt64())) + } + + if !data.MemoryMax.IsNull() && !data.MemoryMax.IsUnknown() { + p.SetMaxmemory(int(data.MemoryMax.ValueInt64())) + } + + data.CpuNumber = types.Int64Null() + data.Memory = types.Int64Null() } - if v, ok := d.GetOk("cpu_speed"); ok { - p.SetCpuspeed(v.(int)) + if !data.CpuSpeed.IsNull() && !data.CpuSpeed.IsUnknown() { + p.SetCpuspeed(int(data.CpuSpeed.ValueInt64())) } - if v, ok := d.GetOk("host_tags"); ok { - p.SetHosttags(v.(string)) + if !data.HostTags.IsNull() && !data.HostTags.IsUnknown() { + p.SetHosttags(data.HostTags.ValueString()) + } else { + data.HostTags = types.StringNull() } - if v, ok := d.GetOk("limit_cpu_use"); ok { - p.SetLimitcpuuse(v.(bool)) + if !data.NetworkRate.IsNull() && !data.NetworkRate.IsUnknown() { + p.SetNetworkrate(int(data.NetworkRate.ValueInt64())) + } else { + data.NetworkRate = types.Int64Null() } - if v, ok := d.GetOk("memory"); ok { - p.SetMemory(v.(int)) + if !data.OfferHa.IsNull() && !data.OfferHa.IsUnknown() { + p.SetOfferha(data.OfferHa.ValueBool()) } - if v, ok := d.GetOk("offer_ha"); ok { - p.SetOfferha(v.(bool)) + if !data.DynamicScaling.IsNull() && !data.DynamicScaling.IsUnknown() { + p.SetDynamicscalingenabled(data.DynamicScaling.ValueBool()) } - if v, ok := d.GetOk("storage_type"); ok { - p.SetStoragetype(v.(string)) + if !data.LimitCpuUse.IsNull() && !data.LimitCpuUse.IsUnknown() { + p.SetLimitcpuuse(data.LimitCpuUse.ValueBool()) } - log.Printf("[DEBUG] Creating Service Offering %s", name) - s, err := cs.ServiceOffering.CreateServiceOffering(p) + if !data.Volatile.IsNull() && !data.Volatile.IsUnknown() { + p.SetIsvolatile(data.Volatile.ValueBool()) + } - if err != nil { - return err + if !data.DeploymentPlanner.IsNull() && !data.DeploymentPlanner.IsUnknown() { + p.SetDeploymentplanner(data.DeploymentPlanner.ValueString()) + } else { + data.DeploymentPlanner = types.StringNull() } - log.Printf("[DEBUG] Service Offering %s successfully created", name) - d.SetId(s.Id) + if !data.ZoneId.IsNull() && !data.ZoneId.IsUnknown() { + zoneIds := make([]string, 0, len(data.ZoneId.Elements())) + diags := data.ZoneId.ElementsAs(ctx, &zoneIds, false) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + p.SetZoneid(zoneIds) + } else { + data.ZoneId = types.ListNull(types.StringType) + } - return resourceCloudStackServiceOfferingRead(d, meta) -} + if !data.DiskOfferingId.IsNull() && !data.DiskOfferingId.IsUnknown() { + p.SetDiskofferingid(data.DiskOfferingId.ValueString()) + } else { + p.SetDiskofferingid("") + data.DiskOfferingId = types.StringNull() + + if !data.StorageType.IsNull() && !data.StorageType.IsUnknown() { + p.SetStoragetype(data.StorageType.ValueString()) + } else { + data.StorageType = types.StringNull() + } -func resourceCloudStackServiceOfferingRead(d *schema.ResourceData, meta interface{}) error { - cs := meta.(*cloudstack.CloudStackClient) - log.Printf("[DEBUG] Retrieving Service Offering %s", d.Get("name").(string)) + if !data.ProvisioningType.IsNull() && !data.ProvisioningType.IsUnknown() { + p.SetProvisioningtype(data.ProvisioningType.ValueString()) + } - // Get the Service Offering details - s, count, err := cs.ServiceOffering.GetServiceOfferingByName(d.Get("name").(string)) + if !data.WriteCacheType.IsNull() && !data.WriteCacheType.IsUnknown() { + p.SetCachemode(data.WriteCacheType.ValueString()) + } - if err != nil { - if count == 0 { - log.Printf("[DEBUG] Service Offering %s does no longer exist", d.Get("name").(string)) - d.SetId("") - return nil + if data.QosType.ValueString() == "hypervisor" { + if !data.DiskReadRateBps.IsNull() && !data.DiskReadRateBps.IsUnknown() { + p.SetBytesreadrate(data.DiskReadRateBps.ValueInt64()) + } + + if !data.DiskWriteRateBps.IsNull() && !data.DiskWriteRateBps.IsUnknown() { + p.SetByteswriterate(data.DiskWriteRateBps.ValueInt64()) + } + + if !data.DiskReadRateIops.IsNull() && !data.DiskReadRateIops.IsUnknown() { + p.SetIopsreadrate(data.DiskReadRateIops.ValueInt64()) + } + + if !data.DiskWriteRateIops.IsNull() && !data.DiskWriteRateIops.IsUnknown() { + p.SetIopswriterate(data.DiskWriteRateIops.ValueInt64()) + } + } else if data.QosType.ValueString() == "storage" { + p.SetCustomizediops(data.CustomIops.ValueBool()) + + if !data.CustomIops.ValueBool() { + if !data.MinIops.IsNull() && !data.MinIops.IsUnknown() { + p.SetMiniops(data.MinIops.ValueInt64()) + } + + if !data.MaxIops.IsNull() && !data.MaxIops.IsUnknown() { + p.SetMaxiops(data.MaxIops.ValueInt64()) + } + } else { + p.SetMiniops(0) Review Comment: I am not sure. But this could cause issues. I would suggest not doing anything if it's not defined. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@cloudstack.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org