git test
This commit is contained in:
71
internal/service/cloudapi/image/data_source_image.go
Normal file
71
internal/service/cloudapi/image/data_source_image.go
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(int(image.ID)))
|
||||
|
||||
flattenImage(d, image)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func DataSourceImage() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceImageRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceImageExtendSchemaMake(),
|
||||
}
|
||||
}
|
||||
175
internal/service/cloudapi/image/data_source_image_list.go
Normal file
175
internal/service/cloudapi/image/data_source_image_list.go
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
)
|
||||
|
||||
func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
imageList, err := utilityImageListCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("items", flattenImageList(imageList))
|
||||
d.Set("entry_count", imageList.EntryCount)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceImageListSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Filter by Storage Endpoint ID",
|
||||
},
|
||||
"by_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Filter by ID",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Filter by name",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Filter by status",
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Filter by architecture",
|
||||
},
|
||||
"type_image": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Description: "Filter by image type",
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
"image_size": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Filter by image size",
|
||||
},
|
||||
"sep_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Filter by SEP name",
|
||||
},
|
||||
"pool": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Filter by pool",
|
||||
},
|
||||
"public": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Description: "Find public/private images",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Description: "Find hot resizable images",
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Description: "Find bootable images",
|
||||
},
|
||||
"sort_by": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "sort by one of supported fields, format +|-(field)",
|
||||
},
|
||||
"page": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "page number",
|
||||
},
|
||||
"storage_policy_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "page size",
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Description: "find by enabled True or False",
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "image list",
|
||||
Elem: &schema.Resource{
|
||||
Schema: dataSourceImageSchemaMake(),
|
||||
},
|
||||
},
|
||||
"entry_count": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func DataSourceImageList() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceImageListRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceImageListSchemaMake(),
|
||||
}
|
||||
}
|
||||
115
internal/service/cloudapi/image/flattens.go
Normal file
115
internal/service/cloudapi/image/flattens.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
|
||||
)
|
||||
|
||||
func flattenHistory(history []image.History) []map[string]interface{} {
|
||||
temp := make([]map[string]interface{}, 0)
|
||||
for _, item := range history {
|
||||
t := map[string]interface{}{
|
||||
"id": item.ID,
|
||||
"guid": item.GUID,
|
||||
"timestamp": item.Timestamp,
|
||||
}
|
||||
|
||||
temp = append(temp, t)
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
func flattenImage(d *schema.ResourceData, img *image.RecordImage) {
|
||||
cdPresentedTo, _ := json.Marshal(img.CdPresentedTo)
|
||||
|
||||
d.Set("unc_path", img.UNCPath)
|
||||
d.Set("account_id", img.AccountID)
|
||||
d.Set("acl", FlattenACL(img.ACL))
|
||||
d.Set("architecture", img.Architecture)
|
||||
d.Set("boot_type", img.BootType)
|
||||
d.Set("bootable", img.Bootable)
|
||||
d.Set("compute_ci_id", img.ComputeCIID)
|
||||
d.Set("cd_presented_to", string(cdPresentedTo))
|
||||
d.Set("deleted_time", img.DeletedTime)
|
||||
d.Set("desc", img.Description)
|
||||
d.Set("drivers", img.Drivers)
|
||||
d.Set("enabled", img.Enabled)
|
||||
d.Set("gid", img.GID)
|
||||
d.Set("guid", img.GUID)
|
||||
d.Set("history", flattenHistory(img.History))
|
||||
d.Set("hot_resize", img.HotResize)
|
||||
d.Set("image_id", img.ID)
|
||||
d.Set("independent", img.Independent)
|
||||
d.Set("last_modified", img.LastModified)
|
||||
d.Set("link_to", img.LinkTo)
|
||||
d.Set("links_to", img.LinksTo)
|
||||
d.Set("milestones", img.Milestones)
|
||||
d.Set("image_name", img.Name)
|
||||
d.Set("network_interface_naming", img.NetworkInterfaceNaming)
|
||||
d.Set("password", img.Password)
|
||||
d.Set("pool_name", img.Pool)
|
||||
d.Set("provider_name", img.ProviderName)
|
||||
d.Set("purge_attempts", img.PurgeAttempts)
|
||||
d.Set("present_to", img.PresentTo)
|
||||
d.Set("res_id", img.ResID)
|
||||
d.Set("rescuecd", img.RescueCD)
|
||||
d.Set("sep_id", img.SepID)
|
||||
d.Set("shared_with", img.SharedWith)
|
||||
d.Set("size", img.Size)
|
||||
d.Set("snapshot_id", img.SnapshotID)
|
||||
d.Set("status", img.Status)
|
||||
d.Set("storage_policy_id", img.StoragePolicyID)
|
||||
d.Set("tech_status", img.TechStatus)
|
||||
d.Set("to_clean", img.ToClean)
|
||||
d.Set("image_type", img.Type)
|
||||
d.Set("username", img.Username)
|
||||
d.Set("version", img.Version)
|
||||
}
|
||||
|
||||
func flattenImageList(il *image.ListImages) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, img := range il.Data {
|
||||
temp := map[string]interface{}{
|
||||
"account_id": img.AccountID,
|
||||
"architecture": img.Architecture,
|
||||
"boot_type": img.BootType,
|
||||
"bootable": img.Bootable,
|
||||
"cdrom": img.CDROM,
|
||||
"desc": img.Description,
|
||||
"drivers": img.Drivers,
|
||||
"hot_resize": img.HotResize,
|
||||
"image_id": img.ID,
|
||||
"link_to": img.LinkTo,
|
||||
"image_name": img.Name,
|
||||
"network_interface_naming": img.NetworkInterfaceNaming,
|
||||
"pool_name": img.Pool,
|
||||
"sep_id": img.SepID,
|
||||
"size": img.Size,
|
||||
"status": img.Status,
|
||||
"storage_policy_id": img.StoragePolicyID,
|
||||
"image_type": img.Type,
|
||||
"username": img.Username,
|
||||
"virtual": img.Virtual,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func FlattenACL(acl interface{}) string {
|
||||
switch d := acl.(type) {
|
||||
case string:
|
||||
return d
|
||||
case int:
|
||||
return strconv.Itoa(d)
|
||||
case int64:
|
||||
return strconv.FormatInt(d, 10)
|
||||
case float64:
|
||||
return strconv.FormatInt(int64(d), 10)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
241
internal/service/cloudapi/image/image_ds_subresource.go
Normal file
241
internal/service/cloudapi/image/image_ds_subresource.go
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
|
||||
func dataSourceImageExtendSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"show_all": {
|
||||
Type: schema.TypeBool,
|
||||
Default: false,
|
||||
Optional: true,
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_ci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"cd_presented_to": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"deleted_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"independent": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"links_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"image_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"network_interface_naming": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"present_to": {
|
||||
Type: schema.TypeMap,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"storage_policy_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"to_clean": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
148
internal/service/cloudapi/image/image_item_subresource.go
Normal file
148
internal/service/cloudapi/image/image_item_subresource.go
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
|
||||
func dataSourceImageSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Owner account id",
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image architecture",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Boot image type",
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Flag, true if image is bootable, otherwise - false",
|
||||
},
|
||||
"cdrom": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Flag, true if image is cdrom image, otherwise - false",
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image description",
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "Image drivers",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Flag, true if image supports hot resize, else if not",
|
||||
},
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Image id",
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "For virtual images, id image, which current image linked",
|
||||
},
|
||||
"links_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"image_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image name",
|
||||
},
|
||||
"network_interface_naming": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image pool",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Image storage endpoint id",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Image size",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image status",
|
||||
},
|
||||
"storage_policy_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image type",
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "username",
|
||||
},
|
||||
"virtual": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "True if image is virtula, otherwise - else",
|
||||
},
|
||||
}
|
||||
}
|
||||
150
internal/service/cloudapi/image/image_rs_subresource.go
Normal file
150
internal/service/cloudapi/image/image_rs_subresource.go
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
)
|
||||
|
||||
func resourceImageSchemaMake(sch map[string]*schema.Schema) map[string]*schema.Schema {
|
||||
delete(sch, "show_all")
|
||||
sch["name"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
}
|
||||
|
||||
sch["url"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "URL where to download media from",
|
||||
}
|
||||
|
||||
sch["image_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "image id",
|
||||
}
|
||||
|
||||
sch["boot_type"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true),
|
||||
Description: "Boot type of image bios or uefi",
|
||||
}
|
||||
|
||||
sch["type"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, true),
|
||||
Description: "Image type linux, windows or unknown",
|
||||
}
|
||||
|
||||
sch["storage_policy_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "ID of the storage policy",
|
||||
}
|
||||
|
||||
sch["hot_resize"] = &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
}
|
||||
|
||||
sch["username"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
}
|
||||
|
||||
sch["password"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
}
|
||||
|
||||
sch["account_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
}
|
||||
|
||||
sch["username_dl"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "username for upload binary media",
|
||||
}
|
||||
|
||||
sch["password_dl"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "password for upload binary media",
|
||||
}
|
||||
|
||||
sch["pool_name"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
}
|
||||
|
||||
sch["sep_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
}
|
||||
|
||||
sch["network_interface_naming"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true),
|
||||
Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming",
|
||||
}
|
||||
|
||||
sch["sync_mode"] = &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Description: "Create image from a media identified by URL (in synchronous mode)",
|
||||
}
|
||||
|
||||
return sch
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func resourceImageVirtualSchemaMake(sch map[string]*schema.Schema) map[string]*schema.Schema {
|
||||
delete(sch, "show_all")
|
||||
|
||||
sch["name"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
}
|
||||
|
||||
sch["link_to"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "ID of real image to link this virtual image to upon creation",
|
||||
}
|
||||
|
||||
sch["account_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Account ID",
|
||||
}
|
||||
|
||||
sch["image_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Image id",
|
||||
}
|
||||
|
||||
return sch
|
||||
}
|
||||
782
internal/service/cloudapi/image/old_schemas.go
Normal file
782
internal/service/cloudapi/image/old_schemas.go
Normal file
@@ -0,0 +1,782 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs"
|
||||
)
|
||||
|
||||
func resourceImageFromBlankComputeSchemaV1() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Compute Id",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true),
|
||||
Description: "Boot type of image BIOS or UEFI",
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "other"}, true),
|
||||
Description: "Image type linux, windows or other",
|
||||
},
|
||||
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"async_mode": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Description: "create an image in async/sync mode",
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"ckey": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_ci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"cd_presented_to": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"deleted_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"image_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"network_interface_naming": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"present_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceImageFromBlankDiskSchemaV1() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"disk_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Disk Id",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true),
|
||||
Description: "Boot type of image BIOS or UEFI",
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "other"}, true),
|
||||
Description: "Image type linux, windows or other",
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"X86_64"}, true),
|
||||
Description: "binary architecture of this image, one of X86_64",
|
||||
},
|
||||
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{
|
||||
StateFunc: statefuncs.StateFuncToUpper,
|
||||
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86"}, false), // observe case while validating
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
Description: "bootable image",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"async_mode": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Description: "create an image in async/sync mode",
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"ckey": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_ci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"cd_presented_to": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"deleted_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"image_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"network_interface_naming": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"present_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceImageExtendSchemaV1() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"show_all": {
|
||||
Type: schema.TypeBool,
|
||||
Default: false,
|
||||
Optional: true,
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"ckey": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_ci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"cd_presented_to": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"deleted_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"image_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"network_interface_naming": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"present_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
func resourceMainImageSchemaV1(sch map[string]*schema.Schema) map[string]*schema.Schema {
|
||||
delete(sch, "show_all")
|
||||
sch["name"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
}
|
||||
|
||||
sch["url"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "URL where to download media from",
|
||||
}
|
||||
|
||||
sch["image_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "image id",
|
||||
}
|
||||
|
||||
sch["boot_type"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true),
|
||||
Description: "Boot type of image bios or uefi",
|
||||
}
|
||||
|
||||
sch["type"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "other"}, true),
|
||||
Description: "Image type linux, windows or other",
|
||||
}
|
||||
|
||||
sch["hot_resize"] = &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
}
|
||||
|
||||
sch["username"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
}
|
||||
|
||||
sch["password"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
}
|
||||
|
||||
sch["account_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
}
|
||||
|
||||
sch["username_dl"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "username for upload binary media",
|
||||
}
|
||||
|
||||
sch["password_dl"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "password for upload binary media",
|
||||
}
|
||||
|
||||
sch["pool_name"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
}
|
||||
|
||||
sch["sep_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
}
|
||||
|
||||
sch["architecture"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"X86_64"}, true),
|
||||
Description: "binary architecture of this image, one of X86_64",
|
||||
}
|
||||
|
||||
sch["drivers"] = &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
}
|
||||
|
||||
sch["network_interface_naming"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"eth", "ens"}, true),
|
||||
Description: "select a network interface naming pattern for your Linux machine. eth - onboard, ens - pci slot naming",
|
||||
}
|
||||
|
||||
return sch
|
||||
}
|
||||
|
||||
func resourceImageSchemaV1() *schema.Resource {
|
||||
return &schema.Resource{Schema: resourceMainImageSchemaV1(dataSourceImageExtendSchemaV1())}
|
||||
}
|
||||
|
||||
func resourceMainImageVirtualSchemaV1(sch map[string]*schema.Schema) map[string]*schema.Schema {
|
||||
delete(sch, "show_all")
|
||||
sch["name"] = &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
}
|
||||
|
||||
sch["link_to"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "ID of real image to link this virtual image to upon creation",
|
||||
}
|
||||
|
||||
sch["image_id"] = &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Image id",
|
||||
}
|
||||
|
||||
return sch
|
||||
}
|
||||
|
||||
func resourceImageVirtualSchemaV1() *schema.Resource {
|
||||
return &schema.Resource{Schema: resourceMainImageVirtualSchemaV1(dataSourceImageExtendSchemaV1())}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/account"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func existAccountID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
accountId := uint64(d.Get("account_id").(int))
|
||||
req := account.ListRequest{}
|
||||
|
||||
accounts, err := c.CloudAPI().Account().List(ctx, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return len(accounts.FilterByID(accountId).Data) != 0, nil
|
||||
}
|
||||
|
||||
func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
gid := uint64(d.Get("gid").(int))
|
||||
req := locations.ListRequest{}
|
||||
|
||||
locationList, err := c.CloudAPI().Locations().List(ctx, req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return len(locationList.FilterByGID(gid).Data) != 0, nil
|
||||
}
|
||||
|
||||
func existComputeID(ctx context.Context, computeId uint64, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := compute.GetRequest{ComputeID: computeId}
|
||||
|
||||
// check for compute existence
|
||||
computeRecord, err := c.CloudAPI().Compute().Get(ctx, req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ComputeID %d is not allowed or does not exist", computeId)
|
||||
}
|
||||
|
||||
// check if compute was created as blank
|
||||
computeImageId := computeRecord.ImageID
|
||||
bootImageId := -1
|
||||
for _, d := range computeRecord.Disks {
|
||||
if computeRecord.Chipset == "i440fx" {
|
||||
if d.PCISlot == 6 {
|
||||
bootImageId = int(d.ImageID)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if d.BusNumber == 6 {
|
||||
bootImageId = int(d.ImageID)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if computeImageId != 0 && bootImageId != 0 {
|
||||
return fmt.Errorf("ComputeID %d is not allowed because it is not blank compute (either compute imageId or boot imageId are not zero)", computeId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func existDiskID(ctx context.Context, diskId uint64, m interface{}) error {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := disks.ListRequest{ByID: diskId}
|
||||
|
||||
diskList, err := c.CloudAPI().Disks().List(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(diskList.Data) != 1 {
|
||||
return fmt.Errorf("diskId %d is not allowed or doesn't exist", diskId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
303
internal/service/cloudapi/image/resource_image.go
Normal file
303
internal/service/cloudapi/image/resource_image.go
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
)
|
||||
|
||||
func resourceImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
haveAccountID, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveAccountID {
|
||||
return diag.Errorf("resourceImageCreate: can't create Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.CreateRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
Name: d.Get("name").(string),
|
||||
URL: d.Get("url").(string),
|
||||
BootType: d.Get("boot_type").(string),
|
||||
ImageType: d.Get("type").(string),
|
||||
StoragePolicyID: uint64(d.Get("storage_policy_id").(int)),
|
||||
}
|
||||
|
||||
if hotresize, ok := d.GetOk("hot_resize"); ok {
|
||||
req.HotResize = hotresize.(bool)
|
||||
}
|
||||
if username, ok := d.GetOk("username"); ok {
|
||||
req.Username = username.(string)
|
||||
}
|
||||
if password, ok := d.GetOk("password"); ok {
|
||||
req.Password = password.(string)
|
||||
}
|
||||
if usernameDL, ok := d.GetOk("username_dl"); ok {
|
||||
req.UsernameDL = usernameDL.(string)
|
||||
}
|
||||
if passwordDL, ok := d.GetOk("password_dl"); ok {
|
||||
req.PasswordDL = passwordDL.(string)
|
||||
}
|
||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||
req.SEPID = uint64(sepId.(int))
|
||||
}
|
||||
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||
req.Pool = poolName.(string)
|
||||
}
|
||||
if networkInterfaceNaming, ok := d.GetOk("network_interface_naming"); ok {
|
||||
req.NetworkInterfaceNaming = networkInterfaceNaming.(string)
|
||||
}
|
||||
|
||||
syncMode := d.Get("sync_mode").(bool)
|
||||
var imageId uint64
|
||||
|
||||
if syncMode {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
imageId, err = c.CloudAPI().Image().Create(ctx, req)
|
||||
log.Debugf("resourceImageCreate: imageID = %d", imageId)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
taskID, err := c.CloudAPI().Image().AsyncCreate(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
taskReq := tasks.GetRequest{
|
||||
AuditID: strings.Trim(taskID, `"`),
|
||||
}
|
||||
|
||||
for {
|
||||
time.Sleep(time.Second * 15)
|
||||
task, err := c.CloudAPI().Tasks().Get(ctx, taskReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
log.Debugf("resourceAccountDelete: delete account - %s", task.Stage)
|
||||
|
||||
if task.Completed {
|
||||
if task.Error != "" {
|
||||
return diag.FromErr(fmt.Errorf("cannot delete account: %v", task.Error))
|
||||
}
|
||||
id, err := task.Result.ID()
|
||||
imageId = uint64(id)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(imageId, 10))
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
_, err = utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return resourceImageRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageRead: called for %s id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
img, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if img == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
switch img.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Destroyed, status.Purged:
|
||||
d.SetId("")
|
||||
return diag.Errorf("The resource cannot be updated because it has been destroyed")
|
||||
// return resourceImageCreate(ctx, d, m)
|
||||
}
|
||||
|
||||
flattenImage(d, img)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
_, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.DeleteRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().Image().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageRename(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageEditName: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.RenameRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().Image().Rename(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageUpdate: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
haveGID, err := existGID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveGID {
|
||||
return diag.Errorf("resourceImageUpdate: can't update Image because GID %d is not allowed or does not exist", d.Get("gid").(int))
|
||||
}
|
||||
|
||||
haveAccountID, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveAccountID {
|
||||
return diag.Errorf("resourceImageUpdate: can't update Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if image == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
switch image.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The image is in status: %s, please, contact support for more information", image.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Destroyed, status.Purged:
|
||||
d.SetId("")
|
||||
return diag.Errorf("The resource cannot be updated because it has been destroyed")
|
||||
// return resourceImageCreate(ctx, d, m)
|
||||
}
|
||||
|
||||
if d.HasChange("name") {
|
||||
err := resourceImageRename(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
return resourceImageRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func ResourceImage() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 2,
|
||||
|
||||
CreateContext: resourceImageCreate,
|
||||
ReadContext: resourceImageRead,
|
||||
UpdateContext: resourceImageUpdate,
|
||||
DeleteContext: resourceImageDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout600s,
|
||||
Read: &constants.Timeout300s,
|
||||
Update: &constants.Timeout300s,
|
||||
Delete: &constants.Timeout300s,
|
||||
Default: &constants.Timeout300s,
|
||||
},
|
||||
|
||||
Schema: resourceImageSchemaMake(dataSourceImageExtendSchemaMake()),
|
||||
StateUpgraders: []schema.StateUpgrader{
|
||||
{
|
||||
Type: resourceImageSchemaV1().CoreConfigSchema().ImpliedType(),
|
||||
Upgrade: resourcePresentToUpgradeV1,
|
||||
Version: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,522 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/compute"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
)
|
||||
|
||||
func resourceImageFromBlankComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
computeId := uint64(d.Get("compute_id").(int))
|
||||
name := d.Get("name").(string)
|
||||
|
||||
log.Debugf("resourceImageFromBlankComputeCreate: called for image %s", name)
|
||||
|
||||
err := existComputeID(ctx, computeId, m)
|
||||
if err != nil {
|
||||
return diag.Errorf("resourceImageFromBlankComputeCreate: can't create Image: %v", err)
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("account_id"); ok {
|
||||
haveAccountID, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveAccountID {
|
||||
return diag.Errorf("resourceImageFromBlankComputeCreate: can't create Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := compute.CreateTemplateFromBlankRequest{
|
||||
ComputeID: computeId,
|
||||
Name: name,
|
||||
BootType: d.Get("boot_type").(string),
|
||||
ImageType: d.Get("type").(string),
|
||||
StoragePolicyID: uint64(d.Get("storage_policy_id").(int)),
|
||||
}
|
||||
|
||||
if username, ok := d.GetOk("username"); ok {
|
||||
req.Username = username.(string)
|
||||
}
|
||||
if password, ok := d.GetOk("password"); ok {
|
||||
req.Password = password.(string)
|
||||
}
|
||||
if accountId, ok := d.GetOk("account_id"); ok {
|
||||
req.AccountID = uint64(accountId.(int))
|
||||
}
|
||||
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||
req.PoolName = poolName.(string)
|
||||
}
|
||||
if hotresize, ok := d.GetOk("hot_resize"); ok {
|
||||
req.HotResize = hotresize.(bool)
|
||||
}
|
||||
|
||||
var imageId uint64
|
||||
asyncMode := d.Get("async_mode").(bool)
|
||||
if !asyncMode {
|
||||
imageId, err = c.CloudAPI().Compute().CreateTemplateFromBlank(ctx, req)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
taskId, err := c.CloudAPI().Compute().CreateTemplateFromBlankAsync(ctx, req)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
taskReq := tasks.GetRequest{
|
||||
AuditID: strings.Trim(taskId, `"`),
|
||||
}
|
||||
|
||||
for {
|
||||
task, err := c.CloudAPI().Tasks().Get(ctx, taskReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
log.Debugf("resourceImageFromBlankComputeCreate: instance creating - %s", task.Stage)
|
||||
|
||||
if task.Completed {
|
||||
if task.Error != "" {
|
||||
return diag.FromErr(fmt.Errorf("cannot create image instance: %v", task.Error))
|
||||
}
|
||||
|
||||
id, err := task.Result.ID()
|
||||
imageId = uint64(id)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 20)
|
||||
}
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(imageId, 10))
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
_, err = utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return resourceImageFromBlankComputeRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceImageFromBlankComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageFromBlankComputeRead: called for %s id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
img, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if img == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
switch img.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Destroyed, status.Purged:
|
||||
d.SetId("")
|
||||
return diag.Errorf("The resource cannot be updated because it has been destroyed")
|
||||
// return resourceImageCreate(ctx, d, m)
|
||||
}
|
||||
|
||||
flattenImage(d, img)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageFromBlankComputeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageFromBlankComputeDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
_, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.DeleteRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().Image().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageFromBlankComputeRename(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageFromBlankComputeRename: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.RenameRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
Name: d.Get("name").(string),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().Image().Rename(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageFromBlankComputeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageFromBlankComputeUpdate: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
// we do not allow change of compute_id, but allow resource update after import
|
||||
old, _ := d.GetChange("compute_id")
|
||||
if old.(int) != 0 && d.HasChange("compute_id") {
|
||||
return diag.Errorf("resourceImageFromBlankComputeUpdate: can't update Image because compute_id is not allowed to be changed")
|
||||
}
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
switch image.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The image is in status: %s, please, contact support for more information", image.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Destroyed, status.Purged:
|
||||
d.SetId("")
|
||||
return diag.Errorf("The resource cannot be updated because it has been destroyed")
|
||||
// return resourceImageCreate(ctx, d, m)
|
||||
}
|
||||
|
||||
if d.HasChange("name") {
|
||||
err := resourceImageFromBlankComputeRename(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
return resourceImageFromBlankComputeRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func ResourceImageFromBlankCompute() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 2,
|
||||
|
||||
CreateContext: resourceImageFromBlankComputeCreate,
|
||||
ReadContext: resourceImageFromBlankComputeRead,
|
||||
UpdateContext: resourceImageFromBlankComputeUpdate,
|
||||
DeleteContext: resourceImageFromBlankComputeDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout30m,
|
||||
Read: &constants.Timeout900s,
|
||||
Update: &constants.Timeout900s,
|
||||
Delete: &constants.Timeout900s,
|
||||
Default: &constants.Timeout900s,
|
||||
},
|
||||
|
||||
Schema: resourceImageFromBlankComputeSchemaMake(),
|
||||
StateUpgraders: []schema.StateUpgrader{
|
||||
{
|
||||
Type: resourceImageFromBlankComputeSchemaV1().CoreConfigSchema().ImpliedType(),
|
||||
Upgrade: resourcePresentToUpgradeV1,
|
||||
Version: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceImageFromBlankComputeSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Compute Id",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
},
|
||||
"storage_policy_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Storage policy ID",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true),
|
||||
Description: "Boot type of image BIOS or UEFI",
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, true),
|
||||
Description: "Image type linux, windows or unknown",
|
||||
},
|
||||
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"async_mode": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Description: "create an image in async/sync mode",
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"ckey": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_ci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"cd_presented_to": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"deleted_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"links_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"image_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"network_interface_naming": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"present_to": {
|
||||
Type: schema.TypeMap,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"to_clean": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/disks"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/tasks"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
|
||||
)
|
||||
|
||||
func resourceImageFromPlatformDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
diskId := uint64(d.Get("disk_id").(int))
|
||||
name := d.Get("name").(string)
|
||||
|
||||
log.Debugf("resourceImageFromPlatformDiskCreate: called for image %s", name)
|
||||
|
||||
err := existDiskID(ctx, diskId, m)
|
||||
if err != nil {
|
||||
return diag.Errorf("resourceImageFromPlatformDiskCreate: can't create Image: %v", err)
|
||||
}
|
||||
|
||||
if _, ok := d.GetOk("account_id"); ok {
|
||||
haveAccountID, err := existAccountID(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
if !haveAccountID {
|
||||
return diag.Errorf("resourceImageFromPlatformDiskCreate: can't create Image because AccountID %d is not allowed or does not exist", d.Get("account_id").(int))
|
||||
}
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := disks.FromPlatformDiskRequest{
|
||||
DiskID: diskId,
|
||||
Name: name,
|
||||
BootType: d.Get("boot_type").(string),
|
||||
ImageType: d.Get("type").(string),
|
||||
Bootable: d.Get("bootable").(bool), // default value - true
|
||||
}
|
||||
|
||||
if username, ok := d.GetOk("username"); ok {
|
||||
req.Username = username.(string)
|
||||
}
|
||||
if password, ok := d.GetOk("password"); ok {
|
||||
req.Password = password.(string)
|
||||
}
|
||||
if accountId, ok := d.GetOk("account_id"); ok {
|
||||
req.AccountID = uint64(accountId.(int))
|
||||
}
|
||||
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||
req.PoolName = poolName.(string)
|
||||
}
|
||||
if hotresize, ok := d.GetOk("hot_resize"); ok {
|
||||
req.HotResize = hotresize.(bool)
|
||||
}
|
||||
|
||||
var imageId uint64
|
||||
asyncMode := d.Get("async_mode").(bool)
|
||||
if !asyncMode {
|
||||
imageId, err = c.CloudAPI().Disks().FromPlatformDisk(ctx, req)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
taskId, err := c.CloudAPI().Disks().FromPlatformDiskAsync(ctx, req)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
taskReq := tasks.GetRequest{
|
||||
AuditID: strings.Trim(taskId, `"`),
|
||||
}
|
||||
|
||||
for {
|
||||
task, err := c.CloudAPI().Tasks().Get(ctx, taskReq)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
log.Debugf("resourceImageFromPlatformDiskCreate: instance creating - %s", task.Stage)
|
||||
|
||||
if task.Completed {
|
||||
if task.Error != "" {
|
||||
return diag.FromErr(fmt.Errorf("cannot create image instance: %v", task.Error))
|
||||
}
|
||||
|
||||
id, err := task.Result.ID()
|
||||
imageId = uint64(id)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 20)
|
||||
}
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(imageId, 10))
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
_, err = utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return resourceImageFromPlatformDiskRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceImageFromPlatformDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageFromPlatformDiskRead: called for %s id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
img, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if img == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
switch img.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The image is in status: %s, please, contact support for more information", img.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Destroyed, status.Purged:
|
||||
d.SetId("")
|
||||
return diag.Errorf("The resource cannot be updated because it has been destroyed")
|
||||
}
|
||||
|
||||
flattenImage(d, img)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageFromPlatformDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageFromPlatformDiskDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
_, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.DeleteRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
}
|
||||
|
||||
_, err = c.CloudAPI().Image().Delete(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageFromPlatformDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageFromPlatformDiskUpdate: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
// we do not allow change of disk_id, but allow resource update after import
|
||||
old, _ := d.GetChange("disk_id")
|
||||
if old.(int) != 0 && d.HasChange("disk_id") {
|
||||
return diag.Errorf("resourceImageFromPlatformDiskUpdate: can't update Image because disk_id is not allowed to be changed")
|
||||
}
|
||||
|
||||
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
switch image.Status {
|
||||
case status.Modeled:
|
||||
return diag.Errorf("The image is in status: %s, please, contact support for more information", image.Status)
|
||||
case status.Creating:
|
||||
case status.Created:
|
||||
case status.Destroyed, status.Purged:
|
||||
d.SetId("")
|
||||
return diag.Errorf("The resource cannot be updated because it has been destroyed")
|
||||
}
|
||||
|
||||
if d.HasChange("name") {
|
||||
err := resourceImageRename(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
return resourceImageFromPlatformDiskRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func ResourceImageFromPlatformDisk() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 2,
|
||||
|
||||
CreateContext: resourceImageFromPlatformDiskCreate,
|
||||
ReadContext: resourceImageFromPlatformDiskRead,
|
||||
UpdateContext: resourceImageFromPlatformDiskUpdate,
|
||||
DeleteContext: resourceImageFromPlatformDiskDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout30m,
|
||||
Read: &constants.Timeout900s,
|
||||
Update: &constants.Timeout900s,
|
||||
Delete: &constants.Timeout900s,
|
||||
Default: &constants.Timeout900s,
|
||||
},
|
||||
|
||||
Schema: resourceImageFromPlatformDiskSchemaMake(),
|
||||
StateUpgraders: []schema.StateUpgrader{
|
||||
{
|
||||
Type: resourceImageFromBlankDiskSchemaV1().CoreConfigSchema().ImpliedType(),
|
||||
Upgrade: resourcePresentToUpgradeV1,
|
||||
Version: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceImageFromPlatformDiskSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"disk_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Disk Id",
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"bios", "uefi"}, true),
|
||||
Description: "Boot type of image BIOS or UEFI",
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"linux", "windows", "unknown"}, true),
|
||||
Description: "Image type linux, windows or unknown",
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
Description: "bootable image",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"async_mode": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Description: "create an image in async/sync mode",
|
||||
},
|
||||
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"ckey": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"acl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"compute_ci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"cd_presented_to": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"deleted_time": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"links_to": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"image_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"network_interface_naming": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"present_to": {
|
||||
Type: schema.TypeMap,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"snapshot_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"to_clean": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
139
internal/service/cloudapi/image/resource_image_virtual.go
Normal file
139
internal/service/cloudapi/image/resource_image_virtual.go
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func resourceImageVirtualCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageVirtualCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.CreateVirtualRequest{
|
||||
Name: d.Get("name").(string),
|
||||
TargetID: uint64(d.Get("link_to").(int)),
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
}
|
||||
|
||||
imageId, err := c.CloudAPI().Image().CreateVirtual(ctx, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(imageId, 10))
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
_, err = utilityImageCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return resourceImageRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceImageVirtualUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceImageUpdate: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
if d.HasChange("name") {
|
||||
err := resourceImageRename(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("link_to") {
|
||||
err := resourceImageVirtualLink(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
return resourceImageRead(ctx, d, m)
|
||||
}
|
||||
|
||||
func resourceImageVirtualLink(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceVirtualImageLink: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.LinkRequest{
|
||||
ImageID: uint64(d.Get("image_id").(int)),
|
||||
TargetID: uint64(d.Get("link_to").(int)),
|
||||
}
|
||||
|
||||
_, err := c.CloudAPI().Image().Link(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ResourceImageVirtual() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 2,
|
||||
|
||||
CreateContext: resourceImageVirtualCreate,
|
||||
ReadContext: resourceImageRead,
|
||||
UpdateContext: resourceImageVirtualUpdate,
|
||||
DeleteContext: resourceImageDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout600s,
|
||||
Read: &constants.Timeout300s,
|
||||
Update: &constants.Timeout300s,
|
||||
Delete: &constants.Timeout300s,
|
||||
Default: &constants.Timeout300s,
|
||||
},
|
||||
|
||||
Schema: resourceImageVirtualSchemaMake(dataSourceImageExtendSchemaMake()),
|
||||
StateUpgraders: []schema.StateUpgrader{
|
||||
{
|
||||
Type: resourceImageVirtualSchemaV1().CoreConfigSchema().ImpliedType(),
|
||||
Upgrade: resourcePresentToUpgradeV1,
|
||||
Version: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
14
internal/service/cloudapi/image/state_upgraders.go
Normal file
14
internal/service/cloudapi/image/state_upgraders.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourcePresentToUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) {
|
||||
log.Debug("resourcePresentToUpgradeV1: upgrading state")
|
||||
rawState["present_to"] = make(map[string]uint64)
|
||||
|
||||
return rawState, nil
|
||||
}
|
||||
65
internal/service/cloudapi/image/utility_image.go
Normal file
65
internal/service/cloudapi/image/utility_image.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.RecordImage, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.GetRequest{}
|
||||
|
||||
if (strconv.Itoa(d.Get("image_id").(int))) != "0" {
|
||||
req.ImageID = uint64(d.Get("image_id").(int))
|
||||
} else {
|
||||
id, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req.ImageID = id
|
||||
}
|
||||
|
||||
if showAll, ok := d.GetOk("show_all"); ok {
|
||||
req.ShowAll = showAll.(bool)
|
||||
}
|
||||
|
||||
image, err := c.CloudAPI().Image().Get(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return image, nil
|
||||
}
|
||||
119
internal/service/cloudapi/image/utility_image_list.go
Normal file
119
internal/service/cloudapi/image/utility_image_list.go
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/image"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*image.ListImages, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := image.ListRequest{}
|
||||
|
||||
if sepID, ok := d.GetOk("sep_id"); ok {
|
||||
req.SEPID = uint64(sepID.(int))
|
||||
}
|
||||
|
||||
if byID, ok := d.GetOk("by_id"); ok {
|
||||
req.ByID = uint64(byID.(int))
|
||||
}
|
||||
|
||||
if name, ok := d.GetOk("name"); ok {
|
||||
req.Name = name.(string)
|
||||
}
|
||||
|
||||
if status, ok := d.GetOk("status"); ok {
|
||||
req.Status = status.(string)
|
||||
}
|
||||
|
||||
if typeImage, ok := d.GetOk("type_image"); ok {
|
||||
for _, v := range typeImage.([]interface{}) {
|
||||
req.TypeImage = append(req.TypeImage, v.(string))
|
||||
}
|
||||
}
|
||||
|
||||
if imageSize, ok := d.GetOk("image_size"); ok {
|
||||
req.ImageSize = uint64(imageSize.(int))
|
||||
}
|
||||
|
||||
if sepName, ok := d.GetOk("sep_name"); ok {
|
||||
req.SEPName = sepName.(string)
|
||||
}
|
||||
|
||||
if pool, ok := d.GetOk("pool"); ok {
|
||||
req.Pool = pool.(string)
|
||||
}
|
||||
|
||||
if public, ok := d.GetOkExists("public"); ok {
|
||||
req.Public = public.(bool)
|
||||
}
|
||||
|
||||
if hotResize, ok := d.GetOkExists("hot_resize"); ok {
|
||||
req.HotResize = hotResize.(bool)
|
||||
}
|
||||
|
||||
if bootable, ok := d.GetOkExists("bootable"); ok {
|
||||
req.Bootable = bootable.(bool)
|
||||
}
|
||||
|
||||
if sortBy, ok := d.GetOk("sort_by"); ok {
|
||||
req.SortBy = sortBy.(string)
|
||||
}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
req.Page = uint64(page.(int))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
req.Size = uint64(size.(int))
|
||||
}
|
||||
if enabled, ok := d.GetOkExists("enabled"); ok {
|
||||
req.Enabled = enabled.(bool)
|
||||
}
|
||||
if storagePolicyID, ok := d.GetOk("storage_policy_id"); ok {
|
||||
req.StoragePolicyID = uint64(storagePolicyID.(int))
|
||||
}
|
||||
|
||||
log.Debugf("utilityImageListCheckPresence: load image list")
|
||||
imageList, err := c.CloudAPI().Image().List(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return imageList, nil
|
||||
}
|
||||
Reference in New Issue
Block a user