This commit is contained in:
2026-06-19 17:43:58 +03:00
parent c734dcfff7
commit c00c608ce9
1307 changed files with 1 additions and 197134 deletions

View File

@@ -1,67 +0,0 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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.FormatUint(image.ID, 10))
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: dataSourceImageSchemaMake(),
}
}

View File

@@ -1,69 +0,0 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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 DataSourceImageList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceImageListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceImageListSchemaMake(),
}
}

View File

@@ -1,253 +0,0 @@
package image
import (
"encoding/json"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
)
func flattenImage(d *schema.ResourceData, img *image.RecordImage) {
cdPresentedTo, _ := json.Marshal(img.CdPresentedTo)
log.Debugf("flattenImageID %d", img.ID)
d.Set("image_id", img.ID)
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("computeci_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("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("name", img.Name)
d.Set("network_interface_naming", img.NetworkInterfaceNaming)
d.Set("password", img.Password)
d.Set("pool_name", img.Pool)
d.Set("present_to", img.PresentTo)
d.Set("provider_name", img.ProviderName)
d.Set("purge_attempts", img.PurgeAttempts)
d.Set("reference_id", img.ReferenceID)
d.Set("res_id", img.ResID)
d.Set("res_name", img.ResName)
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("target_ids", img.LinksTo)
d.Set("image_type", img.Type)
d.Set("url", img.URL)
d.Set("username", img.Username)
d.Set("version", img.Version)
}
func flattenAcl(acl image.ListACL) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(acl))
for _, val := range acl {
temp := map[string]interface{}{
"explicit": val.Explicit,
"guid": val.GUID,
"right": val.Right,
"status": val.Status,
"type": val.Type,
"user_group_id": val.UserGroupID,
}
res = append(res, temp)
}
return res
}
func flattenHistory(history image.ListHistory) []map[string]interface{} {
temp := make([]map[string]interface{}, 0, len(history))
for _, item := range history {
t := map[string]interface{}{
"id": item.ID,
"guid": item.GUID,
"timestamp": item.Timestamp,
}
temp = append(temp, t)
}
return temp
}
func flattenImageList(il *image.ListImages) []map[string]interface{} {
log.Debug("flattenImageList")
res := make([]map[string]interface{}, 0, len(il.Data))
for _, item := range il.Data {
cdPresentedTo, _ := json.Marshal(item.CdPresentedTo)
temp := map[string]interface{}{
"image_id": item.ID,
"unc_path": item.UNCPath,
"account_id": item.AccountID,
"acl": flattenAcl(item.ACL),
"architecture": item.Architecture,
"boot_type": item.BootType,
"bootable": item.Bootable,
"computeci_id": item.ComputeCIID,
"cd_presented_to": string(cdPresentedTo),
"deleted_time": item.DeletedTime,
"desc": item.Description,
"drivers": item.Drivers,
"enabled": item.Enabled,
"gid": item.GID,
"guid": item.GUID,
"history": flattenHistory(item.History),
"hot_resize": item.HotResize,
"independent": item.Independent,
"last_modified": item.LastModified,
"link_to": item.LinkTo,
"links_to": item.LinksTo,
"milestones": item.Milestones,
"name": item.Name,
"network_interface_naming": item.NetworkInterfaceNaming,
"password": item.Password,
"pool_name": item.Pool,
"present_to": item.PresentTo,
"provider_name": item.ProviderName,
"purge_attempts": item.PurgeAttempts,
"reference_id": item.ReferenceID,
"res_id": item.ResID,
"res_name": item.ResName,
"rescuecd": item.RescueCD,
"sep_id": item.SEPID,
"shared_with": item.SharedWith,
"size": item.Size,
"snapshot_id": item.SnapshotID,
"status": item.Status,
"storage_policy_id": item.StoragePolicyID,
"tech_status": item.TechStatus,
"to_clean": item.ToClean,
"image_type": item.Type,
"url": item.URL,
"username": item.Username,
"version": item.Version,
"virtual": item.Virtual,
}
res = append(res, temp)
}
return res
}
func flattenEco(m interface{}) string {
log.Debug("flattenEco")
output := ""
switch d := m.(type) {
case string:
output = d
case int:
output = strconv.Itoa(d)
case int64:
output = strconv.FormatInt(d, 10)
case float64:
output = strconv.FormatInt(int64(d), 10)
default:
}
return output
}
func flattenPackages(pg image.Packages) []map[string]interface{} {
log.Debug("flattenPackages")
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"libvirt_bin": flattenLibvirtBin(pg),
"libvirt_daemon": flattenLibvirtDaemon(pg),
"lvm2_lockd": flattenLvm2Lockd(pg),
"openvswitch_common": flattenOpenvswitchCommon(pg),
"openvswitch_switch": flattenOpenvswitchSwitch(pg),
"qemu_system_x86": flattenQemuSystemX86(pg),
"sanlock": flattenSanlock(pg),
}
res = append(res, temp)
return res
}
func flattenLibvirtBin(lb image.Packages) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"installed_size": lb.LibvirtBin.InstalledSize,
"ver": lb.LibvirtBin.Ver,
}
res = append(res, temp)
return res
}
func flattenLibvirtDaemon(ld image.Packages) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"installed_size": ld.LibvirtDaemon.InstalledSize,
"ver": ld.LibvirtDaemon.Ver,
}
res = append(res, temp)
return res
}
func flattenLvm2Lockd(ll image.Packages) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"installed_size": ll.Lvm2Lockd.InstalledSize,
"ver": ll.Lvm2Lockd.Ver,
}
res = append(res, temp)
return res
}
func flattenOpenvswitchCommon(oc image.Packages) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"installed_size": oc.OpenvswitchCommon.InstalledSize,
"ver": oc.OpenvswitchCommon.Ver,
}
res = append(res, temp)
return res
}
func flattenOpenvswitchSwitch(os image.Packages) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"installed_size": os.OpenvswitchSwitch.InstalledSize,
"ver": os.OpenvswitchSwitch.Ver,
}
res = append(res, temp)
return res
}
func flattenQemuSystemX86(qs image.Packages) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"installed_size": qs.QemuSystemX86.InstalledSize,
"ver": qs.QemuSystemX86.Ver,
}
res = append(res, temp)
return res
}
func flattenSanlock(sl image.Packages) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"installed_size": sl.Sanlock.InstalledSize,
"ver": sl.Sanlock.Ver,
}
res = append(res, temp)
return res
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,238 +0,0 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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/cloudbroker/image"
"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 resourceCDROMImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceCDROMImageCreate: called for image %s", d.Get("name").(string))
c := m.(*controller.ControllerCfg)
req := image.CreateCDROMImageRequest{
Name: d.Get("name").(string),
URL: d.Get("url").(string),
StoragePolicyID: uint64(d.Get("storage_policy_id").(int)),
}
if username, ok := d.GetOk("username_dl"); ok {
req.UsernameDL = username.(string)
}
if password, ok := d.GetOk("password_dl"); ok {
req.PasswordDl = password.(string)
}
if accountId, ok := d.GetOk("account_id"); ok {
req.AccountID = uint64(accountId.(int))
}
if sepId, ok := d.GetOk("sep_id"); ok {
req.SEPID = uint64(sepId.(int))
}
if poolName, ok := d.GetOk("pool_name"); ok {
req.PoolName = poolName.(string)
}
imageId, err := c.CloudBroker().Image().CreateCDROMImage(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(imageId, 10))
return resourceImageRead(ctx, d, m)
}
func resourceCDROMImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceCDROMImageRead: called for %s id: %s", d.Get("name").(string), d.Id())
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
flattenImage(d, img)
return nil
}
func resourceCDROMImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceCDROMImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
imageData, err := utilityImageCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
c := m.(*controller.ControllerCfg)
req := image.DeleteCDROMImageRequest{
ImageID: imageData.ID,
}
_, err = c.CloudBroker().Image().DeleteCDROMImage(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId("")
return nil
}
func resourceCDROMImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceCDROMImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
if d.HasChange("enabled") {
err := resourceImageChangeEnabled(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("shared_with") {
err := resourceImageShare(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("computeci_id") {
err := resourceImageChangeComputeci(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChanges("name", "password_dl", "username_dl", "account_id", "bootable", "hot_resize") {
err := resourceImageCDROMEdit(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
return nil
}
func resourceImageCDROMEdit(ctx context.Context, d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*controller.ControllerCfg)
req := image.EditRequest{}
req.ImageID = uint64(d.Get("image_id").(int))
if d.HasChange("name") {
req.Name = d.Get("name").(string)
}
if d.HasChange("username_dl") {
req.Username = d.Get("username_dl").(string)
}
if d.HasChange("password_dl") {
req.Password = d.Get("password_dl").(string)
}
if d.HasChange("account_id") {
req.AccountID = uint64(d.Get("account_id").(int))
}
if d.HasChange("bootable") {
req.Bootable = d.Get("bootable").(bool)
}
if d.HasChange("hot_resize") {
req.HotResize = d.Get("hot_resize").(bool)
}
_, err := c.CloudBroker().Image().Edit(ctx, req)
if err != nil {
return err
}
return nil
}
func ResourceCDROMImage() *schema.Resource {
return &schema.Resource{
SchemaVersion: 2,
CreateContext: resourceCDROMImageCreate,
ReadContext: resourceCDROMImageRead,
UpdateContext: resourceCDROMImageUpdate,
DeleteContext: resourceCDROMImageDelete,
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: resourceCDROMImageSchemaMake(),
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceCDROMImageV1().CoreConfigSchema().ImpliedType(),
Upgrade: resourcePresentTOUpgradeV1,
Version: 1,
},
},
}
}

View File

@@ -1,50 +0,0 @@
package image
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/ic"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
)
func checkParamsExistenceBlankCompute(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics {
var errs []error
accountID := uint64(d.Get("account_id").(int))
computeId := uint64(d.Get("compute_id").(int))
if err := ic.ExistBlankCompute(ctx, computeId, c); err != nil {
errs = append(errs, err)
}
if _, ok := d.GetOk("account_id"); ok {
if err := ic.ExistAccount(ctx, accountID, c); err != nil {
errs = append(errs, err)
}
}
return dc.ErrorsToDiagnostics(errs)
}
func checkParamsExistencePlatformDisk(ctx context.Context, d *schema.ResourceData, c *controller.ControllerCfg) diag.Diagnostics {
var errs []error
accountID := uint64(d.Get("account_id").(int))
diskId := uint64(d.Get("disk_id").(int))
if err := ic.ExistPlatformDisk(ctx, diskId, c); err != nil {
errs = append(errs, err)
}
if _, ok := d.GetOk("account_id"); ok {
if err := ic.ExistAccount(ctx, accountID, c); err != nil {
errs = append(errs, err)
}
}
return dc.ErrorsToDiagnostics(errs)
}

View File

@@ -1,387 +0,0 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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/cloudbroker/image"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/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/dc"
"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))
url, _ := d.GetOk("url")
c := m.(*controller.ControllerCfg)
syncMode := d.Get("sync_mode").(bool)
log.Debugf("resourceImageCreate: sync_mode = %t", d.Get("sync_mode").(bool))
var imageId uint64
req, err := CreateRequest(ctx, d, m, url.(string))
if syncMode {
if err != nil {
return diag.FromErr(err)
}
imageId, err = c.CloudBroker().Image().CreateImage(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.CloudBroker().Image().AsyncCreateImage(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.CloudBroker().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))
var w dc.Warnings
if _, ok := d.GetOk("shared_with"); ok {
if err := resourceImageShare(ctx, d, m); err != nil {
w.Add(err)
}
}
return append(resourceImageRead(ctx, d, m), w.Get()...)
}
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 err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
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.CloudBroker().Image().Delete(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId("")
return nil
}
func resourceImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
if d.HasChange("enabled") {
err := resourceImageChangeEnabled(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("shared_with") {
err := resourceImageShare(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("computeci_id") {
err := resourceImageChangeComputeci(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize", "network_interface_naming") {
err := resourceImageEdit(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
return nil
}
func resourceImageChangeEnabled(ctx context.Context, d *schema.ResourceData, m interface{}) error {
c := m.(*controller.ControllerCfg)
imageId := uint64(d.Get("image_id").(int))
if d.Get("enabled").(bool) {
req := image.EnableRequest{
ImageID: imageId,
}
_, err := c.CloudBroker().Image().Enable(ctx, req)
if err != nil {
return err
}
} else {
req := image.DisableRequest{
ImageID: imageId,
}
_, err := c.CloudBroker().Image().Disable(ctx, req)
if err != nil {
return err
}
}
return nil
}
func resourceImageShare(ctx context.Context, d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceImageShare: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*controller.ControllerCfg)
imageID, _ := strconv.ParseUint(d.Id(), 10, 64)
sharedWith := d.Get("shared_with").([]interface{})
if len(sharedWith) == 0 {
req := image.RevokeAccessRequest{
ImageID: imageID,
AccountIDs: []int64{-1},
}
_, err := c.CloudBroker().Image().RevokeAccess(ctx, req)
if err != nil {
return err
}
return nil
}
req := image.ShareRequest{
ImageId: imageID,
}
accIds := []uint64{}
for _, accId := range sharedWith {
accIds = append(accIds, uint64(accId.(int)))
}
req.AccountIDs = accIds
getReq := image.GetRequest{ImageID: imageID}
for {
image, err := c.CloudBroker().Image().Get(ctx, getReq)
if err != nil {
return err
}
if image.Status != "CREATING" {
break
}
time.Sleep(time.Second * 10)
}
_, err := c.CloudBroker().Image().Share(ctx, req)
if err != nil {
return err
}
return nil
}
func resourceImageChangeComputeci(ctx context.Context, d *schema.ResourceData, m interface{}) error {
c := m.(*controller.ControllerCfg)
imageId := uint64(d.Get("image_id").(int))
computeci := uint64(d.Get("computeci_id").(int))
if computeci == 0 {
req := image.ComputeCIUnsetRequest{
ImageID: imageId,
}
_, err := c.CloudBroker().Image().ComputeCIUnset(ctx, req)
if err != nil {
return err
}
} else {
req := image.ComputeCISetRequest{
ImageID: imageId,
ComputeCIID: computeci,
}
_, err := c.CloudBroker().Image().ComputeCISet(ctx, req)
if err != nil {
return err
}
}
return nil
}
func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*controller.ControllerCfg)
req := image.EditRequest{}
req.ImageID = uint64(d.Get("image_id").(int))
if d.HasChange("name") {
req.Name = d.Get("name").(string)
}
if d.HasChange("username") {
req.Username = d.Get("username").(string)
}
if d.HasChange("password") {
req.Password = d.Get("password").(string)
}
if d.HasChange("account_id") {
req.AccountID = uint64(d.Get("account_id").(int))
}
if d.HasChange("bootable") {
req.Bootable = d.Get("bootable").(bool)
}
if d.HasChange("hot_resize") {
req.HotResize = d.Get("hot_resize").(bool)
}
if d.HasChange("network_interface_naming") {
req.NetworkInterfaceNaming = d.Get("network_interface_naming").(string)
}
_, err := c.CloudBroker().Image().Edit(ctx, req)
if err != nil {
return err
}
return nil
}
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(),
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceImageV1().CoreConfigSchema().ImpliedType(),
Upgrade: resourcePresentTOUpgradeV1,
Version: 1,
},
},
}
}

View File

@@ -1,286 +0,0 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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/cloudbroker/compute"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/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/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
)
func resourceImageFromBlankComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceImageFromBlankComputeCreate: called for image %s", d.Get("name").(string))
c := m.(*controller.ControllerCfg)
if diags := checkParamsExistenceBlankCompute(ctx, d, c); diags != nil {
return diags
}
req := compute.CreateTemplateFromBlankRequest{
ComputeID: uint64(d.Get("compute_id").(int)),
Name: d.Get("name").(string),
BootType: d.Get("boot_type").(string),
ImageType: d.Get("image_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
var err error
asyncMode := d.Get("async_mode").(bool)
if !asyncMode {
imageId, err = c.CloudBroker().Compute().CreateTemplateFromBlank(ctx, req)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
} else {
taskId, err := c.CloudBroker().Compute().CreateTemplateFromBlankAsync(ctx, req)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
taskReq := tasks.GetRequest{
AuditID: strings.Trim(taskId, `"`),
}
for {
task, err := c.CloudBroker().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)
var w dc.Warnings
if _, ok := d.GetOk("shared_with"); ok {
if err := resourceImageShare(ctx, d, m); err != nil {
w.Add(err)
}
}
return append(resourceImageFromBlankComputeRead(ctx, d, m), w.Get()...)
}
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 err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
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.CloudBroker().Image().Delete(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId("")
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())
c := m.(*controller.ControllerCfg)
if diags := checkParamsExistenceBlankCompute(ctx, d, c); diags != nil {
return diags
}
// 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")
}
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
if d.HasChange("enabled") {
err := resourceImageChangeEnabled(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("shared_with") {
err := resourceImageShare(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("computeci_id") {
err := resourceImageChangeComputeci(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize", "network_interface_naming") {
err := resourceImageEdit(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("shared_with") {
err := resourceImageShare(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: resourceImageFromBlankComputeV1().CoreConfigSchema().ImpliedType(),
Upgrade: resourcePresentTOUpgradeV1,
Version: 1,
},
},
}
}

View File

@@ -1,287 +0,0 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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/cloudbroker/disks"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/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/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
)
func resourceImageFromPlatformDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceImageFromPlatformDiskCreate: called for image %s", d.Get("name").(string))
c := m.(*controller.ControllerCfg)
if diags := checkParamsExistencePlatformDisk(ctx, d, c); diags != nil {
return diags
}
req := disks.FromPlatformDiskRequest{
DiskID: uint64(d.Get("disk_id").(int)),
Name: d.Get("name").(string),
BootType: d.Get("boot_type").(string),
ImageType: d.Get("image_type").(string),
Bootable: d.Get("bootable").(bool), // default is 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
var err error
asyncMode := d.Get("async_mode").(bool)
if !asyncMode {
imageId, err = c.CloudBroker().Disks().FromPlatformDisk(ctx, req)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
} else {
taskId, err := c.CloudBroker().Disks().FromPlatformDiskAsync(ctx, req)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
taskReq := tasks.GetRequest{
AuditID: strings.Trim(taskId, `"`),
}
for {
task, err := c.CloudBroker().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)
var w dc.Warnings
if _, ok := d.GetOk("shared_with"); ok {
if err := resourceImageShare(ctx, d, m); err != nil {
w.Add(err)
}
}
return append(resourceImageFromPlatformDiskRead(ctx, d, m), w.Get()...)
}
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 err != 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.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.CloudBroker().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())
c := m.(*controller.ControllerCfg)
if diags := checkParamsExistencePlatformDisk(ctx, d, c); diags != nil {
return diags
}
// 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")
}
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
if d.HasChange("enabled") {
err := resourceImageChangeEnabled(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("shared_with") {
err := resourceImageShare(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("computeci_id") {
err := resourceImageChangeComputeci(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize", "network_interface_naming") {
err := resourceImageEdit(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("shared_with") {
err := resourceImageShare(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: resourceImageFromPlatformDiskV1().CoreConfigSchema().ImpliedType(),
Upgrade: resourcePresentTOUpgradeV1,
Version: 1,
},
},
}
}

View File

@@ -1,274 +0,0 @@
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/cloudbroker/image"
"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/dc"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/status"
)
func resourceMultiImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceMultiImageCreate: called for image %s", d.Get("name").(string))
c := m.(*controller.ControllerCfg)
targetIDsRaw := d.Get("target_ids").([]interface{})
targetIDs := make([]uint64, 0, len(targetIDsRaw))
for _, id := range targetIDsRaw {
targetIDs = append(targetIDs, uint64(id.(int)))
}
req := image.CreateMultiImageRequest{
Name: d.Get("name").(string),
TargetIDs: targetIDs,
AccountID: uint64(d.Get("account_id").(int)),
}
imageId, err := c.CloudBroker().Image().CreateMultiImage(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(imageId, 10))
d.Set("image_id", imageId)
var w dc.Warnings
if !d.Get("enabled").(bool) {
if err := resourceImageChangeEnabled(ctx, d, m); err != nil {
w.Add(err)
}
}
if _, ok := d.GetOk("shared_with"); ok {
if err := resourceImageShare(ctx, d, m); err != nil {
w.Add(err)
}
}
if _, ok := d.GetOk("computeci_id"); ok {
if err := resourceImageChangeComputeci(ctx, d, m); err != nil {
w.Add(err)
}
}
updReq := image.EditRequest{}
updReq.ImageID = uint64(d.Get("image_id").(int))
if _, ok := d.GetOk("username"); ok {
updReq.Username = d.Get("username").(string)
}
if _, ok := d.GetOk("password"); ok {
updReq.Password = d.Get("password").(string)
}
if _, ok := d.GetOk("account_id"); ok {
updReq.AccountID = uint64(d.Get("account_id").(int))
}
if _, ok := d.GetOkExists("bootable"); ok {
updReq.Bootable = d.Get("bootable").(bool)
}
if _, ok := d.GetOkExists("hot_resize"); ok {
updReq.HotResize = d.Get("hot_resize").(bool)
}
if _, ok := d.GetOk("network_interface_naming"); ok {
updReq.NetworkInterfaceNaming = d.Get("network_interface_naming").(string)
}
_, err = c.CloudBroker().Image().Edit(ctx, updReq)
if err != nil {
w.Add(err)
}
return append(resourceMultiImageRead(ctx, d, m), w.Get()...)
}
func resourceMultiImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceMultiImageRead: called for %s id: %s", d.Get("name").(string), d.Id())
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
flattenImage(d, img)
return nil
}
func resourceMultiImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceMultiImageDelete: 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.CloudBroker().Image().Delete(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId("")
return nil
}
func resourceMultiImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceMultiImageUpdate: called for %s, id: %s", d.Get("name").(string), d.Id())
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
if d.HasChange("enabled") {
err := resourceImageChangeEnabled(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("shared_with") {
err := resourceImageShare(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("computeci_id") {
err := resourceImageChangeComputeci(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize") {
err := resourceImageEdit(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("target_ids") {
err := resourceMultiImageUpdateLinks(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
return resourceMultiImageRead(ctx, d, m)
}
func resourceMultiImageUpdateLinks(ctx context.Context, d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceMultiImageUpdateLinks: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*controller.ControllerCfg)
imageID := uint64(d.Get("image_id").(int))
oldRaw, newRaw := d.GetChange("target_ids")
oldIDs := oldRaw.([]interface{})
newIDs := newRaw.([]interface{})
oldSet := make(map[uint64]bool)
for _, id := range oldIDs {
oldSet[uint64(id.(int))] = true
}
newSet := make(map[uint64]bool)
for _, id := range newIDs {
newSet[uint64(id.(int))] = true
}
toAdd := make([]uint64, 0)
for id := range newSet {
if !oldSet[id] {
toAdd = append(toAdd, id)
}
}
toRemove := make([]uint64, 0)
for id := range oldSet {
if !newSet[id] {
toRemove = append(toRemove, id)
}
}
if len(toAdd) > 0 {
req := image.MultiImageAddLinksRequest{
ImageID: imageID,
TargetIDs: toAdd,
}
_, err := c.CloudBroker().Image().MultiImageAddLinks(ctx, req)
if err != nil {
return err
}
}
if len(toRemove) > 0 {
req := image.MultiImageDelLinksRequest{
ImageID: imageID,
TargetIDs: toRemove,
}
_, err := c.CloudBroker().Image().MultiImageDelLinks(ctx, req)
if err != nil {
return err
}
}
return nil
}
func ResourceMultiImage() *schema.Resource {
return &schema.Resource{
SchemaVersion: 2,
CreateContext: resourceMultiImageCreate,
ReadContext: resourceMultiImageRead,
UpdateContext: resourceMultiImageUpdate,
DeleteContext: resourceMultiImageDelete,
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: resourceMultiImageSchemaMake(),
}
}

View File

@@ -1,214 +0,0 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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/cloudbroker/image"
"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 resourceVirtualImageCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceImageCreate: 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.CloudBroker().Image().CreateVirtual(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(imageId, 10))
return resourceImageRead(ctx, d, m)
}
func resourceVirtualImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceVirtualImageRead: called for %s id: %s", d.Get("name").(string), d.Id())
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
flattenImage(d, img)
return nil
}
func resourceVirtualImageDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceVirtualImageDelete: 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.CloudBroker().Image().Delete(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId("")
return nil
}
func resourceVirtualImageUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Debugf("resourceVirtualImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
img, err := utilityImageCheckPresence(ctx, d, m)
if err != 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.Destroyed, status.Purged:
d.SetId("")
return diag.Errorf("The resource cannot be updated because it has been destroyed")
}
if d.HasChange("enabled") {
err := resourceImageChangeEnabled(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("shared_with") {
err := resourceImageShare(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("computeci_id") {
err := resourceImageChangeComputeci(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChanges("name", "username", "password", "account_id", "bootable", "hot_resize") {
err := resourceImageEdit(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
if d.HasChange("link_to") {
err := resourceImageLink(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
}
return nil
}
func resourceImageLink(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.CloudBroker().Image().Link(ctx, req)
if err != nil {
return err
}
return nil
}
func ResourceVirtualImage() *schema.Resource {
return &schema.Resource{
SchemaVersion: 2,
CreateContext: resourceVirtualImageCreate,
ReadContext: resourceVirtualImageRead,
UpdateContext: resourceVirtualImageUpdate,
DeleteContext: resourceVirtualImageDelete,
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: resourceVirtualImageSchemaMake(),
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceVirtualImageV1().CoreConfigSchema().ImpliedType(),
Upgrade: resourcePresentTOUpgradeV1,
Version: 1,
},
},
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +0,0 @@
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
}

View File

@@ -1,60 +0,0 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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/cloudbroker/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 d.Id() != "" {
id, _ := strconv.ParseUint(d.Id(), 10, 64)
req.ImageID = id
} else {
req.ImageID = uint64(d.Get("image_id").(int))
}
image, err := c.CloudBroker().Image().Get(ctx, req)
if err != nil {
return nil, err
}
return image, nil
}

View File

@@ -1,103 +0,0 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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/cloudbroker/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 {
req.TypeImage = typeImage.(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.CloudBroker().Image().List(ctx, req)
if err != nil {
return nil, err
}
return imageList, nil
}

View File

@@ -1,81 +0,0 @@
/*
Copyright (c) 2019-2023 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
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/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/image"
)
func CreateRequest(ctx context.Context, d *schema.ResourceData, m interface{}, url string) (image.CreateRequest, error) {
req := image.CreateRequest{
Name: d.Get("name").(string),
URL: url,
BootType: d.Get("boot_type").(string),
ImageType: d.Get("image_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 accountId, ok := d.GetOk("account_id"); ok {
req.AccountID = uint64(accountId.(int))
}
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.PoolName = poolName.(string)
}
if bootable, ok := d.GetOk("bootable"); ok {
req.Bootable = bootable.(bool)
}
if networkInterfaceNaming, ok := d.GetOk("network_interface_naming"); ok {
req.NetworkInterfaceNaming = networkInterfaceNaming.(string)
}
return req, nil
}