diff --git a/decort/data_source_disk_list.go b/decort/data_source_disk_list.go new file mode 100644 index 0000000..fa118aa --- /dev/null +++ b/decort/data_source_disk_list.go @@ -0,0 +1,391 @@ +/* +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" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func flattenDiskList(dl DisksListResp) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, disk := range dl { + diskAcl, _ := json.Marshal(disk.Acl) + diskIotune, _ := json.Marshal(disk.IOTune) + temp := map[string]interface{}{ + "account_id": disk.AccountID, + "account_name": disk.AccountName, + "acl": string(diskAcl), + "boot_partition": disk.BootPartition, + "compute_id": disk.ComputeID, + "compute_name": disk.ComputeName, + "created_time": disk.CreatedTime, + "deleted_time": disk.DeletedTime, + "desc": disk.Desc, + "destruction_time": disk.DestructionTime, + "devicename": disk.DeviceName, + "disk_path": disk.DiskPath, + "gid": disk.GridID, + "guid": disk.GUID, + "disk_id": disk.ID, + "image_id": disk.ImageID, + "images": disk.Images, + "iotune": string(diskIotune), + "iqn": disk.IQN, + "login": disk.Login, + "machine_id": disk.MachineId, + "machine_name": disk.MachineName, + "milestones": disk.Milestones, + "name": disk.Name, + "order": disk.Order, + "params": disk.Params, + "parent_id": disk.ParentId, + "passwd": disk.Passwd, + "pci_slot": disk.PciSlot, + "pool": disk.Pool, + "purge_attempts": disk.PurgeAttempts, + "purge_time": disk.PurgeTime, + "reality_device_number": disk.RealityDeviceNumber, + "reference_id": disk.ReferenceId, + "res_id": disk.ResID, + "res_name": disk.ResName, + "role": disk.Role, + "sep_id": disk.SepID, + "sep_type": disk.SepType, + "size_max": disk.SizeMax, + "size_used": disk.SizeUsed, + "snapshots": flattendDiskSnapshotList(disk.Snapshots), + "status": disk.Status, + "tech_status": disk.TechStatus, + "type": disk.Type, + "vmid": disk.VMID, + "update_by": disk.UpdateBy, + } + res = append(res, temp) + } + return res + +} + +func flattendDiskSnapshotList(sl SnapshotRecordList) []interface{} { + res := make([]interface{}, 0) + for _, snapshot := range sl { + temp := map[string]interface{}{ + "guid": snapshot.Guid, + "label": snapshot.Label, + "res_id": snapshot.ResId, + "snap_set_guid": snapshot.SnapSetGuid, + "snap_set_time": snapshot.SnapSetTime, + "timestamp": snapshot.TimeStamp, + } + res = append(res, temp) + } + + return res + +} + +func dataSourceDiskListRead(d *schema.ResourceData, m interface{}) error { + diskList, err := utilityDiskListCheckPresence(d, m) + if err != nil { + return err + } + + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenDiskList(diskList)) + + return nil +} + +func dataSourceDiskListSchemaMake() map[string]*schema.Schema { + res := map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the account the disks belong to", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: "type of the disks", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "Page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "Page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeInt, + Computed: true, + }, + "account_name": { + Type: schema.TypeString, + Computed: true, + }, + "acl": { + Type: schema.TypeString, + Computed: true, + }, + "boot_partition": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_id": { + Type: schema.TypeInt, + Computed: true, + }, + "compute_name": { + Type: schema.TypeString, + Computed: true, + }, + "created_time": { + Type: schema.TypeInt, + Computed: true, + }, + "deleted_time": { + Type: schema.TypeInt, + Computed: true, + }, + "desc": { + Type: schema.TypeString, + Computed: true, + }, + "destruction_time": { + Type: schema.TypeInt, + Computed: true, + }, + "devicename": { + Type: schema.TypeString, + Computed: true, + }, + "disk_path": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "disk_id": { + Type: schema.TypeInt, + Computed: true, + }, + "image_id": { + Type: schema.TypeInt, + Computed: true, + }, + "images": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "iotune": { + Type: schema.TypeString, + Computed: true, + }, + "iqn": { + Type: schema.TypeString, + Computed: true, + }, + "login": { + Type: schema.TypeString, + Computed: true, + }, + "machine_id": { + Type: schema.TypeInt, + Computed: true, + }, + "machine_name": { + Type: schema.TypeString, + Computed: true, + }, + "milestones": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "order": { + Type: schema.TypeInt, + Computed: true, + }, + "params": { + Type: schema.TypeString, + Computed: true, + }, + "parent_id": { + Type: schema.TypeInt, + Computed: true, + }, + "passwd": { + Type: schema.TypeString, + Computed: true, + }, + "pci_slot": { + Type: schema.TypeInt, + Computed: true, + }, + "pool": { + Type: schema.TypeString, + Computed: true, + }, + "purge_attempts": { + Type: schema.TypeInt, + Computed: true, + }, + "purge_time": { + Type: schema.TypeInt, + Computed: true, + }, + "reality_device_number": { + Type: schema.TypeInt, + Computed: true, + }, + "reference_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "res_name": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + }, + "sep_type": { + Type: schema.TypeString, + Computed: true, + }, + "size_max": { + Type: schema.TypeInt, + Computed: true, + }, + "size_used": { + Type: schema.TypeInt, + Computed: true, + }, + "snapshots": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "guid": { + Type: schema.TypeString, + Computed: true, + }, + "label": { + Type: schema.TypeString, + Computed: true, + }, + "res_id": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_guid": { + Type: schema.TypeString, + Computed: true, + }, + "snap_set_time": { + Type: schema.TypeInt, + Computed: true, + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tech_status": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vmid": { + Type: schema.TypeInt, + Computed: true, + }, + "update_by": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + } + return res +} + +func dataSourceDiskList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Read: dataSourceDiskListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &Timeout30s, + Default: &Timeout60s, + }, + + Schema: dataSourceDiskListSchemaMake(), + } +} diff --git a/decort/models_api.go b/decort/models_api.go index ee1e5e3..034cb17 100644 --- a/decort/models_api.go +++ b/decort/models_api.go @@ -298,46 +298,62 @@ const ComputeResizeAPI = "/restmachine/cloudapi/compute/resize" type SnapshotRecord struct { Guid string `json:"guid"` Label string `json:"label"` + ResId string `json:"resId"` SnapSetGuid string `json:"snapSetGuid"` SnapSetTime uint64 `json:"snapSetTime"` TimeStamp uint64 `json:"timestamp"` } +type SnapshotRecordList []SnapshotRecord + type DiskRecord struct { - // ACLs `json:"ACL"` - it is a dictionary, special parsing required - // was - Acl map[string]string `json:"acl"` - AccountID int `json:"accountId"` - AccountName string `json:"accountName"` // NOTE: absent from compute/get output - BootPartition int `json:"bootPartition"` - CreatedTime uint64 `json:"creationTime"` - DeletedTime uint64 `json:"deletionTime"` - Desc string `json:"desc"` - DestructionTime uint64 `json:"destructionTime"` - DiskPath string `json:"diskPath"` - GridID int `json:"gid"` - ID uint `json:"id"` - ImageID int `json:"imageId"` - Images []int `json:"images"` - // IOTune 'json:"iotune" - it is a dictionary - Name string `json:"name"` - // Order `json:"order"` - ParentId int `json:"parentId"` - PciSlot int `json:"pciSlot"` - // ResID string `json:"resId"` - // ResName string `json:"resName"` - // Params string `json:"params"` - Pool string `json:"pool"` - PurgeTime uint64 `json:"purgeTime"` - // Role string `json:"role"` - SepType string `json:"sepType"` - SepID int `json:"sepId"` // NOTE: absent from compute/get output - SizeMax int `json:"sizeMax"` - SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space - Snapshots []SnapshotRecord `json:"snapshots"` - Status string `json:"status"` - TechStatus string `json:"techStatus"` - Type string `json:"type"` - ComputeID int `json:"vmid"` + Acl map[string]interface{} `json:"acl"` + AccountID int `json:"accountId"` + AccountName string `json:"accountName"` + BootPartition int `json:"bootPartition"` + CreatedTime uint64 `json:"creationTime"` + ComputeID int `json:"computeId"` + ComputeName string `json:"computeName"` + DeletedTime uint64 `json:"deletionTime"` + DeviceName string `json:"devicename"` + Desc string `json:"desc"` + DestructionTime uint64 `json:"destructionTime"` + DiskPath string `json:"diskPath"` + GridID int `json:"gid"` + GUID int `json:"guid"` + ID uint `json:"id"` + ImageID int `json:"imageId"` + Images []int `json:"images"` + IOTune map[string]interface{} `json:"iotune"` + IQN string `json:"iqn"` + Login string `json:"login"` + Name string `json:"name"` + MachineId int `json:"machineId"` + MachineName string `json:"machineName"` + Milestones uint64 `json:"milestones"` + Order int `json:"order"` + Params string `json:"params"` + Passwd string `json:"passwd"` + ParentId int `json:"parentId"` + PciSlot int `json:"pciSlot"` + Pool string `json:"pool"` + PurgeTime uint64 `json:"purgeTime"` + PurgeAttempts uint64 `json:"purgeAttempts"` + RealityDeviceNumber int `json:"realityDeviceNumber"` + ReferenceId string `json:"referenceId"` + ResID string `json:"resId"` + ResName string `json:"resName"` + Role string `json:"role"` + SepType string `json:"sepType"` + SepID int `json:"sepId"` // NOTE: absent from compute/get output + SizeMax int `json:"sizeMax"` + SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space + Snapshots []SnapshotRecord `json:"snapshots"` + Status string `json:"status"` + TechStatus string `json:"techStatus"` + Type string `json:"type"` + UpdateBy uint64 `json:"updateBy"` + VMID int `json:"vmid"` } type OsUserRecord struct { @@ -502,6 +518,7 @@ const DisksCreateAPI = "/restmachine/cloudapi/disks/create" const DisksGetAPI = "/restmachine/cloudapi/disks/get" // Returns single DiskRecord on success const DisksListAPI = "/restmachine/cloudapi/disks/list" // Returns list of DiskRecord on success + type DisksListResp []DiskRecord // diff --git a/decort/provider.go b/decort/provider.go index c2a4aa1..2d9e3a9 100644 --- a/decort/provider.go +++ b/decort/provider.go @@ -137,6 +137,7 @@ func Provider() *schema.Provider { "decort_sep_disk_list": dataSourceSepDiskList(), "decort_sep_config": dataSourceSepConfig(), "decort_sep_pool": dataSourceSepPool(), + "decort_disk_list": dataSourceDiskList(), // "decort_pfw": dataSourcePfw(), }, diff --git a/decort/utility_disk_list.go b/decort/utility_disk_list.go new file mode 100644 index 0000000..447f92c --- /dev/null +++ b/decort/utility_disk_list.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +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" + "net/url" + "strconv" + "strings" + + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func utilityDiskListCheckPresence(d *schema.ResourceData, m interface{}) (DisksListResp, error) { + diskList := DisksListResp{} + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + + if page, ok := d.GetOk("page"); ok { + urlValues.Add("page", strconv.Itoa(page.(int))) + } + if size, ok := d.GetOk("size"); ok { + urlValues.Add("size", strconv.Itoa(size.(int))) + } + if diskType, ok := d.GetOk("type"); ok { + urlValues.Add("type", strings.ToUpper(diskType.(string))) + } + if accountId, ok := d.GetOk("accountId"); ok { + urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + } + + log.Debugf("utilityDiskListCheckPresence: load grid list") + diskListRaw, err := controller.decortAPICall("POST", DisksListAPI, urlValues) + if err != nil { + return nil, err + } + + err = json.Unmarshal([]byte(diskListRaw), &diskList) + if err != nil { + return nil, err + } + + return diskList, nil +} diff --git a/samples/README.md b/samples/README.md index 3a20964..d2e8e05 100644 --- a/samples/README.md +++ b/samples/README.md @@ -18,6 +18,7 @@ - sep_pool - sep_consumption - vgpu + - disk_list - resources: - image - virtual_image diff --git a/samples/data_disk_list/main.tf b/samples/data_disk_list/main.tf new file mode 100644 index 0000000..1074f83 --- /dev/null +++ b/samples/data_disk_list/main.tf @@ -0,0 +1,54 @@ +/* +Пример использования +Получение списка доступных дисков +*/ +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "1.1" + source = "digitalenergy.online/decort/decort" + } + } +} +*/ + + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + +data "decort_disk_list" "dl" { + #id аккаунта для получения списка дисков + #опциональный параметр + #тип - число + #account_id = 11111 + + #тип диска + #опциональный параметр + #тип - строка + #возможные типы: "b" - boot_disk, "d" - data_disk + #type = "d" + + #кол-во страниц для вывода + #опицональный параметр + #тип - число + #page = 1 + + #размер страницы + #опицональный параметр + #тип - число + #size = 1 +} + +output "test" { + value = data.decort_disk_list.dl +}