From 92528adf2b4781f228b99bafd9084f5947b0fe6d Mon Sep 17 00:00:00 2001 From: Sergey Shubin svs1370 Date: Thu, 11 Feb 2021 00:52:00 +0300 Subject: [PATCH] Remove files with obsolete naming scheme --- decort/data_source_compute.go | 267 ------------------- decort/data_source_disk.go | 204 -------------- decort/data_source_image.go | 111 -------- decort/data_source_rg.go | 175 ------------ decort/models_objects.go | 97 ------- decort/resource_compute.go | 485 ---------------------------------- decort/resource_resgroup.go | 401 ---------------------------- decort/utility_disk.go | 120 --------- decort/utility_resgroup.go | 154 ----------- decort/utility_vm.go | 159 ----------- 10 files changed, 2173 deletions(-) delete mode 100644 decort/data_source_compute.go delete mode 100644 decort/data_source_disk.go delete mode 100644 decort/data_source_image.go delete mode 100644 decort/data_source_rg.go delete mode 100644 decort/models_objects.go delete mode 100644 decort/resource_compute.go delete mode 100644 decort/resource_resgroup.go delete mode 100644 decort/utility_disk.go delete mode 100644 decort/utility_resgroup.go delete mode 100644 decort/utility_vm.go diff --git a/decort/data_source_compute.go b/decort/data_source_compute.go deleted file mode 100644 index 7ab5348..0000000 --- a/decort/data_source_compute.go +++ /dev/null @@ -1,267 +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 ( - - "encoding/json" - "fmt" - "log" - // "net/url" - - "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/helper/validation" -) - -func flattenCompute(d *schema.ResourceData, comp_facts string) error { - // NOTE: this function modifies ResourceData argument - as such it should never be called - // from resourceComputeExists(...) method - model := ComputeGetResp{} - log.Printf("flattenCompute: ready to unmarshal string %q", comp_facts) - err := json.Unmarshal([]byte(comp_facts), &model) - if err != nil { - return err - } - - log.Printf("flattenCompute: model.ID %d, model.ResGroupID %d", model.ID, model.ResGroupID) - - d.SetId(fmt.Sprintf("%d", model.ID)) - d.Set("name", model.Name) - d.Set("rgid", model.ResGroupID) - d.Set("rg_name", model.ResGroupName) - d.Set("account_id", model.AccountID) - d.Set("account_name", model.AccountName) - d.Set("arch", model.Arch) - d.Set("cpu", model.Cpu) - d.Set("ram", model.Ram) - d.Set("boot_disk_size", model.BootDiskSize) - d.Set("image_id", model.ImageID) - d.Set("description", model.Desc) - d.Set("status", model.Status) - d.Set("tech_status", model.TechStatus) - - bootdisk_map := make(map[string]interface{}) - bootdisk_map["size"] = model.BootDisk - bootdisk_map["label"] = "boot" - bootdisk_map["pool"] = "default" - bootdisk_map["provider"] = "default" - - if err = d.Set("boot_disk", []interface{}{bootdisk_map}); err != nil { - return err - } - - if len(model.DataDisks) > 0 { - log.Printf("flattenCompute: calling flattenDataDisks") - if err = d.Set("data_disks", flattenDataDisks(model.DataDisks)); err != nil { - return err - } - } - - if len(model.NICs) > 0 { - log.Printf("flattenCompute: calling flattenNICs") - if err = d.Set("nics", flattenNICs(model.NICs)); err != nil { - return err - } - log.Printf("flattenCompute: calling flattenNetworks") - if err = d.Set("networks", flattenNetworks(model.NICs)); err != nil { - return err - } - } - - if len(model.GuestLogins) > 0 { - log.Printf("flattenCompute: calling flattenGuestLogins") - guest_logins := flattenGuestLogins(model.GuestLogins) - if err = d.Set("guest_logins", guest_logins); err != nil { - return err - } - - default_login := guest_logins[0].(map[string]interface{}) - // set user & password attributes to the corresponding values of the 1st item in the list - if err = d.Set("user", default_login["login"]); err != nil { - return err - } - if err = d.Set("password", default_login["password"]); err != nil { - return err - } - } - - return nil -} - -func dataSourceComputeRead(d *schema.ResourceData, m interface{}) error { - comp_facts, err := utilityComputeCheckPresence(d, m) - if comp_facts == "" { - // if empty string is returned from utilityComputeCheckPresence then there is no - // such Compute and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty - return err - } - - return flattenCompute(d, comp_facts) -} - -func dataSourceCompute() *schema.Resource { - return &schema.Resource { - SchemaVersion: 1, - - Read: dataSourceComputeRead, - - Timeouts: &schema.ResourceTimeout { - Read: &Timeout30s, - Default: &Timeout60s, - }, - - Schema: map[string]*schema.Schema { - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of this compute instance. NOTE: this parameter is case sensitive.", - }, - - "rgid": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(1), - Description: "ID of the resource group where this compute instance is located.", - }, - - "rg_name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of the resource group where this compute instance is located.", - }, - - "account_id": { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the account this compute instance belongs to.", - }, - - "account_name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of the account this compute instance belongs to.", - }, - - "arch": { - Type: schema.TypeString, - Computed: true, - Description: "Hardware architecture of this compute instance.", - }, - - "cpu": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of CPUs allocated for this compute instance.", - }, - - "ram": { - Type: schema.TypeInt, - Computed: true, - Description: "Amount of RAM in MB allocated for this compute instance.", - }, - - "image_id": { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the OS image this compute instance is based on.", - }, - - "image_name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of the OS image this compute instance is based on.", - }, - - "boot_disk_size": { - Type: schema.TypeInt, - Computed: true, - Description: "This compute instance boot disk size in GB.", - }, - - "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).", - }, - - "guest_logins": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource { - Schema: guestLoginsSubresourceSchema(), - }, - Description: "Details about the guest OS users provisioned together with this compute instance.", - }, - - "networks": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource { - Schema: networkSubresourceSchema(), - }, - Description: "Specification for the networks to connect this virtual machine to.", - }, - - "nics": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource { - Schema: nicSubresourceSchema(), - }, - Description: "Specification for the virutal NICs allocated to this virtual machine.", - }, - - "description": { - Type: schema.TypeString, - Computed: true, - Description: "User-defined text description of 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.", - }, - - /* - "internal_ip": { - Type: schema.TypeString, - Computed: true, - Description: "Internal IP address of this Compute.", - }, - */ - }, - } -} \ No newline at end of file diff --git a/decort/data_source_disk.go b/decort/data_source_disk.go deleted file mode 100644 index 67dda14..0000000 --- a/decort/data_source_disk.go +++ /dev/null @@ -1,204 +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 ( - - "encoding/json" - "fmt" - "log" - // "net/url" - - "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/helper/validation" -) - -func flattenDisk(d *schema.ResourceData, disk_facts string) error { - // NOTE: this function modifies ResourceData argument - as such it should never be called - // from resourceComputeExists(...) method - model := DiskRecord{} - log.Debugf("flattenDisk: ready to unmarshal string %q", disk_facts) - err := json.Unmarshal([]byte(disk_facts), &model) - if err != nil { - return err - } - - log.Debugf("flattenDisk: disk ID %d, disk AccountID %d", model.ID, model.AccountID) - - d.SetId(fmt.Sprintf("%d", model.ID)) - d.Set("disk_id", model.ID) - d.Set("name", model.Name) - d.Set("account_id", model.AccountID) - d.Set("account_name", model.AccountName) - d.Set("size", model.SizeMax) - d.Set("type", model.Type) - d.Set("image_id", model.ImageID) - d.Set("sep_id", model.SepID) - d.Set("sep_type", model.SepType) - d.Set("pool", model.Pool) - d.Set("compute_id", model.ComputeID) - - d.Set("description", model.Desc) - d.Set("status", model.Status) - d.Set("tech_status", model.TechStatus) - - /* we do not manage snapshots via Terraform yet, so keep this commented out for a while - if len(model.Snapshots) > 0 { - log.Debugf("flattenDisk: calling flattenDiskSnapshots") - if err = d.Set("nics", flattenDiskSnapshots(model.Snapshots)); err != nil { - return err - } - } - */ - - return nil -} - -func dataSourceDiskRead(d *schema.ResourceData, m interface{}) error { - disk_facts, err := utilityDiskCheckPresence(d, m) - if disk_facts == "" { - // if empty string is returned from utilityDiskCheckPresence then there is no - // such Disk and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty - return err - } - - return flattenDisk(d, disk_facts) -} - -func dataSourceDiskSchemaMake() map[string]*schema.Schema { - rets := map[string]*schema.Schema { - "name": { - Type: schema.TypeString, - Optional: true, - Description: "Name of this disk. NOTE: disk names are NOT unique within an account.", - }, - - "disk_id": { - Type: schema.TypeInt, - Optional: true, - Description: "ID of the disk to get. If disk ID is specified, then name, account and account ID are ignored.", - }, - - "account_id": { - Type: schema.TypeInt, - Optional: true, - Description: "ID of the account this disk belongs to.", - }, - - "account_name": { - Type: schema.TypeString, - Optional: true, - Description: "Name of the account this disk belongs to. If account ID is specified, account name is ignored.", - }, - - "description": { - Type: schema.TypeString, - Computed: true, - Description: "User-defined text description of this disk.", - }, - - "image_id": { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the image, which this disk was cloned from.", - }, - - "size": { - Type: schema.TypeInt, - Computed: true, - Description: "Size of the disk in GB.", - }, - - "type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of this disk.", - }, - - /* - "snapshots": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource { - Schema: snapshotSubresourceSchemaMake(), - }, - Description: "List of user-created snapshots for this disk." - }, - */ - - "sep_id": { - Type: schema.TypeString, - Computed: true, - Description: "Storage end-point provider serving this disk.", - }, - - "sep_type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of the storage end-point provider serving this disk.", - }, - - "pool": { - Type: schema.TypeString, - Computed: true, - Description: "Pool where this disk is located.", - }, - - "status": { - Type: schema.TypeString, - Computed: true, - Description: "Current model status of this disk.", - }, - - "tech_status": { - Type: schema.TypeString, - Computed: true, - Description: "Current technical status of this disk.", - }, - - "compute_id": { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the compute instance where this disk is attached to, or 0 for unattached disk.", - }, - } - - return ret -} - -func dataSourceDisk() *schema.Resource { - return &schema.Resource { - SchemaVersion: 1, - - Read: dataSourceDiskRead, - - Timeouts: &schema.ResourceTimeout { - Read: &Timeout30s, - Default: &Timeout60s, - }, - - Schema: dataSourceDiskSchemaMake(), -} \ No newline at end of file diff --git a/decort/data_source_image.go b/decort/data_source_image.go deleted file mode 100644 index b81f0f7..0000000 --- a/decort/data_source_image.go +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright (c) 2019-2020 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 ( - "encoding/json" - "fmt" - "log" - "net/url" - - "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/helper/validation" -) - - -func dataSourceImageRead(d *schema.ResourceData, m interface{}) error { - name := d.Get("name").(string) - rgid, rgid_set := d.GetOk("rgid") - tenant_id, tenant_set := d.GetOk("tenant_id") - - controller := m.(*ControllerCfg) - url_values := &url.Values{} - if tenant_set { - url_values.Add("accountId", fmt.Sprintf("%d",tenant_id.(int))) - } - if rgid_set { - url_values.Add("cloudspaceId", fmt.Sprintf("%d",rgid.(int))) - } - body_string, err := controller.decortAPICall("POST", ImagesListAPI, url_values) - if err != nil { - return err - } - - log.Printf("dataSourceImageRead: ready to decode response body") - model := ImagesListResp{} - err = json.Unmarshal([]byte(body_string), &model) - if err != nil { - return err - } - - log.Printf("%#v", model) - log.Printf("dataSourceImageRead: traversing decoded JSON of length %d", len(model)) - for index, item := range model { - // need to match VM by name - if item.Name == name { - log.Printf("dataSourceImageRead: index %d, matched name %q", index, item.Name) - d.SetId(fmt.Sprintf("%d", model[index].ID)) - // d.Set("field_name", value) - return nil - } - } - - return fmt.Errorf("Cannot find OS Image name %q", name) -} - -func dataSourceImage() *schema.Resource { - return &schema.Resource { - SchemaVersion: 1, - - Read: dataSourceImageRead, - - Timeouts: &schema.ResourceTimeout { - Read: &Timeout30s, - Default: &Timeout60s, - }, - - Schema: map[string]*schema.Schema { - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of the OS image to locate. This parameter is case sensitive.", - }, - - "tenant_id": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: validation.IntAtLeast(1), - Description: "ID of the tenant to limit image search to.", - }, - - "rgid": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: validation.IntAtLeast(1), - Description: "ID of the resource group to limit image search to.", - }, - }, - } -} \ No newline at end of file diff --git a/decort/data_source_rg.go b/decort/data_source_rg.go deleted file mode 100644 index 7ed7eb0..0000000 --- a/decort/data_source_rg.go +++ /dev/null @@ -1,175 +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 ( - - "encoding/json" - "fmt" - "log" - // "net/url" - - "github.com/hashicorp/terraform/helper/schema" - // "github.com/hashicorp/terraform/helper/validation" - -) - -func flattenResgroup(d *schema.ResourceData, rg_facts string) error { - // NOTE: this function modifies ResourceData argument - as such it should never be called - // from resourceRsgroupExists(...) method - log.Debugf("%s", rg_facts) - log.Debugf("flattenResgroup: ready to decode response body from %q", CloudspacesGetAPI) - details := ResgroupGetResp{} - err := json.Unmarshal([]byte(rg_facts), &details) - if err != nil { - return err - } - - log.Debugf("flattenResgroup: decoded ResGroup name %q / ID %d, account ID %d, public IP %q", - details.Name, details.ID, details.AccountID, details.PublicIP) - - d.SetId(fmt.Sprintf("%d", details.ID)) - d.Set("name", details.Name) - d.Set("account_id", details.AccountID) - d.Set("grid_id", details.GridID) - d.Set("desc", details.Description) - d.Set("status", details.Status) - d.Set("def_net", details.DefaultNetType) - d.Set("def_net_id", details.DefaultNetID) - d.Set("vins", details.Vins) - d.Set("computes", details.Computes) - - log.Debugf("flattenResgroup: calling flattenQuota()") - if err = d.Set("quotas", flattenQuota(details.Quotas)); err != nil { - return err - } - - return nil -} - -func dataSourceResgroupRead(d *schema.ResourceData, m interface{}) error { - rg_facts, err := utilityResgroupCheckPresence(d, m) - if rg_facts == "" { - // if empty string is returned from utilityResgroupCheckPresence then there is no - // such resource group and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty in this case - return err - } - - return flattenResgroup(d, rg_facts) -} - - -func dataSourceResgroup() *schema.Resource { - return &schema.Resource { - SchemaVersion: 1, - - Read: dataSourceResgroupRead, - - Timeouts: &schema.ResourceTimeout { - Read: &Timeout30s, - Default: &Timeout60s, - }, - - Schema: map[string]*schema.Schema { - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of this resource group. Names are case sensitive and unique within the context of an account.", - }, - - "account": &schema.Schema { - Type: schema.TypeString, - Required: true, - Description: "Name of the account, which this resource group belongs to.", - }, - - "account_id": &schema.Schema { - Type: schema.TypeInt, - Computed: true, - Description: "Unique ID of the account, which this resource group belongs to.", - }, - - "desc": &schema.Schema { - Type: schema.TypeString, - Computed: true, - Description: "User-defined text description of this resource group.", - }, - - "grid_id": &schema.Schema { - Type: schema.TypeInt, - Computed: true, - Description: "Unique ID of the grid, where this resource group is deployed.", - }, - - "quotas": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource { - Schema: quotaRgSubresourceSchema(), // this is a dictionary - }, - Description: "Quotas on the resources for this resource group.", - }, - - "status": { - Type: schema.TypeString, - Computed: true, - Description: "Current status of this resource group.", - }, - - "def_net": &schema.Schema { - Type: schema.TypeString, - Computed: true, - Description: "Type of the default network for this resource group.", - }, - - "def_net_id": &schema.Schema { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the default network for this resource group (if any).", - }, - - "vins": { - Type: schema.TypeList, // this is a list of ints - Computed: true, - MaxItems: LimitMaxVinsPerResgroup, - Elem: &schema.Schema { - Type: schema.TypeInt, - }, - Description: "List of VINs deployed in this resource group.", - }, - - "computes": { - Type: schema.TypeList, //t his is a list of ints - Computed: true, - Elem: &schema.Schema { - Type: schema.TypeInt, - }, - Description: "List of computes deployed in this resource group.", - }, - }, - } -} diff --git a/decort/models_objects.go b/decort/models_objects.go deleted file mode 100644 index 19247ce..0000000 --- a/decort/models_objects.go +++ /dev/null @@ -1,97 +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 - -/* - -type DiskConfig struct { - Label string - Size int - Pool string - Provider string - ID int -} - -type NetworkConfig struct { - Label string - NetworkID int -} - -type PortforwardConfig struct { - Label string - ExtPort int - IntPort int - Proto string -} - -type SshKeyConfig struct { - User string - SshKey string - UserShell string -} - -type ComputeConfig struct { - ResGroupID int - Name string - ID int - Cpu int - Ram int - ImageID int - BootDisk DiskConfig - DataDisks []DiskConfig - Networks []NetworkConfig - PortForwards []PortforwardConfig - SshKeys []SshKeyConfig - Description string - // The following two parameters are required to create data disks by - // a separate disks/create API call - AccountID int - GridID int - // The following one paratmeter is required to create port forwards - // it will be obsoleted when we implement true Resource Groups - ExtIP string -} - -type ResgroupQuotaConfig struct { - Cpu int - Ram float32 // NOTE: it is float32! However, int would be enough here - Disk int - NetTraffic int - ExtIPs int -} - -type ResgroupConfig struct { - AccountID int - AccountName string - Location string - Name string - ID int - GridID int - ExtIP string // legacy field for VDC - this will eventually become obsoleted by true Resource Groups - Quota ResgroupQuotaConfig - Network NetworkConfig -} - -*/ \ No newline at end of file diff --git a/decort/resource_compute.go b/decort/resource_compute.go deleted file mode 100644 index 1f29eee..0000000 --- a/decort/resource_compute.go +++ /dev/null @@ -1,485 +0,0 @@ -/* -Copyright (c) 2019-2020 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 ( - - "encoding/json" - "fmt" - "log" - "net/url" - "strconv" - - "github.com/hashicorp/terraform/helper/schema" - "github.com/hashicorp/terraform/helper/validation" -) - - -func resourceComputeCreate(d *schema.ResourceData, m interface{}) error { - machine := &MachineConfig{ - ResGroupID: d.Get("rgid").(int), - Name: d.Get("name").(string), - Cpu: d.Get("cpu").(int), - Ram: d.Get("ram").(int), - ImageID: d.Get("image_id").(int), - Description: d.Get("description").(string), - } - // BootDisk - // DataDisks - // Networks - // PortForwards - // SshKeyData string - log.Printf("resourceComputeCreate: called for VM name %q, ResGroupID %d", machine.Name, machine.ResGroupID) - - var subres_list []interface{} - var subres_data map[string]interface{} - var arg_value interface{} - var arg_set bool - // boot disk list is a required argument and has only one element, - // which is of type diskSubresourceSchema - subres_list = d.Get("boot_disk").([]interface{}) - subres_data = subres_list[0].(map[string]interface{}) - machine.BootDisk.Label = subres_data["label"].(string) - machine.BootDisk.Size = subres_data["size"].(int) - machine.BootDisk.Pool = subres_data["pool"].(string) - machine.BootDisk.Provider = subres_data["provider"].(string) - - - arg_value, arg_set = d.GetOk("data_disks") - if arg_set { - log.Printf("resourceComputeCreate: calling makeDisksConfig") - machine.DataDisks, _ = makeDisksConfig(arg_value.([]interface{})) - } - - arg_value, arg_set = d.GetOk("networks") - if arg_set { - log.Printf("resourceComputeCreate: calling makeNetworksConfig") - machine.Networks, _ = makeNetworksConfig(arg_value.([]interface{})) - } - - arg_value, arg_set = d.GetOk("port_forwards") - if arg_set { - log.Printf("resourceComputeCreate: calling makePortforwardsConfig") - machine.PortForwards, _ = makePortforwardsConfig(arg_value.([]interface{})) - } - - arg_value, arg_set = d.GetOk("ssh_keys") - if arg_set { - log.Printf("resourceComputeCreate: calling makeSshKeysConfig") - machine.SshKeys, _ = makeSshKeysConfig(arg_value.([]interface{})) - } - - // create basic VM (i.e. without port forwards and ext network connections - those will be done - // by separate API calls) - d.Partial(true) - controller := m.(*ControllerCfg) - url_values := &url.Values{} - url_values.Add("cloudspaceId", fmt.Sprintf("%d", machine.ResGroupID)) - url_values.Add("name", machine.Name) - url_values.Add("description", machine.Description) - url_values.Add("vcpus", fmt.Sprintf("%d", machine.Cpu)) - url_values.Add("memory", fmt.Sprintf("%d", machine.Ram)) - url_values.Add("imageId", fmt.Sprintf("%d", machine.ImageID)) - url_values.Add("disksize", fmt.Sprintf("%d", machine.BootDisk.Size)) - if len(machine.SshKeys) > 0 { - url_values.Add("userdata", makeSshKeysArgString(machine.SshKeys)) - } - api_resp, err := controller.decortAPICall("POST", MachineCreateAPI, url_values) - if err != nil { - return err - } - d.SetId(api_resp) // machines/create API plainly returns ID of the new VM on success - machine.ID, _ = strconv.Atoi(api_resp) - d.SetPartial("name") - d.SetPartial("description") - d.SetPartial("cpu") - d.SetPartial("ram") - d.SetPartial("image_id") - d.SetPartial("boot_disk") - if len(machine.SshKeys) > 0 { - d.SetPartial("ssh_keys") - } - - log.Printf("resourceComputeCreate: new VM ID %d, name %q created", machine.ID, machine.Name) - - if len(machine.DataDisks) > 0 || len(machine.PortForwards) > 0 { - // for data disk or port foreards provisioning we have to know Tenant ID - // and Grid ID so we call utilityResgroupConfigGet method to populate these - // fields in the machine structure that will be passed to provisionVmDisks or - // provisionVmPortforwards - log.Printf("resourceComputeCreate: calling utilityResgroupConfigGet") - resgroup, err := controller.utilityResgroupConfigGet(machine.ResGroupID) - if err == nil { - machine.TenantID = resgroup.TenantID - machine.GridID = resgroup.GridID - machine.ExtIP = resgroup.ExtIP - log.Printf("resourceComputeCreate: tenant ID %d, GridID %d, ExtIP %q", - machine.TenantID, machine.GridID, machine.ExtIP) - } - } - - // - // Configure data disks - disks_ok := true - if len(machine.DataDisks) > 0 { - log.Printf("resourceComputeCreate: calling utilityVmDisksProvision for disk count %d", len(machine.DataDisks)) - if machine.TenantID == 0 { - // if TenantID is still 0 it means that we failed to get Resgroup Facts by - // a previous call to utilityResgroupGetFacts, - // hence we do not have technical ability to provision data disks - disks_ok = false - } else { - // provisionVmDisks accomplishes two steps for each data disk specification - // 1) creates the disks - // 2) attaches them to the VM - err = controller.utilityVmDisksProvision(machine) - if err != nil { - disks_ok = false - } - } - } - - if disks_ok { - d.SetPartial("data_disks") - } - - // - // Configure port forward rules - pfws_ok := true - if len(machine.PortForwards) > 0 { - log.Printf("resourceComputeCreate: calling utilityVmPortforwardsProvision for pfw rules count %d", len(machine.PortForwards)) - if machine.ExtIP == "" { - // if ExtIP is still empty it means that we failed to get Resgroup Facts by - // a previous call to utilityResgroupGetFacts, - // hence we do not have technical ability to provision port forwards - pfws_ok = false - } else { - err := controller.utilityVmPortforwardsProvision(machine) - if err != nil { - pfws_ok = false - } - } - } - if pfws_ok { - // there were no errors reported when configuring port forwards - d.SetPartial("port_forwards") - } - - // - // Configure external networks - // NOTE: currently only one external network can be attached to each VM, so in the current - // implementation we ignore all but the 1st network definition - nets_ok := true - if len(machine.Networks) > 0 { - log.Printf("resourceComputeCreate: calling utilityVmNetworksProvision for networks count %d", len(machine.Networks)) - err := controller.utilityVmNetworksProvision(machine) - if err != nil { - nets_ok = false - } - } - if nets_ok { - // there were no errors reported when configuring networks - d.SetPartial("networks") - } - - if ( disks_ok && nets_ok && pfws_ok ) { - // if there were no errors in setting any of the subresources, we may leave Partial mode - d.Partial(false) - } - - // resourceComputeRead will also update resource ID on success, so that Terraform will know - // that resource exists - return resourceComputeRead(d, m) -} - -func resourceComputeRead(d *schema.ResourceData, m interface{}) error { - log.Printf("resourceComputeRead: called for VM name %q, ResGroupID %d", - d.Get("name").(string), d.Get("rgid").(int)) - - comp_facts, err := utilityComputeCheckPresence(d, m) - if comp_facts == "" { - if err != nil { - return err - } - // VM was not found - return nil - } - - if err = flattenCompute(d, comp_facts); err != nil { - return err - } - log.Printf("resourceComputeRead: after flattenCompute: VM ID %s, VM name %q, ResGroupID %d", - d.Id(), d.Get("name").(string), d.Get("rgid").(int)) - - // Not all parameters, that we may need, are returned by machines/get API - // Continue with further reading of VM subresource parameters: - controller := m.(*ControllerCfg) - url_values := &url.Values{} - - /* - // Obtain information on external networks - url_values.Add("machineId", d.Id()) - body_string, err := controller.decortAPICall("POST", VmExtNetworksListAPI, url_values) - if err != nil { - return err - } - - net_list := ExtNetworksResp{} - err = json.Unmarshal([]byte(body_string), &net_list) - if err != nil { - return err - } - - if len(net_list) > 0 { - if err = d.Set("networks", flattenNetworks(net_list)); err != nil { - return err - } - } - */ - - /* - // Ext networks flattening is now done inside flattenCompute because it is currently based - // on data read into NICs component by machine/get API call - - if err = d.Set("networks", flattenNetworks()); err != nil { - return err - } - */ - - // - // Obtain information on port forwards - url_values.Add("cloudspaceId", fmt.Sprintf("%d",d.Get("rgid"))) - url_values.Add("machineId", d.Id()) - pfw_list := PortforwardsResp{} - body_string, err := controller.decortAPICall("POST", PortforwardsListAPI, url_values) - if err != nil { - return err - } - err = json.Unmarshal([]byte(body_string), &pfw_list) - if err != nil { - return err - } - - if len(pfw_list) > 0 { - if err = d.Set("port_forwards", flattenPortforwards(pfw_list)); err != nil { - return err - } - } - - return nil -} - -func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error { - log.Printf("resourceComputeUpdate: called for VM name %q, ResGroupID %d", - d.Get("name").(string), d.Get("rgid").(int)) - - return resourceComputeRead(d, m) -} - -func resourceComputeDelete(d *schema.ResourceData, m interface{}) error { - // NOTE: this method destroys target VM with flag "permanently", so there is no way to - // restore destroyed VM - log.Printf("resourceComputeDelete: called for VM name %q, ResGroupID %d", - d.Get("name").(string), d.Get("rgid").(int)) - - comp_facts, err := utilityComputeCheckPresence(d, m) - if comp_facts == "" { - // the target VM does not exist - in this case according to Terraform best practice - // we exit from Destroy method without error - return nil - } - - params := &url.Values{} - params.Add("machineId", d.Id()) - params.Add("permanently", "true") - - controller := m.(*ControllerCfg) - comp_facts, err = controller.decortAPICall("POST", MachineDeleteAPI, params) - if err != nil { - return err - } - - return nil -} - -func resourceComputeExists(d *schema.ResourceData, m interface{}) (bool, error) { - // Reminder: according to Terraform rules, this function should not modify its ResourceData argument - log.Printf("resourceComputeExist: called for VM name %q, ResGroupID %d", - d.Get("name").(string), d.Get("rgid").(int)) - - comp_facts, err := utilityComputeCheckPresence(d, m) - if comp_facts == "" { - if err != nil { - return false, err - } - return false, nil - } - return true, nil -} - -func resourceCompute() *schema.Resource { - return &schema.Resource { - SchemaVersion: 1, - - Create: resourceComputeCreate, - Read: resourceComputeRead, - Update: resourceComputeUpdate, - Delete: resourceComputeDelete, - Exists: resourceComputeExists, - - Timeouts: &schema.ResourceTimeout { - Create: &Timeout180s, - Read: &Timeout30s, - Update: &Timeout180s, - Delete: &Timeout60s, - Default: &Timeout60s, - }, - - Schema: map[string]*schema.Schema { - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of this virtual machine. This parameter is case sensitive.", - }, - - "rgid": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(1), - Description: "ID of the resource group where this virtual machine should be deployed.", - }, - - "cpu": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(1, 64), - Description: "Number of CPUs to allocate to this virtual machine.", - }, - - "ram": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(512), - Description: "Amount of RAM in MB to allocate to this virtual machine.", - }, - - "image_id": { - Type: schema.TypeInt, - Required: true, - ForceNew: true, - Description: "ID of the OS image to base this virtual machine on.", - }, - - "boot_disk": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Elem: &schema.Resource { - Schema: diskSubresourceSchema(), - }, - Description: "Specification for a boot disk on this virtual machine.", - }, - - "data_disks": { - Type: schema.TypeList, - Optional: true, - MaxItems: 12, - Elem: &schema.Resource { - Schema: diskSubresourceSchema(), - }, - Description: "Specification for data disks on this virtual machine.", - }, - - "guest_logins": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource { - Schema: loginsSubresourceSchema(), - }, - Description: "Specification for guest logins on this virtual machine.", - }, - - "networks": { - Type: schema.TypeList, - Optional: true, - MaxItems: 8, - Elem: &schema.Resource { - Schema: networkSubresourceSchema(), - }, - Description: "Specification for the networks to connect this virtual machine to.", - }, - - "nics": { - Type: schema.TypeList, - Computed: true, - MaxItems: 8, - Elem: &schema.Resource { - Schema: nicSubresourceSchema(), - }, - Description: "Specification for the virutal NICs allocated to this virtual machine.", - }, - - "ssh_keys": { - Type: schema.TypeList, - Optional: true, - MaxItems: 12, - Elem: &schema.Resource { - Schema: sshSubresourceSchema(), - }, - Description: "SSH keys to authorize on this virtual machine.", - }, - - "port_forwards": { - Type: schema.TypeList, - Optional: true, - MaxItems: 12, - Elem: &schema.Resource { - Schema: portforwardSubresourceSchema(), - }, - Description: "Specification for the port forwards to configure for this virtual machine.", - }, - - "description": { - Type: schema.TypeString, - Optional: true, - Description: "Description of this virtual machine.", - }, - - "user": { - Type: schema.TypeString, - Computed: true, - Description: "Default login name for the guest OS on this virtual machine.", - }, - - "password": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - Description: "Default password for the guest OS login on this virtual machine.", - }, - - }, - } -} \ No newline at end of file diff --git a/decort/resource_resgroup.go b/decort/resource_resgroup.go deleted file mode 100644 index 077d89b..0000000 --- a/decort/resource_resgroup.go +++ /dev/null @@ -1,401 +0,0 @@ -/* -Copyright (c) 2019-2021 Digital Energy Cloud Solutions. All Rights Reserved. - -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 ( - - "fmt" - "log" - "net/url" - "strconv" - "strings" - - "github.com/hashicorp/terraform/helper/schema" - -) - -func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error { - // First validate that we have all parameters required to create the new Resource Group - arg_set := false - account_name, arg_set := d.GetOk("account") - if !arg_set { - return fmt.Errorf("Cannot create new RG: missing account.") - } - rg_name, arg_set := d.GetOk("name") - if !arg_set { - return fmt.Errorf("Cannot create new RG: missing name.") - } - grid_id, arg_set := d.GetOk("grid_id") - if !arg_set { - return fmt.Errorf("Cannot create new RG %q for account %q: missing Grid ID.", - rg_name.(string), account_name.(string)) - } - - // all required parameters are set in the schema - we can continue with RG creation - log.Debugf("resourceResgroupCreate: called for RG name %q, account name %q", - account_name.(string), rg_name.(string)) - - // Valid account ID is required to create new resource group - // obtain Account ID by account name - it should not be zero on success - validated_account_id, err := utilityGetAccountIdByName(account_name.(string), m) - if err != nil { - return err - } - - // quota settings are optional - set_quota := false - var quota_record QuotaRecord - arg_value, arg_set = d.GetOk("quota") - if arg_set { - log.Debugf("resourceResgroupCreate: setting Quota on RG requested") - quota_record, _ = makeQuotaRecord(arg_value.([]interface{})) - set_quota = true - } - - controller := m.(*ControllerCfg) - log.Debugf("resourceResgroupCreate: called by user %q for RG name %q, account %q / ID %d, Grid ID %d", - controller.getdecortUsername(), - rg_name.(string), account_name.(string), validated_account_id, gird_id.(int)) - /* - type ResgroupCreateParam struct { - AccountID int `json:"accountId"` - GridId int `json:"gid"` - Name string `json:"name"` - Ram int `json:"maxMemoryCapacity"` - Disk int `json:"maxVDiskCapacity"` - Cpu int `json:"maxCPUCapacity"` - NetTraffic int `json:"maxNetworkPeerTransfer"` - ExtIPs int `json:"maxNumPublicIP"` - Owner string `json:"owner"` - DefNet string `json:"def_net"` - IPCidr string `json:"ipcidr"` - Desc string `json:"decs"` - Reason string `json:"reason"` - ExtNetID int `json:"extNetId"` - ExtIP string `json:"extIp"` -} - */ - - url_values := &url.Values{} - url_values.Add("accountId", fmt.Sprintf("%d", validated_account_id)) - url_values.Add("name", rg_name.(string)) - url_values.Add("gid", fmt.Sprintf("%d", grid_id.(int))) - url_values.Add("owner", controller.getdecortUsername()) - - // pass quota values as set - if set_quota { - url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quota_record.Cpu)) - url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quota_record.Disk)) - url_values.Add("maxMemoryCapacity", fmt.Sprintf("%d", quota_record.Ram)) - url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quota_record.ExtTraffic)) - url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quota_record.ExtIPs)) - // url_values.Add("???", fmt.Sprintf("%d", quota_record.GpuUnits)) - } - - // parse and handle network settings - def_net_type, arg_set = d.GetOk("def_net_type") - if arg_set { - ulr_values.Add("def_net", def_net_type.(string)) - } - - ipcidr, arg_set = d.GetOk("ipcidr") - if arg_set { - ulr_values.Add("ipcidr", ipcidr.(string)) - } - - ext_net_id, arg_set = d.GetOk("ext_net_id") - if arg_set { - ulr_values.Add("extNetId", ext_net_id.(int)) - } - - ext_ip, arg_set = d.GetOk("ext_ip") - if arg_set { - ulr_values.Add("extIp", ext_ip.(string)) - } - - api_resp, err := controller.decortAPICall("POST", ResgroupCreateAPI, url_values) - if err != nil { - return err - } - - d.SetId(api_resp) // rg/create API returns ID of the newly creted resource group on success - rg.ID, _ = strconv.Atoi(api_resp) - - // re-read newly created RG to make sure schema contains complete and up to date set of specifications - return resourceResgroupRead(d, m) -} - -func resourceResgroupRead(d *schema.ResourceData, m interface{}) error { - log.Debugf("resourceResgroupRead: called for RG name %q, account name %q", - d.Get("name").(string), d.Get("account").(string)) - rg_facts, err := utilityResgroupCheckPresence(d, m) - if rg_facts == "" { - // if empty string is returned from utilityResgroupCheckPresence then there is no - // such resource group and err tells so - just return it to the calling party - d.SetId("") // ensure ID is empty - return err - } - - return flattenResgroup(d, rg_facts) -} - -func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error { - log.Debugf("resourceResgroupUpdate: called for RG name %q, account name %q", - d.Get("name").(string), d.Get("account").(string)) - - do_update := false - - controller := m.(*ControllerCfg) - url_values := &url.Values{} - url_values.Add("rgId", d.Id()) - - name_new, name_set := d.GetOk("name") - if name_set { - log.Debugf("resourceResgroupUpdate: name specified - looking for deltas from the old settings.") - name_old, _ := d.GetChange("name") - if name_old.(string) != name_new.(string) { - do_update := true - url_values.Add("name", name_new.(string)) - } - } - - 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{})) - quota_value_old, _ = d.GetChange("quota") // returns old as 1st, new as 2nd return value - quotarecord_old, _ := makeQuotaRecord(quota_value_old.([]interface{})) - - if quotarecord_new.Cpu != quotarecord_old.Cpu { - do_update = true - log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu) - url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu)) - } - - if quotarecord_new.Disk != quotarecord_old.Disk { - do_update = true - log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.Disk) - url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk)) - } - - if quotarecord_new.Ram != quotarecord_old.Ram { - do_update = true - log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram) - url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram)) - } - - if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic { - do_update = true - log.Debugf("resourceResgroupUpdate: NetTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic) - url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.NetTraffic)) - } - - if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs { - do_update = true - log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs) - url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs)) - } - } - - desc_new, desc_set := d.GetOk("desc") - if desc_set { - log.Debugf("resourceResgroupUpdate: description specified - looking for deltas from the old settings.") - desc_old, _ := d.GetChange("desc") - if desc_old.(string) != desc_new.(string) { - do_update := true - url_values.Add("desc", desc_new.(string)) - } - } - - if do_update { - log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG") - _, err := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values) - if err != nil { - return err - } - } else { - log.Debugf("resourceResgroupUpdate: no difference between old and new state - no update on the RG will be done") - } - - return resourceResgroupRead(d, m) -} - -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 %q, account name %q", - d.Get("name").(string), d.Get("account").(string)) - - rg_facts, err := utilityResgroupCheckPresence(d, m) - if rg_facts == "" { - // the target RG does not exist - in this case according to Terraform best practice - // we exit from Destroy method without error - return nil - } - - url_values := &url.Values{} - url_values.Add("rgId", d.Id()) - url_values.Add("force", "true") - url_values.Add("permanently", "true") - url_values.Add("reason", "Destroyed by DECORT Terraform provider") - - controller := m.(*ControllerCfg) - _, err = controller.decortAPICall("POST", ResgroupDeleteAPI, url_values) - if err != nil { - return err - } - - return nil -} - -func resourceResgroupExists(d *schema.ResourceData, m interface{}) (bool, error) { - // Reminder: according to Terraform rules, this function should NOT modify ResourceData argument - rg_facts, err := utilityResgroupCheckPresence(d, m) - if rg_facts == "" { - if err != nil { - return false, err - } - return false, nil - } - return true, nil -} - -func resourceResgroup() *schema.Resource { - return &schema.Resource { - SchemaVersion: 1, - - Create: resourceResgroupCreate, - Read: resourceResgroupRead, - Update: resourceResgroupUpdate, - Delete: resourceResgroupDelete, - Exists: resourceResgroupExists, - - Timeouts: &schema.ResourceTimeout { - Create: &Timeout180s, - Read: &Timeout30s, - Update: &Timeout180s, - Delete: &Timeout60s, - Default: &Timeout60s, - }, - - Schema: map[string]*schema.Schema { - "name": &schema.Schema { - Type: schema.TypeString, - Required: true, - Description: "Name of this resource group. Names are case sensitive and unique within the context of a account.", - }, - - "account": &schema.Schema { - Type: schema.TypeString, - Required: true, - Description: "Name of the account, which this resource group belongs to.", - }, - - "def_net": &schema.Schema { - Type: schema.TypeString, - Optional: true, - Default: "PRIVATE" - Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.", - }, - - "ipcidr": &schema.Schema { - Type: schema.TypeString, - Optional: true, - Description: "Address of the netowrk inside the private network segment (aka ViNS) if def_net=PRIVATE", - }, - - "ext_net_id": &schema.Schema { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: "ID of the external network, which this resource group will use as default for its computes if def_net=PUBLIC", - }, - - "ext_ip": &schema.Schema { - Type: schema.TypeString, - Optional: true, - Description: "IP address on the external netowrk to request, if def_net=PUBLIC", - }, - - "account_id": &schema.Schema { - Type: schema.TypeInt, - Computed: true, - Description: "Unique ID of the account, which this resource group belongs to.", - }, - - "grid_id": &schema.Schema { - Type: schema.TypeInt, - Required: true, - Description: "Unique ID of the grid, where this resource group is deployed.", - }, - - "quota": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource { - Schema: quotasSubresourceSchema(), - }, - Description: "Quota settings for this resource group.", - }, - - "desc": { - Type: schema.TypeString, - Optional: true, - Description: "User-defined text description of this resource group.", - }, - - "status": { - Type: schema.TypeString, - Computed: true, - Description: "Current status of this resource group.", - }, - - "def_net_id": &schema.Schema { - Type: schema.TypeInt, - Computed: true, - Description: "ID of the default network for this resource group (if any).", - }, - - "vins": { - Type: schema.TypeList, // this is a list of ints - Computed: true, - MaxItems: LimitMaxVinsPerResgroup, - Elem: &schema.Schema { - Type: schema.TypeInt, - }, - Description: "List of VINs deployed in this resource group.", - }, - - "computes": { - Type: schema.TypeList, // this is a list of ints - Computed: true, - Elem: &schema.Schema { - Type: schema.TypeInt, - }, - Description: "List of computes deployed in this resource group.", - }, - }, - } -} \ No newline at end of file diff --git a/decort/utility_disk.go b/decort/utility_disk.go deleted file mode 100644 index fb4f5d3..0000000 --- a/decort/utility_disk.go +++ /dev/null @@ -1,120 +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 ( - - "encoding/json" - "fmt" - "net/url" - "strconv" - - "github.com/hashicorp/terraform/helper/schema" - // "github.com/hashicorp/terraform/helper/validation" -) - - -func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { - // This function tries to locate Disk by one of the following algorithms depending on - // the parameters passed: - // - if disk ID is specified -> by disk ID - // - if disk name is specifeid -> by disk name and either account ID or account name - // - // NOTE: disk names are not unique, so the first occurence of this name in the account will - // be returned. There is no such ambiguity when locating disk by its ID. - // - // If succeeded, it returns non empty string that contains JSON formatted facts about the disk - // as returned by disks/get API call. - // Otherwise it returns empty string and meaningful error. - // - // This function does not modify its ResourceData argument, so it is safe to use it as core - // method for resource's Exists method. - // - - controller := m.(*ControllerCfg) - url_values := &url.Values{} - - disk_id, arg_set := d.GetOk("disk_id") - if arg_set { - // go straight for the disk by its ID - log.Debugf("utilityDiskCheckPresence: locating disk by its ID %d", disk_id.(int)) - url_values.Add("diskId", fmt.Sprintf("%d", disk_id.(int))) - disk_facts, err := controller.decortAPICall("POST", DisksGetAPI, url_values) - if err != nil { - return "", err - } - return body_string, nil - } - - disk_name, arg_set := d.GetOk("name") - if !arg_set { - // no disk ID and no disk name - we cannot locate disk in this case - return "", fmt.Error("Cannot locate disk if name is empty and no disk ID specified.") - } - - account_id, acc_id_set := d.GetOk("account_id") - if !acc_id_set { - account_name, arg_set := d.GetOkd("account_name") - if !arg_set { - return "", fmt.Error("Cannot locate disk by name %s if neither account ID nor account name are set", disk_name.(string)) - } - } - - url_values.Add("accountId", fmt.Sprintf("%d", account_id.(int))) - disk_facts, err := controller.decortAPICall("POST", DisksListAPI, url_values) - if err != nil { - return "", err - } - - log.Debugf("utilityDiskCheckPresence: ready to unmarshal string %q", disk_facts) - - disks_list := []DiskRecord - err = json.Unmarshal([]byte(disk_facts), &disks_list) - if err != nil { - return "", err - } - - // log.Printf("%#v", vm_list) - log.Debugf("utilityDiskCheckPresence: traversing decoded JSON of length %d", len(disks_list)) - for _, item := range disks_list { - // need to match disk by name, return the first match - if item.Name == disk_name && item.Status != "DESTROYED" { - log.Printf("utilityDiskCheckPresence: index %d, matched disk name %q", index, item.Name) - // we found the disk we need - not get detailed information via API call to disks/get - // TODO: this may not be optimal as it initiates one extra call to the DECORT controller - // in spite of the fact that we already have all required information about the disk in - // item variable - get_url_values := &url.Values{} - get_url_values.Add("diskId", fmt.Sprintf("%d", item.ID)) - disk_facts, err = controller.decortAPICall("POST", DisksGetAPI, get_url_values) - if err != nil { - return "", err - } - return disk_facts, nil - } - } - - return "", nil // there should be no error if disk does not exist -} \ No newline at end of file diff --git a/decort/utility_resgroup.go b/decort/utility_resgroup.go deleted file mode 100644 index 480a3eb..0000000 --- a/decort/utility_resgroup.go +++ /dev/null @@ -1,154 +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 ( - - "encoding/json" - "fmt" - "log" - "net/url" - // "strconv" - - "github.com/hashicorp/terraform/helper/schema" - // "github.com/hashicorp/terraform/helper/validation" -) - -func (ctrl *ControllerCfg) utilityResgroupConfigGet(rgid int) (*ResgroupGetResp, error) { - url_values := &url.Values{} - url_values.Add("rgId", fmt.Sprintf("%d", rgid)) - resgroup_facts, err := ctrl.decortAPICall("POST", ResgroupGetAPI, url_values) - if err != nil { - return nil, err - } - - log.Debugf("utilityResgroupConfigGet: ready to unmarshal string %q", resgroup_facts) - model := &ResgroupGetResp{} - err = json.Unmarshal([]byte(resgroup_facts), 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) { - // This function tries to locate resource group by its name and account name. - // If succeeded, it returns non empty string that contains JSON formatted facts about the - // resource group as returned by cloudspaces/get API call. - // Otherwise it returns empty string and meaningful error. - // - // NOTE: As our provider always deletes RGs permanently, there is no "restore" method and - // consequently we are not interested in matching RGs in DELETED state. Hence, we call - // .../rg/list API with includedeleted=false - // - // This function does not modify its ResourceData argument, so it is safe to use it as core - // method for the Terraform resource Exists method. - // - name := d.Get("name").(string) - account_name := d.Get("account").(string) - - controller := m.(*ControllerCfg) - url_values := &url.Values{} - url_values.Add("includedeleted", "false") - body_string, err := controller.decortAPICall("POST", ResgroupListAPI, url_values) - if err != nil { - return "", err - } - - log.Debugf("%s", body_string) - log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %q", ResgroupListAPI) - model := ResgroupListResp{} - err = json.Unmarshal([]byte(body_string), &model) - if err != nil { - return "", err - } - - log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model)) - for index, item := range model { - // need to match RG by name & account name - if item.Name == name && item.AccountName == account_name { - log.Debugf("utilityResgroupCheckPresence: match RG name %q / ID %d, account %q at index %d", - item.Name, item.ID, item.AccountName, index) - - // not all required information is returned by rg/list API, so we need to initiate one more - // call to rg/get to obtain extra data to complete Resource population. - // Namely, we need to extract resource quota settings - req_values := &url.Values{} - req_values.Add("rgId", fmt.Sprintf("%d", item.ID)) - body_string, err := controller.decortAPICall("POST", ResgroupGetAPI, req_values) - if err != nil { - return "", err - } - - return body_string, nil - } - } - - return "", fmt.Errorf("Cannot find RG name %q owned by account %q", name, account_name) -} - -func utilityGetAccountIdByName(account_name string, m interface{}) (int, error) { - controller := m.(*ControllerCfg) - url_values := &url.Values{} - body_string, err := controller.decortAPICall("POST", AccountsListAPI, url_values) - if err != nil { - return 0, err - } - - model := AccountsListResp{} - err = json.Unmarshal([]byte(body_string), &model) - if err != nil { - return 0, err - } - - log.Debugf("utilityGetAccountIdByName: traversing decoded Json of length %d", len(model)) - for index, item := range model { - // need to match Account by name - if item.Name == account_name { - log.Debugf("utilityGetAccountIdByName: match Account name %q / ID %d at index %d", - item.Name, item.ID, index) - return item.ID, nil - } - } - - return 0, fmt.Errorf("Cannot find account %q for the current user. Check account name and your access rights", account_name) -} \ No newline at end of file diff --git a/decort/utility_vm.go b/decort/utility_vm.go deleted file mode 100644 index e668662..0000000 --- a/decort/utility_vm.go +++ /dev/null @@ -1,159 +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 ( - - "encoding/json" - "fmt" - "net/url" - "strconv" - - "github.com/hashicorp/terraform/helper/schema" - // "github.com/hashicorp/terraform/helper/validation" -) - -func (ctrl *ControllerCfg) utilityVmDisksProvision(mcfg *MachineConfig) error { - for index, disk := range mcfg.DataDisks { - url_values := &url.Values{} - // url_values.Add("machineId", fmt.Sprintf("%d", mcfg.ID)) - url_values.Add("accountId", fmt.Sprintf("%d", mcfg.TenantID)) - url_values.Add("gid", fmt.Sprintf("%d", mcfg.GridID)) - url_values.Add("name", fmt.Sprintf("%s", disk.Label)) - url_values.Add("description", fmt.Sprintf("Data disk for VM ID %d / VM Name: %s", mcfg.ID, mcfg.Name)) - url_values.Add("size", fmt.Sprintf("%d", disk.Size)) - url_values.Add("type", "D") - // url_values.Add("iops", ) - - disk_id_resp, err := ctrl.decortAPICall("POST", DiskCreateAPI, url_values) - if err != nil { - // failed to create disk - partial resource update - return err - } - // disk created - API call returns disk ID as a string - use it to update - // disk ID in the corresponding MachineConfig.DiskConfig record - - mcfg.DataDisks[index].ID, err = strconv.Atoi(disk_id_resp) - if err != nil { - // failed to convert disk ID into proper integer value - partial resource update - return err - } - - // now that we have disk created and stored its ID in the mcfg.DataDisks[index].ID - // we can attempt attaching the disk to the VM - url_values = &url.Values{} - // url_values.Add("machineId", fmt.Sprintf("%d", mcfg.ID)) - url_values.Add("machineId", fmt.Sprintf("%d", mcfg.ID)) - url_values.Add("diskId", disk_id_resp) - _, err = ctrl.decortAPICall("POST", DiskAttachAPI, url_values) - if err != nil { - // failed to attach disk - partial resource update - return err - } - } - return nil -} - - -func (ctrl *ControllerCfg) utilityVmPortforwardsProvision(mcfg *MachineConfig) error { - for _, rule := range mcfg.PortForwards { - url_values := &url.Values{} - url_values.Add("machineId", fmt.Sprintf("%d", mcfg.ID)) - url_values.Add("cloudspaceId", fmt.Sprintf("%d", mcfg.ResGroupID)) - url_values.Add("publicIp", mcfg.ExtIP) // this may be obsoleted by Resource group implementation - url_values.Add("publicPort", fmt.Sprintf("%d", rule.ExtPort)) - url_values.Add("localPort", fmt.Sprintf("%d", rule.IntPort)) - url_values.Add("protocol", rule.Proto) - _, err := ctrl.decortAPICall("POST", PortforwardingCreateAPI, url_values) - if err != nil { - // failed to create port forward rule - partial resource update - return err - } - } - return nil -} - -func (ctrl *ControllerCfg) utilityVmNetworksProvision(mcfg *MachineConfig) error { - for _, net := range mcfg.Networks { - url_values := &url.Values{} - url_values.Add("machineId", fmt.Sprintf("%d", mcfg.ID)) - url_values.Add("externalNetworkId", fmt.Sprintf("%d", net.NetworkID)) - _, err := ctrl.decortAPICall("POST", AttachExternalNetworkAPI, url_values) - if err != nil { - // failed to attach network - partial resource update - return err - } - } - return nil -} - -func utilityVmCheckPresence(d *schema.ResourceData, m interface{}) (string, error) { - // This function tries to locate VM by its name and resource group ID - // if succeeded, it returns non empty string that contains JSON formatted facts about the VM - // as returned by machines/get API call. - // Otherwise it returns empty string and meaningful error. - // - // This function does not modify its ResourceData argument, so it is safe to use it as core - // method for resource's Exists method. - // - name := d.Get("name").(string) - rgid := d.Get("rgid").(int) - - controller := m.(*ControllerCfg) - list_url_values := &url.Values{} - list_url_values.Add("cloudspaceId", fmt.Sprintf("%d",rgid)) - body_string, err := controller.decortAPICall("POST", MachinesListAPI, list_url_values) - if err != nil { - return "", err - } - - // log.Printf("%s", body_string) - // log.Printf("dataSourceVmRead: ready to decode mashines/list response body") - vm_list := MachinesListResp{} - err = json.Unmarshal([]byte(body_string), &vm_list) - if err != nil { - return "", err - } - - // log.Printf("%#v", vm_list) - // log.Printf("dataSourceVmRead: traversing decoded JSON of length %d", len(vm_list)) - for _, item := range vm_list { - // need to match VM by name, skip VMs with the same name in DESTROYED satus - if item.Name == name && item.Status != "DESTROYED" { - // log.Printf("dataSourceVmRead: index %d, matched name %q", index, item.Name) - // we found the VM we need - not get detailed information via API call to cloudapi/machines/get - get_url_values := &url.Values{} - get_url_values.Add("machineId", fmt.Sprintf("%d", item.ID)) - body_string, err = controller.decortAPICall("POST", MachinesGetAPI, get_url_values) - if err != nil { - return "", err - } - return body_string, nil - } - } - - return "", nil // there should be no error if VM does not exist - // return "", fmt.Errorf("Cannot find VM name %q in resource group ID %d", name, rgid) -} \ No newline at end of file