From 13e6849328f5ca97a93590851dd624f8d1148ded Mon Sep 17 00:00:00 2001 From: Stanislav Solovev Date: Wed, 30 Mar 2022 17:13:16 +0300 Subject: [PATCH] Features/snapshot --- README.md | 2 +- decort/data_snapshot_list.go | 120 +++++++++++++++++ decort/models_api.go | 18 +++ decort/provider.go | 2 + decort/resource_snapshot.go | 203 +++++++++++++++++++++++++++++ decort/utility_snapshot.go | 55 ++++++++ decort/utility_snapshot_list.go | 56 ++++++++ samples/README.md | 2 + samples/data_snapshot_list/main.tf | 40 ++++++ samples/resource_snapshot/main.tf | 56 ++++++++ 10 files changed, 553 insertions(+), 1 deletion(-) create mode 100644 decort/data_snapshot_list.go create mode 100644 decort/resource_snapshot.go create mode 100644 decort/utility_snapshot.go create mode 100644 decort/utility_snapshot_list.go create mode 100644 samples/data_snapshot_list/main.tf create mode 100644 samples/resource_snapshot/main.tf diff --git a/README.md b/README.md index c3f1faf..2c563e3 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Linux: ``` Windows: ```powershell -%APPDATA%\terraform.d\plugins\${host_name}/${namespace}/${type}/${version}/${target} +%APPDATA%\terraform.d\plugins\${host_name}\${namespace}\${type}\${version}\${target} ``` ВНИМАНИЕ: для ОС Windows `%APP_DATA%` является каталогом, в котором будут помещены будущие файлы terraform. Где: diff --git a/decort/data_snapshot_list.go b/decort/data_snapshot_list.go new file mode 100644 index 0000000..d6f2144 --- /dev/null +++ b/decort/data_snapshot_list.go @@ -0,0 +1,120 @@ +/* +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 ( + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func flattenSnapshotList(gl SnapshotList) []map[string]interface{} { + res := make([]map[string]interface{}, 0) + for _, item := range gl { + temp := map[string]interface{}{ + "label": item.Label, + "guid": item.Guid, + "disks": item.Disks, + "timestamp": item.Timestamp, + } + + res = append(res, temp) + } + return res +} + +func dataSourceSnapshotListRead(d *schema.ResourceData, m interface{}) error { + snapshotList, err := utilitySnapshotListCheckPresence(d, m) + if err != nil { + return err + } + id := uuid.New() + d.SetId(id.String()) + d.Set("items", flattenSnapshotList(snapshotList)) + + return nil +} + +func dataSourceSnapshotListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: "ID of the compute instance to create snapshot for.", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "snapshot list", + Elem: &schema.Resource{ + Schema: dataSourceSnapshotSchemaMake(), + }, + }, + } + + return rets +} + +func dataSourceSnapshotSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "label": { + Type: schema.TypeString, + Computed: true, + Description: "text label for snapshot. Must be unique among this compute snapshots.", + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "timestamp", + }, + } +} + +func dataSourceSnapshotList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Read: dataSourceSnapshotListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &Timeout30s, + Default: &Timeout60s, + }, + + Schema: dataSourceSnapshotListSchemaMake(), + } +} diff --git a/decort/models_api.go b/decort/models_api.go index 6abe147..5e984bd 100644 --- a/decort/models_api.go +++ b/decort/models_api.go @@ -799,3 +799,21 @@ type Grid struct { } type GridList []Grid + +///////////////////// +/// SNAPSHOT API /// +///////////////////// + +const snapshotCreateAPI = "/restmachine/cloudapi/compute/snapshotCreate" +const snapshotDeleteAPI = "/restmachine/cloudapi/compute/snapshotDelete" +const snapshotRollbackAPI = "/restmachine/cloudapi/compute/snapshotRollback" +const snapshotListAPI = "/restmachine/cloudapi/compute/snapshotList" + +type Snapshot struct { + Disks []int `json:"disks"` + Guid string `json:"guid"` + Label string `json:"label"` + Timestamp uint64 `json:"timestamp"` +} + +type SnapshotList []Snapshot diff --git a/decort/provider.go b/decort/provider.go index f7f26a5..98a99fa 100644 --- a/decort/provider.go +++ b/decort/provider.go @@ -110,6 +110,7 @@ func Provider() *schema.Provider { "decort_virtual_image": resourceVirtualImage(), "decort_cdrom_image": resourceCDROMImage(), "decort_delete_images": resourceDeleteImages(), + "decort_snapshot": resourceSnapshot(), }, DataSourcesMap: map[string]*schema.Resource{ @@ -123,6 +124,7 @@ func Provider() *schema.Provider { "decort_grid_list": dataSourceGridList(), "decort_image_list": dataSourceImageList(), "decort_image_list_stacks": dataSourceImageListStacks(), + "decort_snapshot_list": dataSourceSnapshotList(), // "decort_pfw": dataSourcePfw(), }, diff --git a/decort/resource_snapshot.go b/decort/resource_snapshot.go new file mode 100644 index 0000000..75f2b29 --- /dev/null +++ b/decort/resource_snapshot.go @@ -0,0 +1,203 @@ +/* +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 ( + "net/url" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + log "github.com/sirupsen/logrus" +) + +func resourceSnapshotCreate(d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSnapshotCreate: called for snapshot %s", d.Get("label").(string)) + + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + urlValues.Add("label", d.Get("label").(string)) + urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) + + snapshotId, err := controller.decortAPICall("POST", snapshotCreateAPI, urlValues) + if err != nil { + return err + } + + snapshotId = strings.ReplaceAll(snapshotId, "\"", "") + + d.SetId(snapshotId) + d.Set("guid", snapshotId) + + err = resourceSnapshotRead(d, m) + if err != nil { + return err + } + + return nil +} + +func resourceSnapshotRead(d *schema.ResourceData, m interface{}) error { + snapshot, err := utilitySnapshotCheckPresence(d, m) + if err != nil { + return err + } + + d.Set("timestamp", snapshot.Timestamp) + d.Set("guid", snapshot.Guid) + d.Set("disks", snapshot.Disks) + d.Set("label", snapshot.Label) + + return nil +} + +func resourceSnapshotDelete(d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceSnapshotDelete: called for %s, id: %s", d.Get("label").(string), d.Id()) + + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) + urlValues.Add("label", d.Get("label").(string)) + + _, err := controller.decortAPICall("POST", snapshotDeleteAPI, urlValues) + if err != nil { + return err + } + d.SetId("") + + return nil +} + +func resourceSnapshotExists(d *schema.ResourceData, m interface{}) (bool, error) { + snapshot, err := utilitySnapshotCheckPresence(d, m) + if err != nil { + return false, err + } + if snapshot == nil { + return false, nil + } + + return true, nil +} + +func resourceSnapshotEdit(d *schema.ResourceData, m interface{}) error { + err := resourceSnapshotRead(d, m) + if err != nil { + return err + } + + return nil +} + +func resourceSnapshotRollback(d *schema.ResourceDiff, m interface{}) error { + c := m.(*ControllerCfg) + urlValues := &url.Values{} + + urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) + urlValues.Add("label", d.Get("label").(string)) + + _, err := c.decortAPICall("POST", snapshotRollbackAPI, urlValues) + if err != nil { + return err + } + return nil +} + +func resourceSnapshotSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "compute_id": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: "ID of the compute instance to create snapshot for.", + }, + "label": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "text label for snapshot. Must be unique among this compute snapshots.", + }, + "rollback": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "is rollback the snapshot", + }, + "disks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + "guid": { + Type: schema.TypeString, + Computed: true, + Description: "guid of the snapshot", + }, + "timestamp": { + Type: schema.TypeInt, + Computed: true, + Description: "timestamp", + }, + } +} + +func resourceSnapshot() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Create: resourceSnapshotCreate, + Read: resourceSnapshotRead, + Update: resourceSnapshotEdit, + Delete: resourceSnapshotDelete, + Exists: resourceSnapshotExists, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: &Timeout60s, + Read: &Timeout30s, + Update: &Timeout60s, + Delete: &Timeout60s, + Default: &Timeout60s, + }, + + CustomizeDiff: customdiff.All( + customdiff.IfValueChange("rollback", func(old, new, meta interface{}) bool { + o := old.(bool) + if o != new.(bool) && o == false { + return true + } + return false + }, resourceSnapshotRollback), + ), + + Schema: resourceSnapshotSchemaMake(), + } +} diff --git a/decort/utility_snapshot.go b/decort/utility_snapshot.go new file mode 100644 index 0000000..6e7abbc --- /dev/null +++ b/decort/utility_snapshot.go @@ -0,0 +1,55 @@ +/* +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 ( + "errors" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func utilitySnapshotCheckPresence(d *schema.ResourceData, m interface{}) (*Snapshot, error) { + snapShotList, err := utilitySnapshotListCheckPresence(d, m) + if err != nil { + return nil, err + } + + findId := "" + + if (d.Get("guid").(string)) != "" { + findId = d.Get("guid").(string) + } else { + findId = d.Id() + } + + for _, s := range snapShotList { + if s.Guid == findId { + return &s, nil + } + } + + return nil, errors.New("snapshot not found") + +} diff --git a/decort/utility_snapshot_list.go b/decort/utility_snapshot_list.go new file mode 100644 index 0000000..9171d23 --- /dev/null +++ b/decort/utility_snapshot_list.go @@ -0,0 +1,56 @@ +/* +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" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func utilitySnapshotListCheckPresence(d *schema.ResourceData, m interface{}) (SnapshotList, error) { + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int))) + + resp, err := controller.decortAPICall("POST", snapshotListAPI, urlValues) + if err != nil { + return nil, err + } + + if resp == "" { + return nil, nil + } + + snapshotList := SnapshotList{} + if err := json.Unmarshal([]byte(resp), &snapshotList); err != nil { + //return nil, errors.New(fmt.Sprint("Can not unmarshall data to snapshotList: ", resp, " ", snapshotList)) + return nil, err + } + + return snapshotList, nil +} diff --git a/samples/README.md b/samples/README.md index 80fa37a..d2b060f 100644 --- a/samples/README.md +++ b/samples/README.md @@ -8,6 +8,7 @@ - image - image_list - image_list_stacks + - snapshot_list - resources: - image - virtual_image @@ -15,6 +16,7 @@ - delete_images - k8s - k8s_wg + - snapshot ## Как пользоваться примерами 1. Установить terraform diff --git a/samples/data_snapshot_list/main.tf b/samples/data_snapshot_list/main.tf new file mode 100644 index 0000000..c8323ee --- /dev/null +++ b/samples/data_snapshot_list/main.tf @@ -0,0 +1,40 @@ +/* +Пример использования +Получение списка snapshot + +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "1.1" + source = "digitalenergy.online/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +data "decort_snapshot_list" "sl" { + #обязательный параметр + #id вычислительной мощности + #тип - число + compute_id = 24074 +} + +output "test" { + value = data.decort_snapshot_list.sl +} diff --git a/samples/resource_snapshot/main.tf b/samples/resource_snapshot/main.tf new file mode 100644 index 0000000..3fce8a2 --- /dev/null +++ b/samples/resource_snapshot/main.tf @@ -0,0 +1,56 @@ +/* +Пример использования +Ресурса snapshot +Ресурс позволяет: +1. Создавать snapshot +2. Удалять snapshot +3. Откатывать snapshot + +*/ + +#Расскомментируйте этот код, +#и внесите необходимые правки в версию и путь, +#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером +/* +terraform { + required_providers { + decort = { + version = "1.1" + source = "digitalenergy.online/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + allow_unverified_ssl = true +} + + +resource "decort_snapshot" "s" { + #обязательный параметр + #id вычислительной мощности + #тип - число + compute_id = 24074 + + #обязательный параметр + #наименование snapshot + #тип - строка + label = "test_ssht_3" + + #опциональный параметр + #флаг отката + #тип - булев тип + #по-уолчанию - false + #если флаг был измеен с false на true, то произойдет откат + #rollback = false +} + +output "test" { + value = decort_snapshot.s +}