diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..49ad9be --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,33 @@ +linters: + enable: + - bodyclose + - decorder + - dogsled + - errorlint + - exportloopref + - gocognit + - goconst + - gocyclo + - gosec + - ifshort + - makezero + - nestif + - nilerr + - prealloc + - unconvert + - unparam + +linters-settings: + errcheck: + exclude-functions: + - (*github.com/hashicorp/terraform-plugin-sdk/helper/schema.ResourceData).Set + staticcheck: + go: "1.18" + checks: + - all + - -SA1019 + nestif: + min-complexity: 7 + +issues: + max-same-issues: 0 diff --git a/decort/controller.go b/decort/controller.go index addc6e3..25e27ea 100644 --- a/decort/controller.go +++ b/decort/controller.go @@ -94,8 +94,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) { decort_username: "", } - var allow_unverified_ssl bool - allow_unverified_ssl = d.Get("allow_unverified_ssl").(bool) + allow_unverified_ssl := d.Get("allow_unverified_ssl").(bool) if ret_config.controller_url == "" { return nil, fmt.Errorf("Empty DECORT cloud controller URL provided.") @@ -138,7 +137,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) { if allow_unverified_ssl { log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!") - transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} + transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec ret_config.cc_client = &http.Client{ Transport: transCfg, Timeout: Timeout180s, @@ -336,7 +335,7 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) { return true, nil } -func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error) { +func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error) { //nolint:unparam // This is a convenience wrapper around standard HTTP request methods that is aware of the // authorization mode for which the provider was initialized and compiles request accordingly. diff --git a/decort/data_source_compute.go b/decort/data_source_compute.go index 8800308..e1b4169 100644 --- a/decort/data_source_compute.go +++ b/decort/data_source_compute.go @@ -66,60 +66,6 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} { return result } -// NOTE: this is a legacy function, which is not used as of rc-1.10 -// Use "parseComputeDisksToExtraDisks" instead -func parseComputeDisks(disks []DiskRecord) []interface{} { - // Return value was designed to d.Set("disks",) item of dataSourceCompute schema - // However, this item was excluded from the schema as it is not directly - // managed through Terraform - length := len(disks) - log.Debugf("parseComputeDisks: called for %d disks", length) - - /* - if length == 1 && disks[0].Type == "B" { - // there is only one disk in the list and it is a boot disk - // as we skip boot disks, the result will be of 0 lenght - length = 0 - } - */ - - result := []interface{}{} - - if length == 0 { - return result - } - - for _, value := range disks { - /* - if value.Type == "B" { - // skip boot disk when parsing the list of disks - continue - } - */ - elem := make(map[string]interface{}) - // keys in this map should correspond to the Schema definition - // as returned by dataSourceDiskSchemaMake() - elem["name"] = value.Name - elem["disk_id"] = value.ID - elem["account_id"] = value.AccountID - elem["account_name"] = value.AccountName - elem["description"] = value.Desc - elem["image_id"] = value.ImageID - elem["size"] = value.SizeMax - elem["type"] = value.Type - elem["sep_id"] = value.SepID - elem["sep_type"] = value.SepType - elem["pool"] = value.Pool - // elem["status"] = value.Status - // elem["tech_status"] = value.TechStatus - elem["compute_id"] = value.ComputeID - - result = append(result, elem) - } - - return result -} - func parseBootDiskSize(disks []DiskRecord) int { // this return value will be used to d.Set("boot_disk_size",) item of dataSourceCompute schema if len(disks) == 0 { @@ -176,71 +122,6 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} { return result } -/* -func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]interface{} { - // return value will be used to d.Set("network") item of dataSourceCompute schema - length := len(ifaces) - log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length) - - result := make([]map[string]interface{}, length, length) - - for i, value := range ifaces { - elem := make(map[string]interface{}) - // Keys in this map should correspond to the Schema definition - // as returned by networkSubresourceSchemaMake() - elem["net_id"] = value.NetID - elem["net_type"] = value.NetType - elem["ip_address"] = value.IPAddress - elem["mac"] = value.MAC - - // log.Debugf(" element %d: net_id=%d, net_type=%s", i, value.NetID, value.NetType) - - result[i] = elem - } - - return result -} -*/ - -// NOTE: this function is retained for historical purposes and actually not used as of rc-1.10 -func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} { - // return value was designed to d.Set("interfaces",) item of dataSourceCompute schema - // However, this item was excluded from the schema as it is not directly - // managed through Terraform - length := len(ifaces) - log.Debugf("parseComputeInterfaces: called for %d ifaces", length) - - result := make([]map[string]interface{}, length, length) - - for i, value := range ifaces { - // Keys in this map should correspond to the Schema definition - // as returned by dataSourceInterfaceSchemaMake() - elem := make(map[string]interface{}) - - elem["net_id"] = value.NetID - elem["net_type"] = value.NetType - elem["ip_address"] = value.IPAddress - elem["netmask"] = value.NetMask - elem["mac"] = value.MAC - elem["default_gw"] = value.DefaultGW - elem["name"] = value.Name - elem["connection_id"] = value.ConnID - elem["connection_type"] = value.ConnType - - /* TODO: add code to parse QoS - qos_schema := interfaceQosSubresourceSchemaMake() - qos_schema.Set("egress_rate", value.QOS.ERate) - qos_schema.Set("ingress_rate", value.QOS.InRate) - qos_schema.Set("ingress_burst", value.QOS.InBurst) - elem["qos"] = qos_schema - */ - - result[i] = elem - } - - return result -} - func flattenCompute(d *schema.ResourceData, compFacts string) error { // This function expects that compFacts string contains response from API compute/get, // i.e. detailed information about compute instance. @@ -440,17 +321,6 @@ func dataSourceCompute() *schema.Resource { Description: "Network connection(s) for this compute.", }, - /* - "interfaces": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: interfaceSubresourceSchemaMake(), - }, - Description: "Specification for the virtual NICs configured on this compute instance.", - }, - */ - "os_users": { Type: schema.TypeList, Computed: true, @@ -478,26 +348,6 @@ func dataSourceCompute() *schema.Resource { Default: true, Description: "Is compute started.", }, - - /* - "status": { - Type: schema.TypeString, - Computed: true, - Description: "Current model status of this compute instance.", - }, - - "tech_status": { - Type: schema.TypeString, - Computed: true, - Description: "Current technical status of this compute instance.", - }, - - "internal_ip": { - Type: schema.TypeString, - Computed: true, - Description: "Internal IP address of this Compute.", - }, - */ }, } } diff --git a/decort/data_source_grid.go b/decort/data_source_grid.go index cba38ed..2529e3f 100644 --- a/decort/data_source_grid.go +++ b/decort/data_source_grid.go @@ -37,7 +37,6 @@ func flattenGrid(d *schema.ResourceData, grid *Grid) { d.Set("guid", grid.Guid) d.Set("location_code", grid.LocationCode) d.Set("id", grid.Id) - return } func dataSourceGridRead(d *schema.ResourceData, m interface{}) error { diff --git a/decort/data_source_image.go b/decort/data_source_image.go index c7e7bd6..9a218e9 100644 --- a/decort/data_source_image.go +++ b/decort/data_source_image.go @@ -69,7 +69,6 @@ func flattenImage(d *schema.ResourceData, image *Image) { d.Set("meta", flattenMeta(image.Meta)) d.Set("desc", image.Desc) d.Set("shared_with", image.SharedWith) - return } func dataSourceImageRead(d *schema.ResourceData, m interface{}) error { diff --git a/decort/data_source_image_list_stacks.go b/decort/data_source_image_list_stacks.go index 508c7fd..7b37371 100644 --- a/decort/data_source_image_list_stacks.go +++ b/decort/data_source_image_list_stacks.go @@ -29,7 +29,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) -func flattenImageListStacks(d *schema.ResourceData, stack ImageListStacks) []map[string]interface{} { +func flattenImageListStacks(_ *schema.ResourceData, stack ImageListStacks) []map[string]interface{} { temp := make([]map[string]interface{}, 0) for _, item := range stack { t := map[string]interface{}{ diff --git a/decort/data_source_vins.go b/decort/data_source_vins.go index 2fd712b..61fd3c5 100644 --- a/decort/data_source_vins.go +++ b/decort/data_source_vins.go @@ -48,13 +48,13 @@ func flattenVins(d *schema.ResourceData, vins_facts string) error { } log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d", - vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID) + vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID) d.SetId(fmt.Sprintf("%d", vinsRecord.ID)) d.Set("name", vinsRecord.Name) d.Set("account_id", vinsRecord.AccountID) d.Set("account_name", vinsRecord.AccountName) - err = d.Set("rg_id", vinsRecord.RgID) + d.Set("rg_id", vinsRecord.RgID) d.Set("description", vinsRecord.Desc) d.Set("ipcidr", vinsRecord.IPCidr) @@ -117,11 +117,11 @@ func dataSourceVins() *schema.Resource { }, /* - "vins_id": { - Type: schema.TypeInt, - Optional: true, - Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", - }, + "vins_id": { + Type: schema.TypeInt, + Optional: true, + Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.", + }, */ "rg_id": { diff --git a/decort/disk_subresource.go b/decort/disk_subresource.go deleted file mode 100644 index cf3a5c5..0000000 --- a/decort/disk_subresource.go +++ /dev/null @@ -1,86 +0,0 @@ -/* -Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Author: Sergey Shubin, , - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package decort - -import ( - // log "github.com/sirupsen/logrus" - - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" -) - - -// ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID -func diskSubresourceSchemaMake() map[string]*schema.Schema { - rets := map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of this disk.", - }, - - "size": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(1), - Description: "Size of the disk in GB.", - }, - - "account_id": { - Type: schema.TypeInt, - Computed: true, - ValidateFunc: validation.IntAtLeast(1), - Description: "ID of the account this disk belongs to.", - }, - - "type": { - Type: schema.TypeString, - Optional: true, - Description: "Type of this disk.", - }, - - "sep_id": { - Type: schema.TypeString, - Optional: true, - Default: "default", - Description: "ID of the storage end-point provider serving this disk.", - }, - - "sep_type": { - Type: schema.TypeString, - Optional: true, - Default: "default", - Description: "Type of the storage provider serving this disk.", - }, - - "pool": { - Type: schema.TypeString, - Optional: true, - Default: "default", - Description: "Pool on the storage where this disk is located.", - }, - - "image_id": { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the binary Image this disk resource is cloned from (if any).", - }, - } - - return rets -} diff --git a/decort/interface_subresource.go b/decort/interface_subresource.go deleted file mode 100644 index d6f8a9b..0000000 --- a/decort/interface_subresource.go +++ /dev/null @@ -1,331 +0,0 @@ -/* -Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Author: Sergey Shubin, , - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - This file contains definitions and code for handling Interface component of Compute schema -*/ - -package decort - -import ( - /* - "log" - "strconv" - "strings" - */ - - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - // "github.com/hashicorp/terraform-plugin-sdk/helper/validation" -) - -func interfaceSubresourceSchemaMake() map[string]*schema.Schema { - rets := map[string]*schema.Schema{ - "net_id": { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the network entity this interface is connected to.", - }, - - "net_type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of the network entity this interface is connected to.", - }, - - "ip_address": { - Type: schema.TypeString, - Computed: true, - Description: "IP addresses assigned to this interface.", - }, - - "netmask": { - Type: schema.TypeInt, - Computed: true, - Description: "Network mask to be used with this interface.", - }, - - "mac": { - Type: schema.TypeString, - Computed: true, - Description: "MAC address of this interface.", - }, - - "default_gw": { - Type: schema.TypeString, - Computed: true, - Description: "Default gateway associated with this interface.", - }, - - "name": { - Type: schema.TypeString, - Computed: true, - Description: "Interface name.", - }, - - "connection_id": { - Type: schema.TypeInt, - Computed: true, - Description: "VxLAN or VLAN ID this interface is connected to.", - }, - - "connection_type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of the segment (VLAN or VxLAN) this interface is connected to.", - }, - - "qos": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: interfaceQosSubresourceSchemaMake(), - }, - Description: "QoS settings for this interface.", - }, - } - - return rets -} - -func interfaceQosSubresourceSchemaMake() map[string]*schema.Schema { - rets := map[string]*schema.Schema{ - "egress_rate": { - Type: schema.TypeInt, - Computed: true, - Description: "Egress rate limit on this interface.", - }, - - "ingress_burst": { - Type: schema.TypeInt, - Computed: true, - Description: "Ingress burst limit on this interface.", - }, - - "ingress_rate": { - Type: schema.TypeInt, - Computed: true, - Description: "Ingress rate limit on this interface.", - }, - - "guid": { - Type: schema.TypeString, - Computed: true, - Description: "GUID of this QoS record.", - }, - } - - return rets -} - -/* -func flattenNetworks(nets []NicRecord) []interface{} { - // this function expects an array of NicRecord as returned by machines/get API call - // NOTE: it does NOT expect a strucutre as returned by externalnetwork/list - var length = 0 - var strarray []string - - for _, value := range nets { - if value.NicType == "PUBLIC" { - length += 1 - } - } - log.Debugf("flattenNetworks: found %d NICs with PUBLIC type", length) - - result := make([]interface{}, length) - if length == 0 { - return result - } - - elem := make(map[string]interface{}) - - var subindex = 0 - for index, value := range nets { - if value.NicType == "PUBLIC" { - // this will be changed as network segments entity - // value.Params for ext net comes in a form "gateway:176.118.165.1 externalnetworkId:6" - // for network_id we need to extract from this string - strarray = strings.Split(value.Params, " ") - substr := strings.Split(strarray[1], ":") - elem["network_id"], _ = strconv.Atoi(substr[1]) - elem["ip_range"] = value.IPAddress - // elem["label"] = ... - should be uncommented for the future release - log.Debugf("flattenNetworks: parsed element %d - network_id %d, ip_range %s", - index, elem["network_id"].(int), value.IPAddress) - result[subindex] = elem - subindex += 1 - } - } - - return result -} - -func makePortforwardsConfig(arg_list []interface{}) (pfws []PortforwardConfig, count int) { - count = len(arg_list) - if count < 1 { - return nil, 0 - } - - pfws = make([]PortforwardConfig, count) - var subres_data map[string]interface{} - for index, value := range arg_list { - subres_data = value.(map[string]interface{}) - // pfws[index].Label = subres_data["label"].(string) - should be uncommented for future release - pfws[index].ExtPort = subres_data["ext_port"].(int) - pfws[index].IntPort = subres_data["int_port"].(int) - pfws[index].Proto = subres_data["proto"].(string) - } - - return pfws, count -} - -func flattenPortforwards(pfws []PortforwardRecord) []interface{} { - result := make([]interface{}, len(pfws)) - elem := make(map[string]interface{}) - var port_num int - - for index, value := range pfws { - // elem["label"] = ... - should be uncommented for the future release - - // external port field is of TypeInt in the portforwardSubresourceSchema, but string is returned - // by portforwards/list API, so we need conversion here - port_num, _ = strconv.Atoi(value.ExtPort) - elem["ext_port"] = port_num - // internal port field is of TypeInt in the portforwardSubresourceSchema, but string is returned - // by portforwards/list API, so we need conversion here - port_num, _ = strconv.Atoi(value.IntPort) - elem["int_port"] = port_num - elem["proto"] = value.Proto - elem["ext_ip"] = value.ExtIP - elem["int_ip"] = value.IntIP - result[index] = elem - } - - return result -} - -func portforwardSubresourceSchema() map[string]*schema.Schema { - rets := map[string]*schema.Schema{ - "label": { - Type: schema.TypeString, - Required: true, - Description: "Unique label of this network connection to identify it amnong other connections for this VM.", - }, - - "ext_port": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(1, 65535), - Description: "External port number for this port forwarding rule.", - }, - - "int_port": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(1, 65535), - Description: "Internal port number for this port forwarding rule.", - }, - - "proto": { - Type: schema.TypeString, - Required: true, - // ValidateFunc: validation.IntBetween(1, ), - Description: "Protocol type for this port forwarding rule. Should be either 'tcp' or 'udp'.", - }, - - "ext_ip": { - Type: schema.TypeString, - Computed: true, - Description: ".", - }, - - "int_ip": { - Type: schema.TypeString, - Computed: true, - Description: ".", - }, - } - - return rets -} - -func flattenNICs(nics []NicRecord) []interface{} { - var result = make([]interface{}, len(nics)) - elem := make(map[string]interface{}) - - for index, value := range nics { - elem["status"] = value.Status - elem["type"] = value.NicType - elem["mac"] = value.MacAddress - elem["ip_address"] = value.IPAddress - elem["parameters"] = value.Params - elem["reference_id"] = value.ReferenceID - elem["network_id"] = value.NetworkID - result[index] = elem - } - - return result -} - -func nicSubresourceSchema() map[string]*schema.Schema { - rets := map[string]*schema.Schema{ - "status": { - Type: schema.TypeString, - Computed: true, - Description: "Current status of this NIC.", - }, - - "type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of this NIC.", - }, - - "mac": { - Type: schema.TypeString, - Computed: true, - Description: "MAC address assigned to this NIC.", - }, - - "ip_address": { - Type: schema.TypeString, - Computed: true, - Description: "IP address assigned to this NIC.", - }, - - "parameters": { - Type: schema.TypeString, - Computed: true, - Description: "Additional NIC parameters.", - }, - - "reference_id": { - Type: schema.TypeString, - Computed: true, - Description: "Reference ID of this NIC.", - }, - - "network_id": { - Type: schema.TypeInt, - Computed: true, - Description: "Network ID which this NIC is connected to.", - }, - } - - return rets -} - -*/ diff --git a/decort/network_subresource.go b/decort/network_subresource.go index 2e8ca3d..183fe5a 100644 --- a/decort/network_subresource.go +++ b/decort/network_subresource.go @@ -23,7 +23,9 @@ import ( // "fmt" "bytes" "hash/fnv" - log "github.com/sirupsen/logrus" + + log "github.com/sirupsen/logrus" + // "net/url" "sort" @@ -43,19 +45,19 @@ func networkSubresIPAddreDiffSupperss(key, oldVal, newVal string, d *schema.Reso return true // suppress difference } -// This function is based on the original Terraform SerializeResourceForHash found +// This function is based on the original Terraform SerializeResourceForHash found // in helper/schema/serialize.go -// It skips network subresource attributes, which are irrelevant for identification +// It skips network subresource attributes, which are irrelevant for identification // of unique network blocks func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource *schema.Resource) { if val == nil { return } - + rs := resource.Schema m := val.(map[string]interface{}) - var keys []string + keys := make([]string, 0, len(rs)) allComputed := true for k, val := range rs { @@ -96,7 +98,7 @@ func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource // from network subresource (e.g. in flattenCompute) // // This function is based on the original Terraform function HashResource from -// helper/schema/set.go +// helper/schema/set.go func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc { return func(v interface{}) int { var serialized bytes.Buffer @@ -111,11 +113,11 @@ func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc { func networkSubresourceSchemaMake() map[string]*schema.Schema { rets := map[string]*schema.Schema{ "net_type": { - Type: schema.TypeString, - Required: true, - StateFunc: stateFuncToUpper, + Type: schema.TypeString, + Required: true, + StateFunc: stateFuncToUpper, ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, false), // observe case while validating - Description: "Type of the network for this connection, either EXTNET or VINS.", + Description: "Type of the network for this connection, either EXTNET or VINS.", }, "net_id": { @@ -125,11 +127,11 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema { }, "ip_address": { - Type: schema.TypeString, - Optional: true, - Computed: true, + Type: schema.TypeString, + Optional: true, + Computed: true, DiffSuppressFunc: networkSubresIPAddreDiffSupperss, - Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.", + Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.", }, "mac": { @@ -137,7 +139,6 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema { Computed: true, Description: "MAC address associated with this connection. MAC address is assigned automatically.", }, - } return rets } diff --git a/decort/provider.go b/decort/provider.go index 2d9e3a9..8b5cff8 100644 --- a/decort/provider.go +++ b/decort/provider.go @@ -26,8 +26,6 @@ import ( // "github.com/hashicorp/terraform-plugin-sdk/terraform" ) -var decsController *ControllerCfg - func Provider() *schema.Provider { return &schema.Provider{ Schema: map[string]*schema.Schema{ diff --git a/decort/quota_subresource.go b/decort/quota_subresource.go index 7395f7d..f6e2fc1 100644 --- a/decort/quota_subresource.go +++ b/decort/quota_subresource.go @@ -28,7 +28,7 @@ import ( // "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) -func makeQuotaRecord(arg_list []interface{}) (QuotaRecord, int) { +func makeQuotaRecord(arg_list []interface{}) QuotaRecord { quota := QuotaRecord{ Cpu: -1, Ram: -1., // this is float64, but may change in the future @@ -63,7 +63,7 @@ func makeQuotaRecord(arg_list []interface{}) (QuotaRecord, int) { quota.GpuUnits = subres_data["gpu_units"].(int) } - return quota, 1 + return quota } func parseQuota(quota QuotaRecord) []interface{} { diff --git a/decort/resource_cdrom_image.go b/decort/resource_cdrom_image.go index 9711bf4..df93a21 100644 --- a/decort/resource_cdrom_image.go +++ b/decort/resource_cdrom_image.go @@ -385,16 +385,10 @@ func resourceCDROMImage() *schema.Resource { CustomizeDiff: customdiff.All( customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool { - if old.(bool) != new.(bool) { - return true - } - return false + return old.(bool) != new.(bool) }, resourceImageChangeEnabled), customdiff.IfValueChange("name", func(old, new, meta interface{}) bool { - if old.(string) != new.(string) && old.(string) != "" { - return true - } - return false + return old.(string) != new.(string) && old.(string) != "" }, resourceImageEditName), customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool { o := old.([]interface{}) @@ -411,16 +405,10 @@ func resourceCDROMImage() *schema.Resource { count++ } } - if count == 0 { - return true - } - return false + return count == 0 }, resourceImageShare), customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool { - if old.(int) != new.(int) { - return true - } - return false + return old.(int) != new.(int) }, resourceImageChangeComputeci), customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool { o := old.([]interface{}) @@ -437,10 +425,7 @@ func resourceCDROMImage() *schema.Resource { count++ } } - if count == 0 { - return true - } - return false + return count == 0 }, resourceImageUpdateNodes), ), diff --git a/decort/resource_compute.go b/decort/resource_compute.go index b61d8b6..ea43785 100644 --- a/decort/resource_compute.go +++ b/decort/resource_compute.go @@ -132,7 +132,7 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error { log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len()) err = controller.utilityComputeExtraDisksConfigure(d, false) // do_delta=false, as we are working on a new compute if err != nil { - log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %s: %s", compId, err) + log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", compId, err) extraDisksOk = false } } @@ -167,8 +167,7 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error { reqValues := &url.Values{} reqValues.Add("computeId", fmt.Sprintf("%d", compId)) log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId) - apiResp, err = controller.decortAPICall("POST", ComputeStartAPI, reqValues) - if err != nil { + if _, err := controller.decortAPICall("POST", ComputeStartAPI, reqValues); err != nil { return err } } @@ -269,7 +268,7 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error { } d.SetPartial("boot_disk_size") } else if oldSize.(int) > newSize.(int) { - log.Warnf("resourceComputeUpdate: compute ID %d - shrinking boot disk is not allowed", d.Id()) + log.Warnf("resourceComputeUpdate: compute ID %s - shrinking boot disk is not allowed", d.Id()) } // 3. Calculate and apply changes to data disks @@ -320,6 +319,9 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) error { compFacts, err := utilityComputeCheckPresence(d, m) if compFacts == "" { + if err != nil { + return err + } // the target Compute does not exist - in this case according to Terraform best practice // we exit from Destroy method without error return nil @@ -540,39 +542,6 @@ func resourceCompute() *schema.Resource { Default: true, Description: "Is compute started.", }, - - /* - "disks": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID - }, - Description: "Detailed specification for all disks attached to this compute instance (including bood disk).", - }, - - "interfaces": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: interfaceSubresourceSchemaMake(), - }, - Description: "Specification for the virtual NICs configured on this compute instance.", - }, - - - "status": { - Type: schema.TypeString, - Computed: true, - Description: "Current model status of this compute instance.", - }, - - "tech_status": { - Type: schema.TypeString, - Computed: true, - Description: "Current technical status of this compute instance.", - }, - */ }, } } diff --git a/decort/resource_disk.go b/decort/resource_disk.go index a19bf08..0177879 100644 --- a/decort/resource_disk.go +++ b/decort/resource_disk.go @@ -49,11 +49,11 @@ func resourceDiskCreate(d *schema.ResourceData, m interface{}) error { urlValues.Add("type", "D") // NOTE: only disks of Data type are managed via plugin urlValues.Add("sep_id", fmt.Sprintf("%d", d.Get("sep_id").(int))) urlValues.Add("pool", d.Get("pool").(string)) - + argVal, argSet := d.GetOk("description") if argSet { urlValues.Add("description", argVal.(string)) - } + } apiResp, err := controller.decortAPICall("POST", DisksCreateAPI, urlValues) if err != nil { @@ -65,9 +65,9 @@ func resourceDiskCreate(d *schema.ResourceData, m interface{}) error { log.Debugf("resourceDiskCreate: new Disk ID / name %d / %s creation sequence complete", diskId, d.Get("name").(string)) - // We may reuse dataSourceDiskRead here as we maintain similarity + // We may reuse dataSourceDiskRead here as we maintain similarity // between Disk resource and Disk data source schemas - // Disk resource read function will also update resource ID on success, so that Terraform + // Disk resource read function will also update resource ID on success, so that Terraform // will know the resource exists (however, we already did it a few lines before) return dataSourceDiskRead(d, m) } @@ -100,8 +100,8 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error { oldSize, newSize := d.GetChange("size") if oldSize.(int) < newSize.(int) { - log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB", - d.Id(), oldSize.(int), newSize.(int)) + log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB", + d.Id(), oldSize.(int), newSize.(int)) sizeParams := &url.Values{} sizeParams.Add("diskId", d.Id()) sizeParams.Add("size", fmt.Sprintf("%d", newSize.(int))) @@ -116,8 +116,8 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error { oldName, newName := d.GetChange("name") if oldName.(string) != newName.(string) { - log.Debugf("resourceDiskUpdate: renaming disk ID %d - %s -> %s", - d.Get("disk_id").(int), oldName.(string), newName.(string)) + log.Debugf("resourceDiskUpdate: renaming disk ID %d - %s -> %s", + d.Get("disk_id").(int), oldName.(string), newName.(string)) renameParams := &url.Values{} renameParams.Add("diskId", d.Id()) renameParams.Add("name", newName.(string)) @@ -129,24 +129,24 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error { } /* - NOTE: plugin will manage disks of type "Data" only, and type cannot be changed once disk is created + NOTE: plugin will manage disks of type "Data" only, and type cannot be changed once disk is created - oldType, newType := d.GetChange("type") - if oldType.(string) != newType.(string) { - return fmt.Errorf("resourceDiskUpdate: Disk ID %s - changing type of existing disk not allowed", d.Id()) - } + oldType, newType := d.GetChange("type") + if oldType.(string) != newType.(string) { + return fmt.Errorf("resourceDiskUpdate: Disk ID %s - changing type of existing disk not allowed", d.Id()) + } */ d.Partial(false) - // we may reuse dataSourceDiskRead here as we maintain similarity + // we may reuse dataSourceDiskRead here as we maintain similarity // between Compute resource and Compute data source schemas - return dataSourceDiskRead(d, m) + return dataSourceDiskRead(d, m) } func resourceDiskDelete(d *schema.ResourceData, m interface{}) error { - // NOTE: this function tries to detach and destroy target Disk "permanently", so - // there is no way to restore it. + // NOTE: this function tries to detach and destroy target Disk "permanently", so + // there is no way to restore it. // If, however, the disk is attached to a compute, the method will // fail (by failing the underpinning DECORt API call, which is issued with detach=false) log.Debugf("resourceDiskDelete: called for Disk ID / name %d / %s, Account ID %d", @@ -154,6 +154,9 @@ func resourceDiskDelete(d *schema.ResourceData, m interface{}) error { diskFacts, err := utilityDiskCheckPresence(d, m) if diskFacts == "" { + if err != nil { + return err + } // the specified Disk does not exist - in this case according to Terraform best practice // we exit from Destroy method without error return nil @@ -166,8 +169,8 @@ func resourceDiskDelete(d *schema.ResourceData, m interface{}) error { // However, this may change in the future, as TF state management logic may want // to delete disk resource BEFORE it is detached from compute instance, and, while // perfectly OK from data preservation viewpoint, this is breaking expected TF workflow - // in the eyes of an experienced TF user - params.Add("detach", "0") + // in the eyes of an experienced TF user + params.Add("detach", "0") params.Add("permanently", "1") controller := m.(*ControllerCfg) @@ -215,29 +218,29 @@ func resourceDiskSchemaMake() map[string]*schema.Schema { }, "sep_id": { - Type: schema.TypeInt, - Required: true, - ForceNew: true, + Type: schema.TypeInt, + Required: true, + ForceNew: true, ValidateFunc: validation.IntAtLeast(1), - Description: "Storage end-point provider serving this disk. Cannot be changed for existing disk.", + Description: "Storage end-point provider serving this disk. Cannot be changed for existing disk.", }, "pool": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, ValidateFunc: validation.StringIsNotEmpty, - Description: "Pool where this disk is located. Cannot be changed for existing disk.", + Description: "Pool where this disk is located. Cannot be changed for existing disk.", }, "size": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + Required: true, ValidateFunc: validation.IntAtLeast(1), - Description: "Size of the disk in GB. Note, that existing disks can only be grown in size.", + Description: "Size of the disk in GB. Note, that existing disks can only be grown in size.", }, - /* We moved "type" attribute to computed attributes section, as plugin manages disks of only + /* We moved "type" attribute to computed attributes section, as plugin manages disks of only one type - "D", e.g. data disks. "type": { Type: schema.TypeString, @@ -256,7 +259,7 @@ func resourceDiskSchemaMake() map[string]*schema.Schema { Description: "Optional user-defined text description of this disk.", }, - // The rest of the attributes are all computed + // The rest of the attributes are all computed "account_name": { Type: schema.TypeString, Computed: true, @@ -282,14 +285,14 @@ func resourceDiskSchemaMake() map[string]*schema.Schema { }, /* - "snapshots": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource { - Schema: snapshotSubresourceSchemaMake(), + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource { + Schema: snapshotSubresourceSchemaMake(), + }, + Description: "List of user-created snapshots for this disk." }, - Description: "List of user-created snapshots for this disk." - }, */ } diff --git a/decort/resource_image.go b/decort/resource_image.go index 6e206c4..cd4b970 100644 --- a/decort/resource_image.go +++ b/decort/resource_image.go @@ -87,8 +87,7 @@ func resourceImageCreate(d *schema.ResourceData, m interface{}) error { } api := "" - isSync := d.Get("sync").(bool) - if !isSync { + if isSync := d.Get("sync").(bool); !isSync { api = imageCreateAPI } else { api = imageSyncCreateAPI @@ -640,16 +639,10 @@ func resourceImage() *schema.Resource { }, CustomizeDiff: customdiff.All( customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool { - if old.(bool) != new.(bool) { - return true - } - return false + return old.(bool) != new.(bool) }, resourceImageChangeEnabled), customdiff.IfValueChange("name", func(old, new, meta interface{}) bool { - if old.(string) != new.(string) && old.(string) != "" { - return true - } - return false + return old.(string) != new.(string) && old.(string) != "" }, resourceImageEditName), customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool { o := old.([]interface{}) @@ -667,16 +660,10 @@ func resourceImage() *schema.Resource { count++ } } - if count == 0 { - return true - } - return false + return count == 0 }, resourceImageShare), customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool { - if old.(int) != new.(int) { - return true - } - return false + return old.(int) != new.(int) }, resourceImageChangeComputeci), customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool { o := old.([]interface{}) @@ -693,10 +680,7 @@ func resourceImage() *schema.Resource { count++ } } - if count == 0 { - return true - } - return false + return count == 0 }, resourceImageUpdateNodes), ), diff --git a/decort/resource_k8s.go b/decort/resource_k8s.go index 109fc49..e0f3cb0 100644 --- a/decort/resource_k8s.go +++ b/decort/resource_k8s.go @@ -223,15 +223,13 @@ func resourceK8sUpdate(d *schema.ResourceData, m interface{}) error { if newWorkers.Num > wg.Num { urlValues.Add("num", strconv.Itoa(newWorkers.Num-wg.Num)) - _, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues) - if err != nil { + if _, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues); err != nil { return err } } else { for i := wg.Num - 1; i >= newWorkers.Num; i-- { urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID)) - _, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues) - if err != nil { + if _, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues); err != nil { return err } } diff --git a/decort/resource_k8s_wg.go b/decort/resource_k8s_wg.go index 4ce3a0d..d9f4054 100644 --- a/decort/resource_k8s_wg.go +++ b/decort/resource_k8s_wg.go @@ -108,16 +108,14 @@ func resourceK8sWgUpdate(d *schema.ResourceData, m interface{}) error { wg, err := utilityK8sWgCheckPresence(d, m) if err != nil { - return nil + return err } urlValues := &url.Values{} urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int))) urlValues.Add("workersGroupId", d.Id()) - newNum := d.Get("num").(int) - - if newNum > wg.Num { + if newNum := d.Get("num").(int); newNum > wg.Num { urlValues.Add("num", strconv.Itoa(newNum-wg.Num)) _, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues) if err != nil { diff --git a/decort/resource_rg.go b/decort/resource_rg.go index 4a07cb6..b739f76 100644 --- a/decort/resource_rg.go +++ b/decort/resource_rg.go @@ -70,7 +70,7 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error { arg_value, arg_set := d.GetOk("quota") if arg_set { log.Debugf("resourceResgroupCreate: setting Quota on RG requested") - quota_record, _ = makeQuotaRecord(arg_value.([]interface{})) + quota_record = makeQuotaRecord(arg_value.([]interface{})) set_quota = true } @@ -142,7 +142,7 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error { } func resourceResgroupRead(d *schema.ResourceData, m interface{}) error { - log.Debugf("resourceResgroupRead: called for RG name %s, account ID %s", + log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d", d.Get("name").(string), d.Get("account_id").(int)) rg_facts, err := utilityResgroupCheckPresence(d, m) @@ -199,9 +199,9 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error { quota_value, quota_set := d.GetOk("quota") if quota_set { log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.") - quotarecord_new, _ := makeQuotaRecord(quota_value.([]interface{})) + quotarecord_new := makeQuotaRecord(quota_value.([]interface{})) quota_value_old, _ := d.GetChange("quota") // returns old as 1st, new as 2nd return value - quotarecord_old, _ := makeQuotaRecord(quota_value_old.([]interface{})) + quotarecord_old := makeQuotaRecord(quota_value_old.([]interface{})) if quotarecord_new.Cpu != quotarecord_old.Cpu { do_general_update = true @@ -260,11 +260,14 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error { func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error { // NOTE: this method forcibly destroys target resource group with flag "permanently", so there is no way to // restore the destroyed resource group as well all Computes & VINSes that existed in it - log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %s", + log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d", d.Get("name").(string), d.Get("account_id").(int)) rg_facts, err := utilityResgroupCheckPresence(d, m) if rg_facts == "" { + if err != nil { + return err + } // the target RG does not exist - in this case according to Terraform best practice // we exit from Destroy method without error return nil diff --git a/decort/resource_sep.go b/decort/resource_sep.go index 059198d..d3608e3 100644 --- a/decort/resource_sep.go +++ b/decort/resource_sep.go @@ -243,8 +243,7 @@ func resourceSepEdit(d *schema.ResourceData, m interface{}) error { } urlValues = &url.Values{} - err := resourceSepRead(d, m) - if err != nil { + if err := resourceSepRead(d, m); err != nil { return err } @@ -282,8 +281,6 @@ func resourceSepUpdateNodes(d *schema.ResourceDiff, m interface{}) error { urlValues := &url.Values{} t1, t2 := d.GetChange("consumed_by") - d1 := t1.([]interface{}) - d2 := t2.([]interface{}) urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int))) @@ -291,7 +288,7 @@ func resourceSepUpdateNodes(d *schema.ResourceDiff, m interface{}) error { temp := "" api := "" - if len(d1) > len(d2) { + if d1, d2 := t1.([]interface{}), t2.([]interface{}); len(d1) > len(d2) { for _, n := range d2 { if !findElInt(d1, n) { consumedIds = append(consumedIds, n) @@ -510,10 +507,7 @@ func resourceSep() *schema.Resource { CustomizeDiff: customdiff.All( customdiff.IfValueChange("enable", func(old, new, meta interface{}) bool { - if old.(bool) != new.(bool) { - return true - } - return false + return old.(bool) != new.(bool) }, resourceSepChangeEnabled), customdiff.IfValueChange("consumed_by", func(old, new, meta interface{}) bool { o := old.([]interface{}) @@ -530,10 +524,7 @@ func resourceSep() *schema.Resource { count++ } } - if count == 0 { - return true - } - return false + return count == 0 }, resourceSepUpdateNodes), customdiff.IfValueChange("provided_by", func(old, new, meta interface{}) bool { o := old.([]interface{}) @@ -550,10 +541,7 @@ func resourceSep() *schema.Resource { count++ } } - if count == 0 { - return true - } - return false + return count == 0 }, resourceSepUpdateProviders), ), } diff --git a/decort/resource_sep_config.go b/decort/resource_sep_config.go index 9663291..c16b0f0 100644 --- a/decort/resource_sep_config.go +++ b/decort/resource_sep_config.go @@ -55,9 +55,7 @@ func resourceSepConfigCreate(d *schema.ResourceData, m interface{}) error { return errors.New("provided sep id config does not exist") } - resourceSepConfigRead(d, m) - - return nil + return resourceSepConfigRead(d, m) } func resourceSepConfigRead(d *schema.ResourceData, m interface{}) error { diff --git a/decort/resource_snapshot.go b/decort/resource_snapshot.go index 75f2b29..7a75867 100644 --- a/decort/resource_snapshot.go +++ b/decort/resource_snapshot.go @@ -191,7 +191,7 @@ func resourceSnapshot() *schema.Resource { CustomizeDiff: customdiff.All( customdiff.IfValueChange("rollback", func(old, new, meta interface{}) bool { o := old.(bool) - if o != new.(bool) && o == false { + if o != new.(bool) && !o { return true } return false diff --git a/decort/resource_vins.go b/decort/resource_vins.go index caa9b58..cdfb5f6 100644 --- a/decort/resource_vins.go +++ b/decort/resource_vins.go @@ -40,7 +40,7 @@ import ( func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool { if oldVal == "" && newVal != "" { // if old value for "ipcidr" resource is empty string, it means that we are creating new ViNS - // and there is a chance that the user will want specific IP address range for this ViNS - + // and there is a chance that the user will want specific IP address range for this ViNS - // check if "ipcidr" is explicitly set in TF file to a non-empty string. log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal) return false // there is a difference between stored and new value @@ -51,7 +51,7 @@ func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool func resourceVinsCreate(d *schema.ResourceData, m interface{}) error { log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d", - d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) + d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) apiToCall := VinsCreateInAccountAPI @@ -65,7 +65,7 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error { apiToCall = VinsCreateInRgAPI urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int))) } else { - // RG ID either not set at all or set to 0 - user may want ViNS at account level + // RG ID either not set at all or set to 0 - user may want ViNS at account level argVal, argSet = d.GetOk("account_id") if !argSet || argVal.(int) <= 0 { // No valid Account ID (and no RG ID either) - cannot create ViNS @@ -79,14 +79,14 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error { if argVal.(int) > 0 { // connect to specific external network urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int))) - /* - Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform! - - // in case of specific ext net connection user may also want a particular IP address - argVal, argSet = d.GetOk("ext_net_ip") - if argSet && argVal.(string) != "" { - urlValues.Add("extIp", argVal.(string)) - } + /* + Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform! + + // in case of specific ext net connection user may also want a particular IP address + argVal, argSet = d.GetOk("ext_net_ip") + if argSet && argVal.(string) != "" { + urlValues.Add("extIp", argVal.(string)) + } */ } else { // ext_net_id is set to a negative value - connect to default external network @@ -100,7 +100,7 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error { log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string)) urlValues.Add("ipcidr", argVal.(string)) } - + argVal, argSet = d.GetOk("description") if argSet { urlValues.Add("desc", argVal.(string)) @@ -116,9 +116,9 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error { log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsId, d.Get("name").(string)) - // We may reuse dataSourceVinsRead here as we maintain similarity + // We may reuse dataSourceVinsRead here as we maintain similarity // between ViNS resource and ViNS data source schemas - // ViNS resource read function will also update resource ID on success, so that Terraform + // ViNS resource read function will also update resource ID on success, so that Terraform // will know the resource exists (however, we already did it a few lines before) return dataSourceVinsRead(d, m) } @@ -138,12 +138,12 @@ func resourceVinsRead(d *schema.ResourceData, m interface{}) error { func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error { log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d", - d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) + d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int)) controller := m.(*ControllerCfg) d.Partial(true) - + // 1. Handle external network connection change oldExtNetId, newExtNedId := d.GetChange("ext_net_id") if oldExtNetId.(int) != newExtNedId.(int) { @@ -168,15 +168,15 @@ func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error { return err } } - + d.SetPartial("ext_net_id") } d.Partial(false) - // we may reuse dataSourceVinsRead here as we maintain similarity + // we may reuse dataSourceVinsRead here as we maintain similarity // between Compute resource and Compute data source schemas - return dataSourceVinsRead(d, m) + return dataSourceVinsRead(d, m) } func resourceVinsDelete(d *schema.ResourceData, m interface{}) error { @@ -185,6 +185,9 @@ func resourceVinsDelete(d *schema.ResourceData, m interface{}) error { vinsFacts, err := utilityVinsCheckPresence(d, m) if vinsFacts == "" { + if err != nil { + return err + } // the specified ViNS does not exist - in this case according to Terraform best practice // we exit from Destroy method without error return nil @@ -192,8 +195,8 @@ func resourceVinsDelete(d *schema.ResourceData, m interface{}) error { params := &url.Values{} params.Add("vinsId", d.Id()) - params.Add("force", "1") // disconnect all computes before deleting ViNS - params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin + params.Add("force", "1") // disconnect all computes before deleting ViNS + params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin controller := m.(*ControllerCfg) _, err = controller.decortAPICall("POST", VinsDeleteAPI, params) @@ -222,10 +225,10 @@ func resourceVinsExists(d *schema.ResourceData, m interface{}) (bool, error) { func resourceVinsSchemaMake() map[string]*schema.Schema { rets := map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, ValidateFunc: validation.StringIsNotEmpty, - Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.", + Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.", }, /* we do not need ViNS ID as an argument because if we already know this ID, it is not practical to call resource provider. @@ -246,25 +249,25 @@ func resourceVinsSchemaMake() map[string]*schema.Schema { }, "account_id": { - Type: schema.TypeInt, - Required: true, - ForceNew: true, + Type: schema.TypeInt, + Required: true, + ForceNew: true, ValidateFunc: validation.IntAtLeast(1), - Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.", + Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.", }, "ext_net_id": { - Type: schema.TypeInt, - Required: true, + Type: schema.TypeInt, + Required: true, ValidateFunc: validation.IntAtLeast(0), - Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.", + Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.", }, "ipcidr": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, DiffSuppressFunc: ipcidrDiffSupperss, - Description: "Network address to use by this ViNS. This parameter is only valid when creating new ViNS.", + Description: "Network address to use by this ViNS. This parameter is only valid when creating new ViNS.", }, "description": { diff --git a/decort/resource_virtual_image.go b/decort/resource_virtual_image.go index b1cec35..5097db1 100644 --- a/decort/resource_virtual_image.go +++ b/decort/resource_virtual_image.go @@ -332,22 +332,13 @@ func resourceVirtualImage() *schema.Resource { CustomizeDiff: customdiff.All( customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool { - if old.(bool) != new.(bool) { - return true - } - return false + return old.(bool) != new.(bool) }, resourceImageChangeEnabled), customdiff.IfValueChange("link_to", func(old, new, meta interface{}) bool { - if old.(int) != new.(int) { - return true - } - return false + return old.(int) != new.(int) }, resourceImageLink), customdiff.IfValueChange("name", func(old, new, meta interface{}) bool { - if old.(string) != new.(string) && old.(string) != "" { - return true - } - return false + return old.(string) != new.(string) && old.(string) != "" }, resourceImageEditName), customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool { o := old.([]interface{}) @@ -364,16 +355,10 @@ func resourceVirtualImage() *schema.Resource { count++ } } - if count == 0 { - return true - } - return false + return count == 0 }, resourceImageShare), customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool { - if old.(int) != new.(int) { - return true - } - return false + return old.(int) != new.(int) }, resourceImageChangeComputeci), customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool { o := old.([]interface{}) @@ -390,10 +375,7 @@ func resourceVirtualImage() *schema.Resource { count++ } } - if count == 0 { - return true - } - return false + return count == 0 }, resourceImageUpdateNodes), ), diff --git a/decort/utility_compute.go b/decort/utility_compute.go index 8767a25..d8b559d 100644 --- a/decort/utility_compute.go +++ b/decort/utility_compute.go @@ -38,14 +38,14 @@ import ( func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceData, do_delta bool) error { // d is filled with data according to computeResource schema, so extra disks config is retrieved via "extra_disks" key - // If do_delta is true, this function will identify changes between new and existing specs for extra disks and try to + // If do_delta is true, this function will identify changes between new and existing specs for extra disks and try to // update compute configuration accordingly - // Otherwise it will apply whatever is found in the new set of "extra_disks" right away. + // Otherwise it will apply whatever is found in the new set of "extra_disks" right away. // Primary use of do_delta=false is when calling this function from compute Create handler. - // Note that this function will not abort on API errors, but will continue to configure (attach / detach) other individual + // Note that this function will not abort on API errors, but will continue to configure (attach / detach) other individual // disks via atomic API calls. However, it will not retry failed manipulation on the same disk. - log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %b", d.Id(), do_delta) + log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta) // NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt old_set, new_set := d.GetChange("extra_disks") @@ -71,11 +71,11 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD } if apiErrCount > 0 { - log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s", - apiErrCount, d.Id(), lastSavedError) + log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) return lastSavedError } - + return nil } @@ -110,8 +110,8 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD } if apiErrCount > 0 { - log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s", - apiErrCount, d.Id(), lastSavedError) + log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) return lastSavedError } @@ -120,11 +120,11 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceData, do_delta bool) error { // "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key - // If do_delta is true, this function will identify changes between new and existing specs for network and try to + // If do_delta is true, this function will identify changes between new and existing specs for network and try to // update compute configuration accordingly - // Otherwise it will apply whatever is found in the new set of "network" right away. + // Otherwise it will apply whatever is found in the new set of "network" right away. // Primary use of do_delta=false is when calling this function from compute Create handler. - + old_set, new_set := d.GetChange("network") apiErrCount := 0 @@ -137,7 +137,7 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat for _, runner := range new_set.(*schema.Set).List() { urlValues := &url.Values{} - net_data := runner.(map[string]interface{}) + net_data := runner.(map[string]interface{}) urlValues.Add("computeId", d.Id()) urlValues.Add("netType", net_data["net_type"].(string)) urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int))) @@ -154,8 +154,8 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat } if apiErrCount > 0 { - log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s", - apiErrCount, d.Id(), lastSavedError) + log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) return lastSavedError } return nil @@ -172,8 +172,8 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat _, err := ctrl.decortAPICall("POST", ComputeNetDetachAPI, urlValues) if err != nil { // failed to detach this network - there will be partial resource update - log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s", - net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err) + log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s", + net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err) apiErrCount++ lastSavedError = err } @@ -185,7 +185,7 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat urlValues := &url.Values{} net_data := runner.(map[string]interface{}) urlValues.Add("computeId", d.Id()) - urlValues.Add("netId", fmt.Sprintf("%d",net_data["net_id"].(int))) + urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int))) urlValues.Add("netType", net_data["net_type"].(string)) if net_data["ip_address"].(string) != "" { urlValues.Add("ipAddr", net_data["ip_address"].(string)) @@ -193,16 +193,16 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat _, err := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues) if err != nil { // failed to attach this network - there will be partial resource update - log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s", - net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err) + log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s", + net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err) apiErrCount++ lastSavedError = err } } - + if apiErrCount > 0 { - log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s", - apiErrCount, d.Id(), lastSavedError) + log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s", + apiErrCount, d.Id(), lastSavedError) return lastSavedError } @@ -262,7 +262,7 @@ func utilityComputeCheckPresence(d *schema.ResourceData, m interface{}) (string, if !argSet { return "", fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string)) } - + urlValues.Add("rgId", fmt.Sprintf("%d", rgId)) apiResp, err := controller.decortAPICall("POST", RgListComputesAPI, urlValues) if err != nil { diff --git a/decort/utility_general.go b/decort/utility_general.go deleted file mode 100644 index 4934d0c..0000000 --- a/decort/utility_general.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Author: Sergey Shubin, , - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration -Technology platfom. - -Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. -*/ - -package decort - -import ( - - "strings" - -) - -func Jo2JSON(arg_str string) string { - // DECORT API historically returns response in the form of Python dictionary, which generally - // looks like JSON, but does not comply with JSON syntax. - // For Golang JSON Unmarshal to work properly we need to pre-process API response as follows: - ret_string := strings.Replace(string(arg_str), "u'", "\"", -1) - ret_string = strings.Replace(ret_string, "'", "\"", -1) - ret_string = strings.Replace(ret_string, ": False", ": false", -1) - ret_string = strings.Replace(ret_string, ": True", ": true", -1) - ret_string = strings.Replace(ret_string, "null", "\"\"", -1) - ret_string = strings.Replace(ret_string, "None", "\"\"", -1) - - // fix for incorrect handling of usage info - // ret_string = strings.Replace(ret_string, "<", "\"", -1) - // ret_string = strings.Replace(ret_string, ">", "\"", -1) - return ret_string -} diff --git a/decort/utility_grid.go b/decort/utility_grid.go index 2131cde..8500a5f 100644 --- a/decort/utility_grid.go +++ b/decort/utility_grid.go @@ -27,7 +27,6 @@ package decort import ( "encoding/json" "errors" - "fmt" "net/url" "strconv" @@ -44,7 +43,7 @@ func utilityGridCheckPresence(d *schema.ResourceData, m interface{}) (*Grid, err if gridId, ok := d.GetOk("grid_id"); ok { urlValues.Add("gridId", strconv.Itoa(gridId.(int))) } else { - return nil, errors.New(fmt.Sprintf("grid_id is required")) + return nil, errors.New("grid_id is required") } log.Debugf("utilityGridCheckPresence: load grid") diff --git a/decort/utility_pcidevice.go b/decort/utility_pcidevice.go index 2782ac1..5709ea0 100644 --- a/decort/utility_pcidevice.go +++ b/decort/utility_pcidevice.go @@ -43,21 +43,12 @@ func utilityPcideviceCheckPresence(d *schema.ResourceData, m interface{}) (*Pcid id, _ := strconv.Atoi(d.Id()) pcideviceId = id } - pcidevice := &Pcidevice{} - - flag := false for _, pd := range pcideviceList { if pd.ID == pcideviceId { - pcidevice = &pd - flag = true - break + return &pd, nil } } - if !flag { - return nil, nil - } - - return pcidevice, nil + return nil, nil } diff --git a/decort/utility_pcidevice_list.go b/decort/utility_pcidevice_list.go index 6767c7d..e4f7580 100644 --- a/decort/utility_pcidevice_list.go +++ b/decort/utility_pcidevice_list.go @@ -31,7 +31,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) -func utilityPcideviceListCheckPresence(d *schema.ResourceData, m interface{}) (PcideviceList, error) { +func utilityPcideviceListCheckPresence(_ *schema.ResourceData, m interface{}) (PcideviceList, error) { pcideviceList := PcideviceList{} controller := m.(*ControllerCfg) urlValues := &url.Values{} diff --git a/decort/utility_rg.go b/decort/utility_rg.go index 371e678..c3c7d2b 100644 --- a/decort/utility_rg.go +++ b/decort/utility_rg.go @@ -36,38 +36,6 @@ import ( // "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) -func (ctrl *ControllerCfg) utilityResgroupConfigGet(rgid int) (*ResgroupGetResp, error) { - urlValues := &url.Values{} - urlValues.Add("rgId", fmt.Sprintf("%d", rgid)) - rgFacts, err := ctrl.decortAPICall("POST", ResgroupGetAPI, urlValues) - if err != nil { - return nil, err - } - - log.Debugf("utilityResgroupConfigGet: ready to unmarshal string %s", rgFacts) - model := &ResgroupGetResp{} - err = json.Unmarshal([]byte(rgFacts), model) - if err != nil { - return nil, err - } - - /* - ret := &ResgroupConfig{} - ret.AccountID = model.AccountID - ret.Location = model.Location - ret.Name = model.Name - ret.ID = rgid - ret.GridID = model.GridID - ret.ExtIP = model.ExtIP // legacy field for VDC - this will eventually become obsoleted by true Resource Groups - // Quota ResgroupQuotaConfig - // Network NetworkConfig - */ - log.Debugf("utilityResgroupConfigGet: account ID %d, GridID %d, Name %s", - model.AccountID, model.GridID, model.Name) - - return model, nil -} - // On success this function returns a string, as returned by API rg/get, which could be unmarshalled // into ResgroupGetResp structure func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { @@ -104,7 +72,7 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string } else { idSet = true } - + if idSet { // go straight for the RG by its ID log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId) @@ -165,11 +133,3 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, validatedAccountId) } - -func utilityResgroupGetDefaultGridID() (interface{}, error) { - if DefaultGridID > 0 { - return fmt.Sprintf("%d", DefaultGridID), nil - } - - return "", fmt.Errorf("utilityResgroupGetDefaultGridID: invalid default Grid ID %d", DefaultGridID) - } diff --git a/decort/utility_vins.go b/decort/utility_vins.go index f64cc79..03a410c 100644 --- a/decort/utility_vins.go +++ b/decort/utility_vins.go @@ -35,28 +35,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) -func (ctrl *ControllerCfg) utilityVinsConfigGet(vinsid int) (*VinsRecord, error) { - urlValues := &url.Values{} - urlValues.Add("vinsId", fmt.Sprintf("%d", vinsid)) - vinsFacts, err := ctrl.decortAPICall("POST", VinsGetAPI, urlValues) - if err != nil { - return nil, err - } - - log.Debugf("utilityVinsConfigGet: ready to unmarshal string %q", vinsFacts) - model := &VinsRecord{} - err = json.Unmarshal([]byte(vinsFacts), model) - if err != nil { - return nil, err - } - - log.Debugf("utilityVinsConfigGet: Name %d, account name:ID %s:%d, RG Name:ID %s:%d", - model.Name, model.AccountName, model.AccountID, - model.RgName, model.RgID) - - return model, nil -} - // On success this function returns a string, as returned by API vins/get, which could be unmarshalled // into VinsGetResp structure func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { @@ -129,7 +107,7 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er if err != nil { return "", err } - + // log.Debugf("%s", apiResp) // log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI) model := VinsSearchResp{} @@ -141,24 +119,24 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(model)) for index, item := range model { if item.Name == vinsName.(string) { - if ( accountSet && item.AccountID != accountId.(int) ) || - ( rgSet && item.RgID != rgId.(int) ) { - // double check that account ID and Rg ID match, if set in the schema - continue + if (accountSet && item.AccountID != accountId.(int)) || + (rgSet && item.RgID != rgId.(int)) { + // double check that account ID and Rg ID match, if set in the schema + continue } log.Debugf("utilityVinsCheckPresence: match ViNS name %s / ID %d, account ID %d, RG ID %d at index %d", - item.Name, item.ID, item.AccountID, item.RgID, index) + item.Name, item.ID, item.AccountID, item.RgID, index) - // element returned by API vins/search does not contain all information we may need to + // element returned by API vins/search does not contain all information we may need to // manage ViNS, so we have to get detailed info by calling API vins/get rqValues := &url.Values{} - rqValues.Add("vinsId", fmt.Sprintf("%d",item.ID)) + rqValues.Add("vinsId", fmt.Sprintf("%d", item.ID)) vinsGetResp, err := controller.decortAPICall("POST", VinsGetAPI, rqValues) if err != nil { return "", err } - return vinsGetResp, nil + return vinsGetResp, nil } }