Features/snapshot

This commit is contained in:
Stanislav Solovev
2022-03-30 17:13:16 +03:00
committed by Petr Krutov
parent 94f222fe19
commit 13e6849328
10 changed files with 553 additions and 1 deletions

View File

@@ -0,0 +1,120 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
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(),
}
}

View File

@@ -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

View File

@@ -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(),
},

203
decort/resource_snapshot.go Normal file
View File

@@ -0,0 +1,203 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
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(),
}
}

View File

@@ -0,0 +1,55 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
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")
}

View File

@@ -0,0 +1,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
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
}