parent
2b7f3d45f3
commit
28ceebecf8
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package image
|
||||||
|
|
||||||
|
const imageCreateAPI = "/restmachine/cloudapi/image/createImage"
|
||||||
|
const imageCreateVirtualAPI = "/restmachine/cloudapi/image/createVirtual"
|
||||||
|
const imageGetAPI = "/restmachine/cloudapi/image/get"
|
||||||
|
const imageListGetAPI = "/restmachine/cloudapi/image/list"
|
||||||
|
const imageDeleteAPI = "/restmachine/cloudapi/image/delete"
|
||||||
|
const imageEditNameAPI = "/restmachine/cloudapi/image/rename"
|
||||||
|
const imageLinkAPI = "/restmachine/cloudapi/image/link"
|
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/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"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenHistory(history []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 *ImageExtend) {
|
||||||
|
d.Set("unc_path", img.UNCPath)
|
||||||
|
d.Set("ckey", img.CKey)
|
||||||
|
d.Set("account_id", img.AccountId)
|
||||||
|
d.Set("acl", 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("deleted_time", img.DeletedTime)
|
||||||
|
d.Set("desc", img.Description)
|
||||||
|
d.Set("drivers", img.Drivers)
|
||||||
|
d.Set("enabled", img.Enabled)
|
||||||
|
d.Set("gid", img.GridId)
|
||||||
|
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("last_modified", img.LastModified)
|
||||||
|
d.Set("link_to", img.LinkTo)
|
||||||
|
d.Set("milestones", img.Milestones)
|
||||||
|
d.Set("image_name", img.Name)
|
||||||
|
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("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("status", img.Status)
|
||||||
|
d.Set("tech_status", img.TechStatus)
|
||||||
|
d.Set("type", img.Type)
|
||||||
|
d.Set("username", img.Username)
|
||||||
|
d.Set("version", img.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
|
||||||
|
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(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/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"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenImageList(il ImageList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, img := range il {
|
||||||
|
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,
|
||||||
|
"pool_name": img.Pool,
|
||||||
|
"sep_id": img.SepId,
|
||||||
|
"size": img.Size,
|
||||||
|
"status": img.Status,
|
||||||
|
"type": img.Type,
|
||||||
|
"username": img.Username,
|
||||||
|
"virtual": img.Virtual,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceImageListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
imageList, err := utilityImageListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenImageList(imageList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceImageListSchemaMake() map[string]*schema.Schema {
|
||||||
|
rets := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "optional account ID to include account images",
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "page number",
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "page size",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Description: "image list",
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceImageSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceImageList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceImageListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceImageListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/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,
|
||||||
|
},
|
||||||
|
"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,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
"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,
|
||||||
|
},
|
||||||
|
"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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/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",
|
||||||
|
},
|
||||||
|
"image_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Image name",
|
||||||
|
},
|
||||||
|
"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",
|
||||||
|
},
|
||||||
|
"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",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/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["gid"] = &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "grid (platform) ID where this template should be create in",
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
Optional: true,
|
||||||
|
Computed: 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", "PPC64_LE"}, true),
|
||||||
|
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
|
||||||
|
}
|
||||||
|
|
||||||
|
sch["drivers"] = &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Required: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sch["permanently"] = &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "whether to completely delete the image",
|
||||||
|
}
|
||||||
|
|
||||||
|
return sch
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/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["permanently"] = &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "whether to completely delete the image",
|
||||||
|
}
|
||||||
|
|
||||||
|
sch["image_id"] = &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Image id",
|
||||||
|
}
|
||||||
|
|
||||||
|
return sch
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package image
|
||||||
|
|
||||||
|
/*
|
||||||
|
type History struct {
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Timestamp int64 `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Image struct {
|
||||||
|
ImageId int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Gid int `json:"gid"`
|
||||||
|
Guid int `json:"guid"`
|
||||||
|
Boottype string `json:"bootType"`
|
||||||
|
Imagetype string `json:"type"`
|
||||||
|
Drivers []string `json:"drivers"`
|
||||||
|
Hotresize bool `json:"hotResize"`
|
||||||
|
Bootable bool `json:"bootable"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
AccountId int `json:"accountId"`
|
||||||
|
UsernameDL string `json:"usernameDL"`
|
||||||
|
PasswordDL string `json:"passwordDL"`
|
||||||
|
SepId int `json:"sepId"`
|
||||||
|
PoolName string `json:"pool"`
|
||||||
|
Architecture string `json:"architecture"`
|
||||||
|
UNCPath string `json:"UNCPath"`
|
||||||
|
LinkTo int `json:"linkTo"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
TechStatus string `json:"techStatus"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
ComputeciId int `json:"computeciId"`
|
||||||
|
Milestones int `json:"milestones"`
|
||||||
|
ProviderName string `json:"provider_name"`
|
||||||
|
PurgeAttempts int `json:"purgeAttempts"`
|
||||||
|
ReferenceId string `json:"referenceId"`
|
||||||
|
ResId string `json:"resId"`
|
||||||
|
ResName string `json:"resName"`
|
||||||
|
Rescuecd bool `json:"rescuecd"`
|
||||||
|
Meta []interface{} `json:"_meta"`
|
||||||
|
History []History `json:"history"`
|
||||||
|
LastModified int64 `json:"lastModified"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
SharedWith []int `json:"sharedWith"`
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Image struct {
|
||||||
|
AccountId int `json:"accountId"`
|
||||||
|
Architecture string `json:"architecture"`
|
||||||
|
BootType string `json:"bootType"`
|
||||||
|
Bootable bool `json:"bootable"`
|
||||||
|
CDROM bool `json:"cdrom"`
|
||||||
|
Description string `json:"desc"`
|
||||||
|
Drivers []string `json:"drivers"`
|
||||||
|
HotResize bool `json:"hotResize"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
LinkTo int `json:"linkTo"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Pool string `json:"pool"`
|
||||||
|
SepId int `json:"sepId"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Virtual bool `json:"virtual"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageList []Image
|
||||||
|
|
||||||
|
type History struct {
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
Timestamp int64 `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageExtend struct {
|
||||||
|
UNCPath string `json:"UNCPath"`
|
||||||
|
CKey string `json:"_ckey"`
|
||||||
|
AccountId int `json:"accountId"`
|
||||||
|
Acl interface{} `json:"acl"`
|
||||||
|
Architecture string `json:"architecture"`
|
||||||
|
BootType string `json:"bootType"`
|
||||||
|
Bootable bool `json:"bootable"`
|
||||||
|
ComputeCiId int `json:"computeciId"`
|
||||||
|
DeletedTime int `json:"deletedTime"`
|
||||||
|
Description string `json:"desc"`
|
||||||
|
Drivers []string `json:"drivers"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
GridId int `json:"gid"`
|
||||||
|
GUID int `json:"guid"`
|
||||||
|
History []History `json:"history"`
|
||||||
|
HotResize bool `json:"hotResize"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
LastModified int `json:"lastModified"`
|
||||||
|
LinkTo int `json:"linkTo"`
|
||||||
|
Milestones int `json:"milestones"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Pool string `json:"pool"`
|
||||||
|
ProviderName string `json:"provider_name"`
|
||||||
|
PurgeAttempts int `json:"purgeAttempts"`
|
||||||
|
ResId string `json:"resId"`
|
||||||
|
RescueCD bool `json:"rescuecd"`
|
||||||
|
SepId int `json:"sepId"`
|
||||||
|
SharedWith []int `json:"sharedWith"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
TechStatus string `json:"techStatus"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
}
|
@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceImageCreate(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)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("name", d.Get("name").(string))
|
||||||
|
urlValues.Add("url", d.Get("url").(string))
|
||||||
|
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
|
||||||
|
urlValues.Add("boottype", d.Get("boot_type").(string))
|
||||||
|
urlValues.Add("imagetype", d.Get("image_type").(string))
|
||||||
|
|
||||||
|
tstr := d.Get("drivers").([]interface{})
|
||||||
|
temp := ""
|
||||||
|
l := len(tstr)
|
||||||
|
for i, str := range tstr {
|
||||||
|
s := "\"" + str.(string) + "\""
|
||||||
|
if i != (l - 1) {
|
||||||
|
s += ","
|
||||||
|
}
|
||||||
|
temp = temp + s
|
||||||
|
}
|
||||||
|
temp = "[" + temp + "]"
|
||||||
|
urlValues.Add("drivers", temp)
|
||||||
|
|
||||||
|
if hotresize, ok := d.GetOk("hot_resize"); ok {
|
||||||
|
urlValues.Add("hotresize", strconv.FormatBool(hotresize.(bool)))
|
||||||
|
}
|
||||||
|
if username, ok := d.GetOk("username"); ok {
|
||||||
|
urlValues.Add("username", username.(string))
|
||||||
|
}
|
||||||
|
if password, ok := d.GetOk("password"); ok {
|
||||||
|
urlValues.Add("password", password.(string))
|
||||||
|
}
|
||||||
|
if accountId, ok := d.GetOk("account_id"); ok {
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
||||||
|
}
|
||||||
|
if usernameDL, ok := d.GetOk("username_dl"); ok {
|
||||||
|
urlValues.Add("usernameDL", usernameDL.(string))
|
||||||
|
}
|
||||||
|
if passwordDL, ok := d.GetOk("password_dl"); ok {
|
||||||
|
urlValues.Add("passwordDL", passwordDL.(string))
|
||||||
|
}
|
||||||
|
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||||
|
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
|
||||||
|
}
|
||||||
|
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||||
|
urlValues.Add("poolName", poolName.(string))
|
||||||
|
}
|
||||||
|
if architecture, ok := d.GetOk("architecture"); ok {
|
||||||
|
urlValues.Add("architecture", architecture.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
imageId, err := c.DecortAPICall(ctx, "POST", imageCreateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(imageId)
|
||||||
|
d.Set("image_id", imageId)
|
||||||
|
|
||||||
|
_, err = utilityImageCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
diagnostics := resourceImageRead(ctx, d, m)
|
||||||
|
if diagnostics != nil {
|
||||||
|
return diagnostics
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("unc_path", img.UNCPath)
|
||||||
|
d.Set("ckey", img.CKey)
|
||||||
|
d.Set("account_id", img.AccountId)
|
||||||
|
d.Set("acl", 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("deleted_time", img.DeletedTime)
|
||||||
|
d.Set("desc", img.Description)
|
||||||
|
d.Set("drivers", img.Drivers)
|
||||||
|
d.Set("enabled", img.Enabled)
|
||||||
|
d.Set("gid", img.GridId)
|
||||||
|
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("last_modified", img.LastModified)
|
||||||
|
d.Set("link_to", img.LinkTo)
|
||||||
|
d.Set("milestones", img.Milestones)
|
||||||
|
d.Set("image_name", img.Name)
|
||||||
|
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("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("status", img.Status)
|
||||||
|
d.Set("tech_status", img.TechStatus)
|
||||||
|
d.Set("type", img.Type)
|
||||||
|
d.Set("username", img.Username)
|
||||||
|
d.Set("version", img.Version)
|
||||||
|
|
||||||
|
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())
|
||||||
|
|
||||||
|
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||||
|
if image == nil {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||||
|
|
||||||
|
if permanently, ok := d.GetOk("permanently"); ok {
|
||||||
|
urlValues.Add("permanently", strconv.FormatBool(permanently.(bool)))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", imageDeleteAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceImageExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
log.Debugf("resourceImageExists: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||||
|
|
||||||
|
image, err := utilityImageCheckPresence(ctx, d, m)
|
||||||
|
if image == nil {
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceImageEditName(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)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||||
|
urlValues.Add("name", d.Get("name").(string))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", imageEditNameAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceImageEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||||
|
|
||||||
|
if d.HasChange("name") {
|
||||||
|
err := resourceImageEditName(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceImageRead(ctx, d, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceImage() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceImageCreate,
|
||||||
|
ReadContext: resourceImageRead,
|
||||||
|
UpdateContext: resourceImageEdit,
|
||||||
|
DeleteContext: resourceImageDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout60s,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout60s,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: resourceImageSchemaMake(dataSourceImageExtendSchemaMake()),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("name", d.Get("name").(string))
|
||||||
|
urlValues.Add("targetId", strconv.Itoa(d.Get("target_id").(int)))
|
||||||
|
|
||||||
|
imageId, err := c.DecortAPICall(ctx, "POST", imageCreateVirtualAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(imageId)
|
||||||
|
d.Set("image_id", imageId)
|
||||||
|
|
||||||
|
_, err = utilityImageCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
diagnostics := resourceImageRead(ctx, d, m)
|
||||||
|
if diagnostics != nil {
|
||||||
|
return diagnostics
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceImageVirtualEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||||
|
|
||||||
|
if d.HasChange("name") {
|
||||||
|
err := resourceImageEditName(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)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||||
|
urlValues.Add("targetId", strconv.Itoa(d.Get("link_to").(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", imageLinkAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceImageVirtual() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceImageVirtualCreate,
|
||||||
|
ReadContext: resourceImageRead,
|
||||||
|
UpdateContext: resourceImageVirtualEdit,
|
||||||
|
DeleteContext: resourceImageDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout60s,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout60s,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: resourceImageVirtualSchemaMake(dataSourceImageExtendSchemaMake()),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityImageCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*ImageExtend, error) {
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
if (strconv.Itoa(d.Get("image_id").(int))) != "0" {
|
||||||
|
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("imageId", d.Id())
|
||||||
|
}
|
||||||
|
|
||||||
|
if showAll, ok := d.GetOk("show_all"); ok {
|
||||||
|
urlValues.Add("page", strconv.FormatBool(showAll.(bool)))
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.DecortAPICall(ctx, "POST", imageGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
image := &ImageExtend{}
|
||||||
|
if err := json.Unmarshal([]byte(resp), image); err != nil {
|
||||||
|
return nil, errors.New(fmt.Sprint("Can not unmarshall data to image: ", resp, " ", image))
|
||||||
|
}
|
||||||
|
|
||||||
|
return image, nil
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityImageListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ImageList, error) {
|
||||||
|
imageList := ImageList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
if accountId, ok := d.GetOk("account_id"); ok {
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if page, ok := d.GetOk("page"); ok {
|
||||||
|
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||||
|
}
|
||||||
|
if size, ok := d.GetOk("size"); ok {
|
||||||
|
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityImageListCheckPresence: load image list")
|
||||||
|
imageListRaw, err := c.DecortAPICall(ctx, "POST", imageListGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(imageListRaw), &imageList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return imageList, nil
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func dataSourceAccountAuditSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"call": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"responsetime": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"statuscode": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func dataSourceAccountComputeSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cpus": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"registered": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"rg_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"tech_status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_disks_size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"user_managed": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vins_connected": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func dataSourceAccountDiskSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"disk_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disk_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"pool_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"sep_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func dataSourceAccountSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"dc_location": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"current": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disksize": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"extips": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"exttraffic": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"reserved": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disksize": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"extips": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"exttraffic": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ckey": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"acl": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"explicit": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"user_group_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"company": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"companyurl": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deactivation_time": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"displayname": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"resource_limits": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cu_c": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_d": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_i": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_m": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_np": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu_units": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"send_access_emails": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"service_account": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vins": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func dataSourceAccountFlipGroupSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"client_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"conn_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"default_gw": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"desc": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"fg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ip": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"milestones": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"fg_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"net_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"net_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"netmask": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func dataSourceAccountItemSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"dc_location": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ckey": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"acl": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"explicit": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"user_group_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"company": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"companyurl": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deactivation_time": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"displayname": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"resource_limits": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cu_c": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_d": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_i": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_m": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_np": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu_units": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"send_access_emails": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"service_account": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vins": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func dataSourceAccountRGSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"computes": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"started": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"stopped": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"consumed": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disksize": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"extips": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"exttraffic": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"limits": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disksize": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"extips": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"exttraffic": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"reserved": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disksize": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"extips": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"exttraffic": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"milestones": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"rg_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vinses": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,320 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func resourceAccountSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "account name",
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "username of owner the account",
|
||||||
|
},
|
||||||
|
"emailaddress": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "email",
|
||||||
|
},
|
||||||
|
"send_access_emails": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Description: "if true send emails when a user is granted access to resources",
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"user_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"access_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"recursive_delete": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"restore": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Description: "restore a deleted account",
|
||||||
|
},
|
||||||
|
"permanently": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "whether to completely delete the account",
|
||||||
|
},
|
||||||
|
"enable": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Description: "enable/disable account",
|
||||||
|
},
|
||||||
|
"resource_limits": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cu_c": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_d": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_i": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_m": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_np": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu_units": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"dc_location": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"current": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disksize": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"extips": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"exttraffic": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"reserved": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disksize": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"extips": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"exttraffic": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ckey": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"acl": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"explicit": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"user_group_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"company": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"companyurl": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deactivation_time": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"displayname": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"service_account": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vins": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func dataSourceAccountVinsSchema() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"computes": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"external_ip": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vin_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vin_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"pri_vnf_dev_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"rg_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
const accountAddUserAPI = "/restmachine/cloudbroker/account/addUser"
|
||||||
|
const accountAuditsAPI = "/restmachine/cloudbroker/account/audits"
|
||||||
|
const accountCreateAPI = "/restmachine/cloudbroker/account/create"
|
||||||
|
const accountDeleteAPI = "/restmachine/cloudbroker/account/delete"
|
||||||
|
const accountDeleteUserAPI = "/restmachine/cloudbroker/account/deleteUser"
|
||||||
|
const accountDisableAPI = "/restmachine/cloudbroker/account/disable"
|
||||||
|
const accountEnableAPI = "/restmachine/cloudbroker/account/enable"
|
||||||
|
const accountGetAPI = "/restmachine/cloudbroker/account/get"
|
||||||
|
const accountListAPI = "/restmachine/cloudbroker/account/list"
|
||||||
|
const accountListComputesAPI = "/restmachine/cloudbroker/account/listComputes"
|
||||||
|
const accountListDeletedAPI = "/restmachine/cloudbroker/account/listDeleted"
|
||||||
|
const accountListDisksAPI = "/restmachine/cloudbroker/account/listDisks"
|
||||||
|
const accountListFlipGroupsAPI = "/restmachine/cloudbroker/account/listFlipGroups"
|
||||||
|
const accountListRGAPI = "/restmachine/cloudbroker/account/listRG"
|
||||||
|
const accountListVinsAPI = "/restmachine/cloudbroker/account/listVins"
|
||||||
|
const accountRestoreAPI = "/restmachine/cloudbroker/account/restore"
|
||||||
|
const accountUpdateAPI = "/restmachine/cloudbroker/account/update"
|
||||||
|
const accountUpdateUserAPI = "/restmachine/cloudbroker/account/updateUser"
|
||||||
|
const accountsEnableAPI = "/restmachine/cloudbroker/account/enableAccounts"
|
||||||
|
const accountsDisableAPI = "/restmachine/cloudbroker/account/disableAccounts"
|
||||||
|
const accountsDeleteAPI = "/restmachine/cloudbroker/account/deleteAccounts"
|
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/flattens"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
acc, err := utilityAccountCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("dc_location", acc.DCLocation)
|
||||||
|
d.Set("resources", flattenAccResources(acc.Resources))
|
||||||
|
d.Set("ckey", acc.CKey)
|
||||||
|
d.Set("meta", flattens.FlattenMeta(acc.Meta))
|
||||||
|
d.Set("acl", flattenAccAcl(acc.Acl))
|
||||||
|
d.Set("company", acc.Company)
|
||||||
|
d.Set("companyurl", acc.CompanyUrl)
|
||||||
|
d.Set("created_by", acc.CreatedBy)
|
||||||
|
d.Set("created_time", acc.CreatedTime)
|
||||||
|
d.Set("deactivation_time", acc.DeactiovationTime)
|
||||||
|
d.Set("deleted_by", acc.DeletedBy)
|
||||||
|
d.Set("deleted_time", acc.DeletedTime)
|
||||||
|
d.Set("displayname", acc.DisplayName)
|
||||||
|
d.Set("guid", acc.GUID)
|
||||||
|
d.Set("account_id", acc.ID)
|
||||||
|
d.Set("account_name", acc.Name)
|
||||||
|
d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits))
|
||||||
|
d.Set("send_access_emails", acc.SendAccessEmails)
|
||||||
|
d.Set("service_account", acc.ServiceAccount)
|
||||||
|
d.Set("status", acc.Status)
|
||||||
|
d.Set("updated_time", acc.UpdatedTime)
|
||||||
|
d.Set("version", acc.Version)
|
||||||
|
d.Set("vins", acc.Vins)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, acls := range acls {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"explicit": acls.IsExplicit,
|
||||||
|
"guid": acls.Guid,
|
||||||
|
"right": acls.Rights,
|
||||||
|
"status": acls.Status,
|
||||||
|
"type": acls.Type,
|
||||||
|
"user_group_id": acls.UgroupID,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccount() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenAccountAuditsList(aal AccountAuditsList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, aa := range aal {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"call": aa.Call,
|
||||||
|
"responsetime": aa.ResponseTime,
|
||||||
|
"statuscode": aa.StatusCode,
|
||||||
|
"timestamp": aa.Timestamp,
|
||||||
|
"user": aa.User,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountAuditsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
accountAuditsList, err := utilityAccountAuditsListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenAccountAuditsList(accountAuditsList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountAuditsListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "ID of the account",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Search Result",
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceAccountAuditSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccountAuditsList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountAuditsListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountAuditsListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenAccountComputesList(acl AccountComputesList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, acc := range acl {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"account_id": acc.AccountId,
|
||||||
|
"account_name": acc.AccountName,
|
||||||
|
"cpus": acc.CPUs,
|
||||||
|
"created_by": acc.CreatedBy,
|
||||||
|
"created_time": acc.CreatedTime,
|
||||||
|
"deleted_by": acc.DeletedBy,
|
||||||
|
"deleted_time": acc.DeletedTime,
|
||||||
|
"compute_id": acc.ComputeId,
|
||||||
|
"compute_name": acc.ComputeName,
|
||||||
|
"ram": acc.RAM,
|
||||||
|
"registered": acc.Registered,
|
||||||
|
"rg_id": acc.RgId,
|
||||||
|
"rg_name": acc.RgName,
|
||||||
|
"status": acc.Status,
|
||||||
|
"tech_status": acc.TechStatus,
|
||||||
|
"total_disks_size": acc.TotalDisksSize,
|
||||||
|
"updated_by": acc.UpdatedBy,
|
||||||
|
"updated_time": acc.UpdatedTime,
|
||||||
|
"user_managed": acc.UserManaged,
|
||||||
|
"vins_connected": acc.VinsConnected,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountComputesListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
accountComputesList, err := utilityAccountComputesListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenAccountComputesList(accountComputesList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountComputesListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "ID of the account",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Search Result",
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceAccountComputeSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccountComputesList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountComputesListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountComputesListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceAccountDeletedListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
accountDeletedList, err := utilityAccountDeletedListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenAccountList(accountDeletedList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccountDeletedList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountDeletedListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenAccountDisksList(adl AccountDisksList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, ad := range adl {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"disk_id": ad.ID,
|
||||||
|
"disk_name": ad.Name,
|
||||||
|
"pool_name": ad.Pool,
|
||||||
|
"sep_id": ad.SepId,
|
||||||
|
"size_max": ad.SizeMax,
|
||||||
|
"type": ad.Type,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountDisksListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
accountDisksList, err := utilityAccountDisksListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenAccountDisksList(accountDisksList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountDisksListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "ID of the account",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Search Result",
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceAccountDiskSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccountDisksList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountDisksListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountDisksListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenAccountFlipGroupsList(afgl AccountFlipGroupsList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, afg := range afgl {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"account_id": afg.AccountId,
|
||||||
|
"client_type": afg.ClientType,
|
||||||
|
"conn_type": afg.ConnType,
|
||||||
|
"created_by": afg.CreatedBy,
|
||||||
|
"created_time": afg.CreatedTime,
|
||||||
|
"default_gw": afg.DefaultGW,
|
||||||
|
"deleted_by": afg.DeletedBy,
|
||||||
|
"deleted_time": afg.DeletedTime,
|
||||||
|
"desc": afg.Desc,
|
||||||
|
"gid": afg.GID,
|
||||||
|
"guid": afg.GUID,
|
||||||
|
"fg_id": afg.ID,
|
||||||
|
"ip": afg.IP,
|
||||||
|
"milestones": afg.Milestones,
|
||||||
|
"fg_name": afg.Name,
|
||||||
|
"net_id": afg.NetID,
|
||||||
|
"net_type": afg.NetType,
|
||||||
|
"netmask": afg.NetMask,
|
||||||
|
"status": afg.Status,
|
||||||
|
"updated_by": afg.UpdatedBy,
|
||||||
|
"updated_time": afg.UpdatedTime,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountFlipGroupsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
accountFlipGroupsList, err := utilityAccountFlipGroupsListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenAccountFlipGroupsList(accountFlipGroupsList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountFlipGroupsListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "ID of the account",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Search Result",
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceAccountFlipGroupSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccountFlipGroupsList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountFlipGroupsListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountFlipGroupsListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/flattens"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenRgAcl(rgAcls []AccountAclRecord) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, rgAcl := range rgAcls {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"explicit": rgAcl.IsExplicit,
|
||||||
|
"guid": rgAcl.Guid,
|
||||||
|
"right": rgAcl.Rights,
|
||||||
|
"status": rgAcl.Status,
|
||||||
|
"type": rgAcl.Type,
|
||||||
|
"user_group_id": rgAcl.UgroupID,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenAccountList(al AccountList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, acc := range al {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"dc_location": acc.DCLocation,
|
||||||
|
"ckey": acc.CKey,
|
||||||
|
"meta": flattens.FlattenMeta(acc.Meta),
|
||||||
|
|
||||||
|
"acl": flattenRgAcl(acc.Acl),
|
||||||
|
|
||||||
|
"company": acc.Company,
|
||||||
|
"companyurl": acc.CompanyUrl,
|
||||||
|
"created_by": acc.CreatedBy,
|
||||||
|
|
||||||
|
"created_time": acc.CreatedTime,
|
||||||
|
|
||||||
|
"deactivation_time": acc.DeactiovationTime,
|
||||||
|
"deleted_by": acc.DeletedBy,
|
||||||
|
|
||||||
|
"deleted_time": acc.DeletedTime,
|
||||||
|
|
||||||
|
"displayname": acc.DisplayName,
|
||||||
|
"guid": acc.GUID,
|
||||||
|
|
||||||
|
"account_id": acc.ID,
|
||||||
|
"account_name": acc.Name,
|
||||||
|
|
||||||
|
"resource_limits": flattenRgResourceLimits(acc.ResourceLimits),
|
||||||
|
"send_access_emails": acc.SendAccessEmails,
|
||||||
|
"service_account": acc.ServiceAccount,
|
||||||
|
|
||||||
|
"status": acc.Status,
|
||||||
|
"updated_time": acc.UpdatedTime,
|
||||||
|
|
||||||
|
"version": acc.Version,
|
||||||
|
"vins": acc.Vins,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"cu_c": rl.CUC,
|
||||||
|
"cu_d": rl.CUD,
|
||||||
|
"cu_i": rl.CUI,
|
||||||
|
"cu_m": rl.CUM,
|
||||||
|
"cu_np": rl.CUNP,
|
||||||
|
"gpu_units": rl.GpuUnits,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
accountList, err := utilityAccountListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenAccountList(accountList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"page": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Page number",
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Page size",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceAccountItemSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccountList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenAccountRGList(argl AccountRGList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, arg := range argl {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"computes": flattenAccRGComputes(arg.Computes),
|
||||||
|
"resources": flattenAccRGResources(arg.Resources),
|
||||||
|
"created_by": arg.CreatedBy,
|
||||||
|
"created_time": arg.CreatedTime,
|
||||||
|
"deleted_by": arg.DeletedBy,
|
||||||
|
"deleted_time": arg.DeletedTime,
|
||||||
|
"rg_id": arg.RGID,
|
||||||
|
"milestones": arg.Milestones,
|
||||||
|
"rg_name": arg.RGName,
|
||||||
|
"status": arg.Status,
|
||||||
|
"updated_by": arg.UpdatedBy,
|
||||||
|
"updated_time": arg.UpdatedTime,
|
||||||
|
"vinses": arg.Vinses,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenAccRGComputes(argc AccountRGComputes) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"started": argc.Started,
|
||||||
|
"stopped": argc.Stopped,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenAccRGResources(argr AccountRGResources) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"consumed": flattenAccResource(argr.Consumed),
|
||||||
|
"limits": flattenAccResource(argr.Limits),
|
||||||
|
"reserved": flattenAccResource(argr.Reserved),
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenAccResources(r Resources) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"current": flattenAccResource(r.Current),
|
||||||
|
"reserved": flattenAccResource(r.Reserved),
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenAccResource(r Resource) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"cpu": r.CPU,
|
||||||
|
"disksize": r.Disksize,
|
||||||
|
"extips": r.Extips,
|
||||||
|
"exttraffic": r.Exttraffic,
|
||||||
|
"gpu": r.GPU,
|
||||||
|
"ram": r.RAM,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountRGListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
accountRGList, err := utilityAccountRGListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenAccountRGList(accountRGList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountRGListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "ID of the account",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Search Result",
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceAccountRGSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccountRGList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountRGListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountRGListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenAccountVinsList(avl AccountVinsList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, av := range avl {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"account_id": av.AccountId,
|
||||||
|
"account_name": av.AccountName,
|
||||||
|
"computes": av.Computes,
|
||||||
|
"created_by": av.CreatedBy,
|
||||||
|
"created_time": av.CreatedTime,
|
||||||
|
"deleted_by": av.DeletedBy,
|
||||||
|
"deleted_time": av.DeletedTime,
|
||||||
|
"external_ip": av.ExternalIP,
|
||||||
|
"vin_id": av.ID,
|
||||||
|
"vin_name": av.Name,
|
||||||
|
"network": av.Network,
|
||||||
|
"pri_vnf_dev_id": av.PriVnfDevId,
|
||||||
|
"rg_id": av.RgId,
|
||||||
|
"rg_name": av.RgName,
|
||||||
|
"status": av.Status,
|
||||||
|
"updated_by": av.UpdatedBy,
|
||||||
|
"updated_time": av.UpdatedTime,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountVinsListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
accountVinsList, err := utilityAccountVinsListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenAccountVinsList(accountVinsList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAccountVinsListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "ID of the account",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Search Result",
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceAccountVinsSchema(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceAccountVinsList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceAccountVinsListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceAccountVinsListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
type AccountAclRecord struct {
|
||||||
|
IsExplicit bool `json:"explicit"`
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Rights string `json:"right"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
UgroupID string `json:"userGroupId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResourceLimits struct {
|
||||||
|
CUC float64 `json:"CU_C"`
|
||||||
|
CUD float64 `json:"CU_D"`
|
||||||
|
CUI float64 `json:"CU_I"`
|
||||||
|
CUM float64 `json:"CU_M"`
|
||||||
|
CUNP float64 `json:"CU_NP"`
|
||||||
|
GpuUnits float64 `json:"gpu_units"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Account struct {
|
||||||
|
DCLocation string `json:"DCLocation"`
|
||||||
|
CKey string `jspn:"_ckey"`
|
||||||
|
Meta []interface{} `json:"_meta"`
|
||||||
|
Acl []AccountAclRecord `json:"acl"`
|
||||||
|
Company string `json:"company"`
|
||||||
|
CompanyUrl string `json:"companyurl"`
|
||||||
|
CreatedBy string `jspn:"createdBy"`
|
||||||
|
CreatedTime int `json:"createdTime"`
|
||||||
|
DeactiovationTime float64 `json:"deactivationTime"`
|
||||||
|
DeletedBy string `json:"deletedBy"`
|
||||||
|
DeletedTime int `json:"deletedTime"`
|
||||||
|
DisplayName string `json:"displayname"`
|
||||||
|
GUID int `json:"guid"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ResourceLimits ResourceLimits `json:"resourceLimits"`
|
||||||
|
SendAccessEmails bool `json:"sendAccessEmails"`
|
||||||
|
ServiceAccount bool `json:"serviceAccount"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
UpdatedTime int `json:"updatedTime"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
Vins []int `json:"vins"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountList []Account
|
||||||
|
|
||||||
|
type Resource struct {
|
||||||
|
CPU int `json:"cpu"`
|
||||||
|
Disksize int `json:"disksize"`
|
||||||
|
Extips int `json:"extips"`
|
||||||
|
Exttraffic int `json:"exttraffic"`
|
||||||
|
GPU int `json:"gpu"`
|
||||||
|
RAM int `json:"ram"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Resources struct {
|
||||||
|
Current Resource `json:"Current"`
|
||||||
|
Reserved Resource `json:"Reserved"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountWithResources struct {
|
||||||
|
Account
|
||||||
|
Resources Resources `json:"Resources"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountCompute struct {
|
||||||
|
AccountId int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
CPUs int `json:"cpus"`
|
||||||
|
CreatedBy string `json:"createdBy"`
|
||||||
|
CreatedTime int `json:"createdTime"`
|
||||||
|
DeletedBy string `json:"deletedBy"`
|
||||||
|
DeletedTime int `json:"deletedTime"`
|
||||||
|
ComputeId int `json:"id"`
|
||||||
|
ComputeName string `json:"name"`
|
||||||
|
RAM int `json:"ram"`
|
||||||
|
Registered bool `json:"registered"`
|
||||||
|
RgId int `json:"rgId"`
|
||||||
|
RgName string `json:"rgName"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
TechStatus string `json:"techStatus"`
|
||||||
|
TotalDisksSize int `json:"totalDisksSize"`
|
||||||
|
UpdatedBy string `json:"updatedBy"`
|
||||||
|
UpdatedTime int `json:"updatedTime"`
|
||||||
|
UserManaged bool `json:"userManaged"`
|
||||||
|
VinsConnected int `json:"vinsConnected"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountComputesList []AccountCompute
|
||||||
|
|
||||||
|
type AccountDisk struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Pool string `json:"pool"`
|
||||||
|
SepId int `json:"sepId"`
|
||||||
|
SizeMax int `json:"sizeMax"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountDisksList []AccountDisk
|
||||||
|
|
||||||
|
type AccountVin struct {
|
||||||
|
AccountId int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
Computes int `json:"computes"`
|
||||||
|
CreatedBy string `json:"createdBy"`
|
||||||
|
CreatedTime int `json:"createdTime"`
|
||||||
|
DeletedBy string `json:"deletedBy"`
|
||||||
|
DeletedTime int `json:"deletedTime"`
|
||||||
|
ExternalIP string `json:"externalIP"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Network string `json:"network"`
|
||||||
|
PriVnfDevId int `json:"priVnfDevId"`
|
||||||
|
RgId int `json:"rgId"`
|
||||||
|
RgName string `json:"rgName"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
UpdatedBy string `json:"updatedBy"`
|
||||||
|
UpdatedTime int `json:"updatedTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountVinsList []AccountVin
|
||||||
|
|
||||||
|
type AccountAudit struct {
|
||||||
|
Call string `json:"call"`
|
||||||
|
ResponseTime float64 `json:"responsetime"`
|
||||||
|
StatusCode int `json:"statuscode"`
|
||||||
|
Timestamp float64 `json:"timestamp"`
|
||||||
|
User string `json:"user"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountAuditsList []AccountAudit
|
||||||
|
|
||||||
|
type AccountRGComputes struct {
|
||||||
|
Started int `json:"Started"`
|
||||||
|
Stopped int `json:"Stopped"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountRGResources struct {
|
||||||
|
Consumed Resource `json:"Consumed"`
|
||||||
|
Limits Resource `json:"Limits"`
|
||||||
|
Reserved Resource `json:"Reserved"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountRG struct {
|
||||||
|
Computes AccountRGComputes `json:"Computes"`
|
||||||
|
Resources AccountRGResources `json:"Resources"`
|
||||||
|
CreatedBy string `json:"createdBy"`
|
||||||
|
CreatedTime int `json:"createdTime"`
|
||||||
|
DeletedBy string `json:"deletedBy"`
|
||||||
|
DeletedTime int `json:"deletedTime"`
|
||||||
|
RGID int `json:"id"`
|
||||||
|
Milestones int `json:"milestones"`
|
||||||
|
RGName string `json:"name"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
UpdatedBy string `json:"updatedBy"`
|
||||||
|
UpdatedTime int `json:"updatedTime"`
|
||||||
|
Vinses int `json:"vinses"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountRGList []AccountRG
|
||||||
|
|
||||||
|
type AccountFlipGroup struct {
|
||||||
|
AccountId int `json:"accountId"`
|
||||||
|
ClientType string `json:"clientType"`
|
||||||
|
ConnType string `json:"connType"`
|
||||||
|
CreatedBy string `json:"createdBy"`
|
||||||
|
CreatedTime int `json:"createdTime"`
|
||||||
|
DefaultGW string `json:"defaultGW"`
|
||||||
|
DeletedBy string `json:"deletedBy"`
|
||||||
|
DeletedTime int `json:"deletedTime"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
GID int `json:"gid"`
|
||||||
|
GUID int `json:"guid"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
IP string `json:"ip"`
|
||||||
|
Milestones int `json:"milestones"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
NetID int `json:"netId"`
|
||||||
|
NetType string `json:"netType"`
|
||||||
|
NetMask int `json:"netmask"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
UpdatedBy string `json:"updatedBy"`
|
||||||
|
UpdatedTime int `json:"updatedTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountFlipGroupsList []AccountFlipGroup
|
@ -0,0 +1,485 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/flattens"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceAccountCreate")
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("name", d.Get("account_name").(string))
|
||||||
|
urlValues.Add("username", d.Get("username").(string))
|
||||||
|
|
||||||
|
if emailaddress, ok := d.GetOk("emailaddress"); ok {
|
||||||
|
urlValues.Add("emailaddress", emailaddress.(string))
|
||||||
|
}
|
||||||
|
if sendAccessEmails, ok := d.GetOk("send_access_emails"); ok {
|
||||||
|
urlValues.Add("sendAccessEmails", strconv.FormatBool(sendAccessEmails.(bool)))
|
||||||
|
}
|
||||||
|
if resLimits, ok := d.GetOk("resource_limits"); ok {
|
||||||
|
resLimit := resLimits.([]interface{})[0]
|
||||||
|
resLimitConv := resLimit.(map[string]interface{})
|
||||||
|
if resLimitConv["cu_m"] != nil {
|
||||||
|
maxMemCap := int(resLimitConv["cu_m"].(float64))
|
||||||
|
if maxMemCap == 0 {
|
||||||
|
urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resLimitConv["cu_d"] != nil {
|
||||||
|
maxDiskCap := int(resLimitConv["cu_d"].(float64))
|
||||||
|
if maxDiskCap == 0 {
|
||||||
|
urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resLimitConv["cu_c"] != nil {
|
||||||
|
maxCPUCap := int(resLimitConv["cu_c"].(float64))
|
||||||
|
if maxCPUCap == 0 {
|
||||||
|
urlValues.Add("maxCPUCapacity", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if resLimitConv["cu_i"] != nil {
|
||||||
|
maxNumPublicIP := int(resLimitConv["cu_i"].(float64))
|
||||||
|
if maxNumPublicIP == 0 {
|
||||||
|
urlValues.Add("maxNumPublicIP", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if resLimitConv["cu_np"] != nil {
|
||||||
|
maxNP := int(resLimitConv["cu_np"].(float64))
|
||||||
|
if maxNP == 0 {
|
||||||
|
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if resLimitConv["gpu_units"] != nil {
|
||||||
|
gpuUnits := int(resLimitConv["gpu_units"].(float64))
|
||||||
|
if gpuUnits == 0 {
|
||||||
|
urlValues.Add("gpu_units", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("gpu_units", strconv.Itoa(gpuUnits))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
accountId, err := c.DecortAPICall(ctx, "POST", accountCreateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(accountId)
|
||||||
|
d.Set("account_id", accountId)
|
||||||
|
|
||||||
|
diagnostics := resourceAccountRead(ctx, d, m)
|
||||||
|
if diagnostics != nil {
|
||||||
|
return diagnostics
|
||||||
|
}
|
||||||
|
|
||||||
|
if enable, ok := d.GetOk("enable"); ok {
|
||||||
|
api := accountDisableAPI
|
||||||
|
enable := enable.(bool)
|
||||||
|
if enable {
|
||||||
|
api = accountEnableAPI
|
||||||
|
}
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if users, ok := d.GetOk("users"); ok {
|
||||||
|
addedUsers := users.([]interface{})
|
||||||
|
|
||||||
|
if len(addedUsers) > 0 {
|
||||||
|
for _, user := range addedUsers {
|
||||||
|
userConv := user.(map[string]interface{})
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
urlValues.Add("userId", userConv["user_id"].(string))
|
||||||
|
urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", accountAddUserAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceAccountRead")
|
||||||
|
|
||||||
|
acc, err := utilityAccountCheckPresence(ctx, d, m)
|
||||||
|
if acc == nil {
|
||||||
|
d.SetId("")
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("dc_location", acc.DCLocation)
|
||||||
|
d.Set("resources", flattenAccResources(acc.Resources))
|
||||||
|
d.Set("ckey", acc.CKey)
|
||||||
|
d.Set("meta", flattens.FlattenMeta(acc.Meta))
|
||||||
|
d.Set("acl", flattenAccAcl(acc.Acl))
|
||||||
|
d.Set("company", acc.Company)
|
||||||
|
d.Set("companyurl", acc.CompanyUrl)
|
||||||
|
d.Set("created_by", acc.CreatedBy)
|
||||||
|
d.Set("created_time", acc.CreatedTime)
|
||||||
|
d.Set("deactivation_time", acc.DeactiovationTime)
|
||||||
|
d.Set("deleted_by", acc.DeletedBy)
|
||||||
|
d.Set("deleted_time", acc.DeletedTime)
|
||||||
|
d.Set("displayname", acc.DisplayName)
|
||||||
|
d.Set("guid", acc.GUID)
|
||||||
|
d.Set("account_id", acc.ID)
|
||||||
|
d.Set("account_name", acc.Name)
|
||||||
|
d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits))
|
||||||
|
d.Set("send_access_emails", acc.SendAccessEmails)
|
||||||
|
d.Set("service_account", acc.ServiceAccount)
|
||||||
|
d.Set("status", acc.Status)
|
||||||
|
d.Set("updated_time", acc.UpdatedTime)
|
||||||
|
d.Set("version", acc.Version)
|
||||||
|
d.Set("vins", acc.Vins)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceAccountDelete")
|
||||||
|
|
||||||
|
account, err := utilityAccountCheckPresence(ctx, d, m)
|
||||||
|
if account == nil {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
|
||||||
|
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", accountDeleteAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAccountExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
log.Debugf("resourceAccountExists")
|
||||||
|
|
||||||
|
account, err := utilityAccountCheckPresence(ctx, d, m)
|
||||||
|
if account == nil {
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAccountEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceAccountEdit")
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
if d.HasChange("enable") {
|
||||||
|
api := accountDisableAPI
|
||||||
|
enable := d.Get("enable").(bool)
|
||||||
|
if enable {
|
||||||
|
api = accountEnableAPI
|
||||||
|
}
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", api, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("account_name") {
|
||||||
|
urlValues.Add("name", d.Get("account_name").(string))
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
if d.HasChange("resource_limits") {
|
||||||
|
resLimit := d.Get("resource_limits").([]interface{})[0]
|
||||||
|
resLimitConv := resLimit.(map[string]interface{})
|
||||||
|
|
||||||
|
if resLimitConv["cu_m"] != nil {
|
||||||
|
maxMemCap := int(resLimitConv["cu_m"].(float64))
|
||||||
|
if maxMemCap == 0 {
|
||||||
|
urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resLimitConv["cu_d"] != nil {
|
||||||
|
maxDiskCap := int(resLimitConv["cu_d"].(float64))
|
||||||
|
if maxDiskCap == 0 {
|
||||||
|
urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if resLimitConv["cu_c"] != nil {
|
||||||
|
maxCPUCap := int(resLimitConv["cu_c"].(float64))
|
||||||
|
if maxCPUCap == 0 {
|
||||||
|
urlValues.Add("maxCPUCapacity", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if resLimitConv["cu_i"] != nil {
|
||||||
|
maxNumPublicIP := int(resLimitConv["cu_i"].(float64))
|
||||||
|
if maxNumPublicIP == 0 {
|
||||||
|
urlValues.Add("maxNumPublicIP", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if resLimitConv["cu_np"] != nil {
|
||||||
|
maxNP := int(resLimitConv["cu_np"].(float64))
|
||||||
|
if maxNP == 0 {
|
||||||
|
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if resLimitConv["gpu_units"] != nil {
|
||||||
|
gpuUnits := int(resLimitConv["gpu_units"].(float64))
|
||||||
|
if gpuUnits == 0 {
|
||||||
|
urlValues.Add("gpu_units", strconv.Itoa(-1))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("gpu_units", strconv.Itoa(gpuUnits))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("send_access_emails") {
|
||||||
|
urlValues.Add("sendAccessEmails", strconv.FormatBool(d.Get("send_access_emails").(bool)))
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", accountUpdateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("restore") {
|
||||||
|
restore := d.Get("restore").(bool)
|
||||||
|
if restore {
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", accountRestoreAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("users") {
|
||||||
|
deletedUsers := make([]interface{}, 0)
|
||||||
|
addedUsers := make([]interface{}, 0)
|
||||||
|
updatedUsers := make([]interface{}, 0)
|
||||||
|
|
||||||
|
old, new := d.GetChange("users")
|
||||||
|
oldConv := old.([]interface{})
|
||||||
|
newConv := new.([]interface{})
|
||||||
|
for _, el := range oldConv {
|
||||||
|
if !isContainsUser(newConv, el) {
|
||||||
|
deletedUsers = append(deletedUsers, el)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, el := range newConv {
|
||||||
|
if !isContainsUser(oldConv, el) {
|
||||||
|
addedUsers = append(addedUsers, el)
|
||||||
|
} else {
|
||||||
|
if isChangedUser(oldConv, el) {
|
||||||
|
updatedUsers = append(updatedUsers, el)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(deletedUsers) > 0 {
|
||||||
|
for _, user := range deletedUsers {
|
||||||
|
userConv := user.(map[string]interface{})
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
urlValues.Add("userId", userConv["user_id"].(string))
|
||||||
|
urlValues.Add("recursivedelete", strconv.FormatBool(userConv["recursive_delete"].(bool)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", accountDeleteUserAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(addedUsers) > 0 {
|
||||||
|
for _, user := range addedUsers {
|
||||||
|
userConv := user.(map[string]interface{})
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
urlValues.Add("userId", userConv["user_id"].(string))
|
||||||
|
urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", accountAddUserAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(updatedUsers) > 0 {
|
||||||
|
for _, user := range updatedUsers {
|
||||||
|
userConv := user.(map[string]interface{})
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
urlValues.Add("userId", userConv["user_id"].(string))
|
||||||
|
urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", accountUpdateUserAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isContainsUser(els []interface{}, el interface{}) bool {
|
||||||
|
for _, elOld := range els {
|
||||||
|
elOldConv := elOld.(map[string]interface{})
|
||||||
|
elConv := el.(map[string]interface{})
|
||||||
|
if elOldConv["user_id"].(string) == elConv["user_id"].(string) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isChangedUser(els []interface{}, el interface{}) bool {
|
||||||
|
for _, elOld := range els {
|
||||||
|
elOldConv := elOld.(map[string]interface{})
|
||||||
|
elConv := el.(map[string]interface{})
|
||||||
|
if elOldConv["user_id"].(string) == elConv["user_id"].(string) &&
|
||||||
|
(!strings.EqualFold(elOldConv["access_type"].(string), elConv["access_type"].(string)) ||
|
||||||
|
elOldConv["recursive_delete"].(bool) != elConv["recursive_delete"].(bool)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceAccount() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceAccountCreate,
|
||||||
|
ReadContext: resourceAccountRead,
|
||||||
|
UpdateContext: resourceAccountEdit,
|
||||||
|
DeleteContext: resourceAccountDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout60s,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout60s,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: resourceAccountSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*AccountWithResources, error) {
|
||||||
|
account := &AccountWithResources{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
if (strconv.Itoa(d.Get("account_id").(int))) != "0" {
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("accountId", d.Id())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountCheckPresence: load account")
|
||||||
|
accountRaw, err := c.DecortAPICall(ctx, "POST", accountGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountRaw), &account)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return account, nil
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountAuditsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountAuditsList, error) {
|
||||||
|
accountAuditsList := AccountAuditsList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountAuditsListCheckPresence: load account list")
|
||||||
|
accountAuditsListRaw, err := c.DecortAPICall(ctx, "POST", accountAuditsAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountAuditsListRaw), &accountAuditsList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountAuditsList, nil
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountComputesListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountComputesList, error) {
|
||||||
|
accountComputesList := AccountComputesList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountComputesListCheckPresence: load account list")
|
||||||
|
accountComputesListRaw, err := c.DecortAPICall(ctx, "POST", accountListComputesAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountComputesListRaw), &accountComputesList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountComputesList, nil
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountDeletedListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountList, error) {
|
||||||
|
accountDeletedList := AccountList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
if page, ok := d.GetOk("page"); ok {
|
||||||
|
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||||
|
}
|
||||||
|
if size, ok := d.GetOk("size"); ok {
|
||||||
|
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountDeletedListCheckPresence: load")
|
||||||
|
accountDeletedListRaw, err := c.DecortAPICall(ctx, "POST", accountListDeletedAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountDeletedListRaw), &accountDeletedList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountDeletedList, nil
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountDisksListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountDisksList, error) {
|
||||||
|
accountDisksList := AccountDisksList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountDisksListCheckPresence: load account list")
|
||||||
|
accountDisksListRaw, err := c.DecortAPICall(ctx, "POST", accountListDisksAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountDisksListRaw), &accountDisksList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountDisksList, nil
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountFlipGroupsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountFlipGroupsList, error) {
|
||||||
|
accountFlipGroupsList := AccountFlipGroupsList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountFlipGroupsListCheckPresence")
|
||||||
|
accountFlipGroupsListRaw, err := c.DecortAPICall(ctx, "POST", accountListFlipGroupsAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountFlipGroupsListRaw), &accountFlipGroupsList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountFlipGroupsList, nil
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountList, error) {
|
||||||
|
accountList := AccountList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
if page, ok := d.GetOk("page"); ok {
|
||||||
|
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||||
|
}
|
||||||
|
if size, ok := d.GetOk("size"); ok {
|
||||||
|
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountListCheckPresence: load account list")
|
||||||
|
accountListRaw, err := c.DecortAPICall(ctx, "POST", accountListAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountListRaw), &accountList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountList, nil
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountRGListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountRGList, error) {
|
||||||
|
accountRGList := AccountRGList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountRGListCheckPresence: load account list")
|
||||||
|
accountRGListRaw, err := c.DecortAPICall(ctx, "POST", accountListRGAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountRGListRaw), &accountRGList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountRGList, nil
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package account
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityAccountVinsListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (AccountVinsList, error) {
|
||||||
|
accountVinsList := AccountVinsList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||||
|
|
||||||
|
log.Debugf("utilityAccountVinsListCheckPresence: load account list")
|
||||||
|
accountVinsListRaw, err := c.DecortAPICall(ctx, "POST", accountListVinsAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(accountVinsListRaw), &accountVinsList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountVinsList, nil
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package disks
|
||||||
|
|
||||||
|
const disksCreateAPI = "/restmachine/cloudbroker/disks/create"
|
||||||
|
const disksGetAPI = "/restmachine/cloudbroker/disks/get"
|
||||||
|
const disksListAPI = "/restmachine/cloudbroker/disks/list"
|
||||||
|
const disksResizeAPI = "/restmachine/cloudbroker/disks/resize2"
|
||||||
|
const disksRenameAPI = "/restmachine/cloudbroker/disks/rename"
|
||||||
|
const disksDeleteAPI = "/restmachine/cloudbroker/disks/delete"
|
||||||
|
const disksIOLimitAPI = "/restmachine/cloudbroker/disks/limitIO"
|
||||||
|
const disksRestoreAPI = "/restmachine/cloudbroker/disks/restore"
|
@ -0,0 +1,389 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package disks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
// "net/url"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
disk, err := utilityDiskCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
|
||||||
|
diskAcl, _ := json.Marshal(disk.Acl)
|
||||||
|
|
||||||
|
d.Set("account_id", disk.AccountID)
|
||||||
|
d.Set("account_name", disk.AccountName)
|
||||||
|
d.Set("acl", string(diskAcl))
|
||||||
|
d.Set("boot_partition", disk.BootPartition)
|
||||||
|
d.Set("compute_id", disk.ComputeID)
|
||||||
|
d.Set("compute_name", disk.ComputeName)
|
||||||
|
d.Set("created_time", disk.CreatedTime)
|
||||||
|
d.Set("deleted_time", disk.DeletedTime)
|
||||||
|
d.Set("desc", disk.Desc)
|
||||||
|
d.Set("destruction_time", disk.DestructionTime)
|
||||||
|
d.Set("devicename", disk.DeviceName)
|
||||||
|
d.Set("disk_path", disk.DiskPath)
|
||||||
|
d.Set("gid", disk.GridID)
|
||||||
|
d.Set("guid", disk.GUID)
|
||||||
|
d.Set("disk_id", disk.ID)
|
||||||
|
d.Set("image_id", disk.ImageID)
|
||||||
|
d.Set("images", disk.Images)
|
||||||
|
d.Set("iotune", flattenIOTune(disk.IOTune))
|
||||||
|
d.Set("iqn", disk.IQN)
|
||||||
|
d.Set("login", disk.Login)
|
||||||
|
d.Set("milestones", disk.Milestones)
|
||||||
|
d.Set("disk_name", disk.Name)
|
||||||
|
d.Set("order", disk.Order)
|
||||||
|
d.Set("params", disk.Params)
|
||||||
|
d.Set("parent_id", disk.ParentId)
|
||||||
|
d.Set("passwd", disk.Passwd)
|
||||||
|
d.Set("pci_slot", disk.PciSlot)
|
||||||
|
d.Set("pool", disk.Pool)
|
||||||
|
d.Set("purge_attempts", disk.PurgeAttempts)
|
||||||
|
d.Set("purge_time", disk.PurgeTime)
|
||||||
|
d.Set("reality_device_number", disk.RealityDeviceNumber)
|
||||||
|
d.Set("reference_id", disk.ReferenceId)
|
||||||
|
d.Set("res_id", disk.ResID)
|
||||||
|
d.Set("res_name", disk.ResName)
|
||||||
|
d.Set("role", disk.Role)
|
||||||
|
d.Set("sep_id", disk.SepID)
|
||||||
|
d.Set("sep_type", disk.SepType)
|
||||||
|
d.Set("size_max", disk.SizeMax)
|
||||||
|
d.Set("size_used", disk.SizeUsed)
|
||||||
|
d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots))
|
||||||
|
d.Set("status", disk.Status)
|
||||||
|
d.Set("tech_status", disk.TechStatus)
|
||||||
|
d.Set("type", disk.Type)
|
||||||
|
d.Set("vmid", disk.VMID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceDiskSchemaMake() map[string]*schema.Schema {
|
||||||
|
rets := map[string]*schema.Schema{
|
||||||
|
"disk_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"acl": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"boot_partition": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"desc": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"destruction_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"devicename": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disk_path": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"image_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"images": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iotune": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"read_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iqn": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"milestones": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disk_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"parent_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"passwd": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"pci_slot": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"pool": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"purge_attempts": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"purge_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"reality_device_number": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"reference_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"sep_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"sep_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_used": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snapshots": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snap_set_guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snap_set_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"tech_status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vmid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceDisk() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceDiskRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceDiskSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,473 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package disks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenIOTune(iot IOTune) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"read_bytes_sec": iot.ReadBytesSec,
|
||||||
|
"read_bytes_sec_max": iot.ReadBytesSecMax,
|
||||||
|
"read_iops_sec": iot.ReadIopsSec,
|
||||||
|
"read_iops_sec_max": iot.ReadIopsSecMax,
|
||||||
|
"size_iops_sec": iot.SizeIopsSec,
|
||||||
|
"total_bytes_sec": iot.TotalBytesSec,
|
||||||
|
"total_bytes_sec_max": iot.TotalBytesSecMax,
|
||||||
|
"total_iops_sec": iot.TotalIopsSec,
|
||||||
|
"total_iops_sec_max": iot.TotalIopsSecMax,
|
||||||
|
"write_bytes_sec": iot.WriteBytesSec,
|
||||||
|
"write_bytes_sec_max": iot.WriteBytesSecMax,
|
||||||
|
"write_iops_sec": iot.WriteIopsSec,
|
||||||
|
"write_iops_sec_max": iot.WriteIopsSecMax,
|
||||||
|
}
|
||||||
|
|
||||||
|
res = append(res, temp)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenDiskList(dl DisksList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, disk := range dl {
|
||||||
|
diskAcl, _ := json.Marshal(disk.Acl)
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"account_id": disk.AccountID,
|
||||||
|
"account_name": disk.AccountName,
|
||||||
|
"acl": string(diskAcl),
|
||||||
|
"boot_partition": disk.BootPartition,
|
||||||
|
"compute_id": disk.ComputeID,
|
||||||
|
"compute_name": disk.ComputeName,
|
||||||
|
"created_time": disk.CreatedTime,
|
||||||
|
"deleted_time": disk.DeletedTime,
|
||||||
|
"desc": disk.Desc,
|
||||||
|
"destruction_time": disk.DestructionTime,
|
||||||
|
"devicename": disk.DeviceName,
|
||||||
|
"disk_path": disk.DiskPath,
|
||||||
|
"gid": disk.GridID,
|
||||||
|
"guid": disk.GUID,
|
||||||
|
"disk_id": disk.ID,
|
||||||
|
"image_id": disk.ImageID,
|
||||||
|
"images": disk.Images,
|
||||||
|
"iotune": flattenIOTune(disk.IOTune),
|
||||||
|
"iqn": disk.IQN,
|
||||||
|
"login": disk.Login,
|
||||||
|
"machine_id": disk.MachineId,
|
||||||
|
"machine_name": disk.MachineName,
|
||||||
|
"milestones": disk.Milestones,
|
||||||
|
"disk_name": disk.Name,
|
||||||
|
"order": disk.Order,
|
||||||
|
"params": disk.Params,
|
||||||
|
"parent_id": disk.ParentId,
|
||||||
|
"passwd": disk.Passwd,
|
||||||
|
"pci_slot": disk.PciSlot,
|
||||||
|
"pool": disk.Pool,
|
||||||
|
"purge_attempts": disk.PurgeAttempts,
|
||||||
|
"purge_time": disk.PurgeTime,
|
||||||
|
"reality_device_number": disk.RealityDeviceNumber,
|
||||||
|
"reference_id": disk.ReferenceId,
|
||||||
|
"res_id": disk.ResID,
|
||||||
|
"res_name": disk.ResName,
|
||||||
|
"role": disk.Role,
|
||||||
|
"sep_id": disk.SepID,
|
||||||
|
"sep_type": disk.SepType,
|
||||||
|
"size_max": disk.SizeMax,
|
||||||
|
"size_used": disk.SizeUsed,
|
||||||
|
"snapshots": flattendDiskSnapshotList(disk.Snapshots),
|
||||||
|
"status": disk.Status,
|
||||||
|
"tech_status": disk.TechStatus,
|
||||||
|
"type": disk.Type,
|
||||||
|
"vmid": disk.VMID,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattendDiskSnapshotList(sl SnapshotList) []interface{} {
|
||||||
|
res := make([]interface{}, 0)
|
||||||
|
for _, snapshot := range sl {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"guid": snapshot.Guid,
|
||||||
|
"label": snapshot.Label,
|
||||||
|
"res_id": snapshot.ResId,
|
||||||
|
"snap_set_guid": snapshot.SnapSetGuid,
|
||||||
|
"snap_set_time": snapshot.SnapSetTime,
|
||||||
|
"timestamp": snapshot.TimeStamp,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceDiskListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
diskList, err := utilityDiskListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenDiskList(diskList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceDiskListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "ID of the account the disks belong to",
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "type of the disks",
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Page number",
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Page size",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"acl": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"boot_partition": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"desc": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"destruction_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"devicename": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disk_path": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disk_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"image_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"images": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iotune": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"read_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iqn": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"machine_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"machine_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"milestones": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disk_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"parent_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"passwd": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"pci_slot": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"pool": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"purge_attempts": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"purge_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"reality_device_number": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"reference_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"sep_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"sep_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_used": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snapshots": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snap_set_guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snap_set_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"tech_status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vmid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceDiskList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceDiskListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceDiskListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package disks
|
||||||
|
|
||||||
|
type Disk struct {
|
||||||
|
Acl map[string]interface{} `json:"acl"`
|
||||||
|
AccountID int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
BootPartition int `json:"bootPartition"`
|
||||||
|
CreatedTime uint64 `json:"creationTime"`
|
||||||
|
ComputeID int `json:"computeId"`
|
||||||
|
ComputeName string `json:"computeName"`
|
||||||
|
DeletedTime uint64 `json:"deletionTime"`
|
||||||
|
DeviceName string `json:"devicename"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
DestructionTime uint64 `json:"destructionTime"`
|
||||||
|
DiskPath string `json:"diskPath"`
|
||||||
|
GridID int `json:"gid"`
|
||||||
|
GUID int `json:"guid"`
|
||||||
|
ID uint `json:"id"`
|
||||||
|
ImageID int `json:"imageId"`
|
||||||
|
Images []int `json:"images"`
|
||||||
|
IOTune IOTune `json:"iotune"`
|
||||||
|
IQN string `json:"iqn"`
|
||||||
|
Login string `json:"login"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
MachineId int `json:"machineId"`
|
||||||
|
MachineName string `json:"machineName"`
|
||||||
|
Milestones uint64 `json:"milestones"`
|
||||||
|
Order int `json:"order"`
|
||||||
|
Params string `json:"params"`
|
||||||
|
Passwd string `json:"passwd"`
|
||||||
|
ParentId int `json:"parentId"`
|
||||||
|
PciSlot int `json:"pciSlot"`
|
||||||
|
Pool string `json:"pool"`
|
||||||
|
PurgeTime uint64 `json:"purgeTime"`
|
||||||
|
PurgeAttempts uint64 `json:"purgeAttempts"`
|
||||||
|
RealityDeviceNumber int `json:"realityDeviceNumber"`
|
||||||
|
ReferenceId string `json:"referenceId"`
|
||||||
|
ResID string `json:"resId"`
|
||||||
|
ResName string `json:"resName"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
SepType string `json:"sepType"`
|
||||||
|
SepID int `json:"sepId"` // NOTE: absent from compute/get output
|
||||||
|
SizeMax int `json:"sizeMax"`
|
||||||
|
SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space
|
||||||
|
Snapshots []Snapshot `json:"snapshots"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
TechStatus string `json:"techStatus"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
UpdateBy uint64 `json:"updateBy"`
|
||||||
|
VMID int `json:"vmid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Snapshot struct {
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
ResId string `json:"resId"`
|
||||||
|
SnapSetGuid string `json:"snapSetGuid"`
|
||||||
|
SnapSetTime uint64 `json:"snapSetTime"`
|
||||||
|
TimeStamp uint64 `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnapshotList []Snapshot
|
||||||
|
|
||||||
|
type DisksList []Disk
|
||||||
|
|
||||||
|
type IOTune struct {
|
||||||
|
ReadBytesSec int `json:"read_bytes_sec"`
|
||||||
|
ReadBytesSecMax int `json:"read_bytes_sec_max"`
|
||||||
|
ReadIopsSec int `json:"read_iops_sec"`
|
||||||
|
ReadIopsSecMax int `json:"read_iops_sec_max"`
|
||||||
|
SizeIopsSec int `json:"size_iops_sec"`
|
||||||
|
TotalBytesSec int `json:"total_bytes_sec"`
|
||||||
|
TotalBytesSecMax int `json:"total_bytes_sec_max"`
|
||||||
|
TotalIopsSec int `json:"total_iops_sec"`
|
||||||
|
TotalIopsSecMax int `json:"total_iops_sec_max"`
|
||||||
|
WriteBytesSec int `json:"write_bytes_sec"`
|
||||||
|
WriteBytesSecMax int `json:"write_bytes_sec_max"`
|
||||||
|
WriteIopsSec int `json:"write_iops_sec"`
|
||||||
|
WriteIopsSecMax int `json:"write_iops_sec_max"`
|
||||||
|
}
|
@ -0,0 +1,638 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package disks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceDiskCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
||||||
|
urlValues.Add("gid", fmt.Sprintf("%d", d.Get("gid").(int)))
|
||||||
|
urlValues.Add("name", d.Get("disk_name").(string))
|
||||||
|
urlValues.Add("size", fmt.Sprintf("%d", d.Get("size_max").(int)))
|
||||||
|
if typeRaw, ok := d.GetOk("type"); ok {
|
||||||
|
urlValues.Add("type", strings.ToUpper(typeRaw.(string)))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("type", "D")
|
||||||
|
}
|
||||||
|
|
||||||
|
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||||
|
urlValues.Add("sep_id", strconv.Itoa(sepId.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if poolName, ok := d.GetOk("pool"); ok {
|
||||||
|
urlValues.Add("pool", poolName.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
argVal, argSet := d.GetOk("desc")
|
||||||
|
if argSet {
|
||||||
|
urlValues.Add("description", argVal.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
diskId, err := c.DecortAPICall(ctx, "POST", disksCreateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
|
||||||
|
d.SetId(diskId) // update ID of the resource to tell Terraform that the disk resource exists
|
||||||
|
|
||||||
|
if iotuneRaw, ok := d.GetOk("iotune"); ok {
|
||||||
|
iot := iotuneRaw.([]interface{})[0]
|
||||||
|
iotune := iot.(map[string]interface{})
|
||||||
|
urlValues.Add("diskId", diskId)
|
||||||
|
urlValues.Add("iops", strconv.Itoa(iotune["total_iops_sec"].(int)))
|
||||||
|
urlValues.Add("read_bytes_sec", strconv.Itoa(iotune["read_bytes_sec"].(int)))
|
||||||
|
urlValues.Add("read_bytes_sec_max", strconv.Itoa(iotune["read_bytes_sec_max"].(int)))
|
||||||
|
urlValues.Add("read_iops_sec", strconv.Itoa(iotune["read_iops_sec"].(int)))
|
||||||
|
urlValues.Add("read_iops_sec_max", strconv.Itoa(iotune["read_iops_sec_max"].(int)))
|
||||||
|
urlValues.Add("size_iops_sec", strconv.Itoa(iotune["size_iops_sec"].(int)))
|
||||||
|
urlValues.Add("total_bytes_sec", strconv.Itoa(iotune["total_bytes_sec"].(int)))
|
||||||
|
urlValues.Add("total_bytes_sec_max", strconv.Itoa(iotune["total_bytes_sec_max"].(int)))
|
||||||
|
urlValues.Add("total_iops_sec_max", strconv.Itoa(iotune["total_iops_sec_max"].(int)))
|
||||||
|
urlValues.Add("write_bytes_sec", strconv.Itoa(iotune["write_bytes_sec"].(int)))
|
||||||
|
urlValues.Add("write_bytes_sec_max", strconv.Itoa(iotune["write_bytes_sec_max"].(int)))
|
||||||
|
urlValues.Add("write_iops_sec", strconv.Itoa(iotune["write_iops_sec"].(int)))
|
||||||
|
urlValues.Add("write_iops_sec_max", strconv.Itoa(iotune["write_iops_sec_max"].(int)))
|
||||||
|
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", disksIOLimitAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
dgn := resourceDiskRead(ctx, d, m)
|
||||||
|
if dgn != nil {
|
||||||
|
return dgn
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceDiskRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
disk, err := utilityDiskCheckPresence(ctx, d, m)
|
||||||
|
if disk == nil {
|
||||||
|
d.SetId("")
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
diskAcl, _ := json.Marshal(disk.Acl)
|
||||||
|
|
||||||
|
d.Set("account_id", disk.AccountID)
|
||||||
|
d.Set("account_name", disk.AccountName)
|
||||||
|
d.Set("acl", string(diskAcl))
|
||||||
|
d.Set("boot_partition", disk.BootPartition)
|
||||||
|
d.Set("compute_id", disk.ComputeID)
|
||||||
|
d.Set("compute_name", disk.ComputeName)
|
||||||
|
d.Set("created_time", disk.CreatedTime)
|
||||||
|
d.Set("deleted_time", disk.DeletedTime)
|
||||||
|
d.Set("desc", disk.Desc)
|
||||||
|
d.Set("destruction_time", disk.DestructionTime)
|
||||||
|
d.Set("devicename", disk.DeviceName)
|
||||||
|
d.Set("disk_path", disk.DiskPath)
|
||||||
|
d.Set("gid", disk.GridID)
|
||||||
|
d.Set("guid", disk.GUID)
|
||||||
|
d.Set("disk_id", disk.ID)
|
||||||
|
d.Set("image_id", disk.ImageID)
|
||||||
|
d.Set("images", disk.Images)
|
||||||
|
d.Set("iotune", flattenIOTune(disk.IOTune))
|
||||||
|
d.Set("iqn", disk.IQN)
|
||||||
|
d.Set("login", disk.Login)
|
||||||
|
d.Set("milestones", disk.Milestones)
|
||||||
|
d.Set("disk_name", disk.Name)
|
||||||
|
d.Set("order", disk.Order)
|
||||||
|
d.Set("params", disk.Params)
|
||||||
|
d.Set("parent_id", disk.ParentId)
|
||||||
|
d.Set("passwd", disk.Passwd)
|
||||||
|
d.Set("pci_slot", disk.PciSlot)
|
||||||
|
d.Set("pool", disk.Pool)
|
||||||
|
d.Set("purge_attempts", disk.PurgeAttempts)
|
||||||
|
d.Set("purge_time", disk.PurgeTime)
|
||||||
|
d.Set("reality_device_number", disk.RealityDeviceNumber)
|
||||||
|
d.Set("reference_id", disk.ReferenceId)
|
||||||
|
d.Set("res_id", disk.ResID)
|
||||||
|
d.Set("res_name", disk.ResName)
|
||||||
|
d.Set("role", disk.Role)
|
||||||
|
d.Set("sep_id", disk.SepID)
|
||||||
|
d.Set("sep_type", disk.SepType)
|
||||||
|
d.Set("size_max", disk.SizeMax)
|
||||||
|
d.Set("size_used", disk.SizeUsed)
|
||||||
|
d.Set("snapshots", flattendDiskSnapshotList(disk.Snapshots))
|
||||||
|
d.Set("status", disk.Status)
|
||||||
|
d.Set("tech_status", disk.TechStatus)
|
||||||
|
d.Set("type", disk.Type)
|
||||||
|
d.Set("vmid", disk.VMID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceDiskUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
if d.HasChange("size_max") {
|
||||||
|
oldSize, newSize := d.GetChange("size_max")
|
||||||
|
if oldSize.(int) < newSize.(int) {
|
||||||
|
log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB",
|
||||||
|
d.Id(), oldSize.(int), newSize.(int))
|
||||||
|
urlValues.Add("diskId", d.Id())
|
||||||
|
urlValues.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", disksResizeAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
d.Set("size_max", newSize)
|
||||||
|
} else if oldSize.(int) > newSize.(int) {
|
||||||
|
return diag.FromErr(fmt.Errorf("resourceDiskUpdate: Disk ID %s - reducing disk size is not allowed", d.Id()))
|
||||||
|
}
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("disk_name") {
|
||||||
|
urlValues.Add("diskId", d.Id())
|
||||||
|
urlValues.Add("name", d.Get("disk_name").(string))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", disksRenameAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("iotune") {
|
||||||
|
iot := d.Get("iotune").([]interface{})[0]
|
||||||
|
iotune := iot.(map[string]interface{})
|
||||||
|
urlValues.Add("diskId", d.Id())
|
||||||
|
urlValues.Add("iops", strconv.Itoa(iotune["total_iops_sec"].(int)))
|
||||||
|
urlValues.Add("read_bytes_sec", strconv.Itoa(iotune["read_bytes_sec"].(int)))
|
||||||
|
urlValues.Add("read_bytes_sec_max", strconv.Itoa(iotune["read_bytes_sec_max"].(int)))
|
||||||
|
urlValues.Add("read_iops_sec", strconv.Itoa(iotune["read_iops_sec"].(int)))
|
||||||
|
urlValues.Add("read_iops_sec_max", strconv.Itoa(iotune["read_iops_sec_max"].(int)))
|
||||||
|
urlValues.Add("size_iops_sec", strconv.Itoa(iotune["size_iops_sec"].(int)))
|
||||||
|
urlValues.Add("total_bytes_sec", strconv.Itoa(iotune["total_bytes_sec"].(int)))
|
||||||
|
urlValues.Add("total_bytes_sec_max", strconv.Itoa(iotune["total_bytes_sec_max"].(int)))
|
||||||
|
urlValues.Add("total_iops_sec_max", strconv.Itoa(iotune["total_iops_sec_max"].(int)))
|
||||||
|
urlValues.Add("write_bytes_sec", strconv.Itoa(iotune["write_bytes_sec"].(int)))
|
||||||
|
urlValues.Add("write_bytes_sec_max", strconv.Itoa(iotune["write_bytes_sec_max"].(int)))
|
||||||
|
urlValues.Add("write_iops_sec", strconv.Itoa(iotune["write_iops_sec"].(int)))
|
||||||
|
urlValues.Add("write_iops_sec_max", strconv.Itoa(iotune["write_iops_sec_max"].(int)))
|
||||||
|
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", disksIOLimitAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("restore") {
|
||||||
|
if d.Get("restore").(bool) {
|
||||||
|
urlValues.Add("diskId", d.Id())
|
||||||
|
urlValues.Add("reason", d.Get("reason").(string))
|
||||||
|
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", disksRestoreAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceDiskRead(ctx, d, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceDiskDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
|
||||||
|
disk, err := utilityDiskCheckPresence(ctx, d, m)
|
||||||
|
if disk == nil {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
params := &url.Values{}
|
||||||
|
params.Add("diskId", d.Id())
|
||||||
|
params.Add("detach", strconv.FormatBool(d.Get("detach").(bool)))
|
||||||
|
params.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
|
||||||
|
params.Add("reason", d.Get("reason").(string))
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", disksDeleteAPI, params)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceDiskExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
|
||||||
|
diskFacts, err := utilityDiskCheckPresence(ctx, d, m)
|
||||||
|
if diskFacts == nil {
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||||
|
rets := map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"disk_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"size_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"pool": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"sep_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"desc": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"D", "B", "T"}, false),
|
||||||
|
},
|
||||||
|
|
||||||
|
"detach": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "detach disk from machine first",
|
||||||
|
},
|
||||||
|
"permanently": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "whether to completely delete the disk, works only with non attached disks",
|
||||||
|
},
|
||||||
|
"reason": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Default: "",
|
||||||
|
Description: "reason for an action",
|
||||||
|
},
|
||||||
|
"restore": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "restore deleting disk",
|
||||||
|
},
|
||||||
|
|
||||||
|
"disk_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"acl": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"boot_partition": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"destruction_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"devicename": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disk_path": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"image_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"images": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iotune": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"read_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"read_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"total_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_bytes_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_bytes_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_iops_sec": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"write_iops_sec_max": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"iqn": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"milestones": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"order": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"parent_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"passwd": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"pci_slot": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"purge_attempts": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"purge_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"reality_device_number": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"reference_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"sep_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"size_used": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snapshots": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snap_set_guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"snap_set_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"tech_status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vmid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceDisk() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceDiskCreate,
|
||||||
|
ReadContext: resourceDiskRead,
|
||||||
|
UpdateContext: resourceDiskUpdate,
|
||||||
|
DeleteContext: resourceDiskDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout180s,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout180s,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: resourceDiskSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package disks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityDiskCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*Disk, error) {
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
disk := &Disk{}
|
||||||
|
|
||||||
|
if d.Get("disk_id").(int) == 0 {
|
||||||
|
urlValues.Add("diskId", d.Id())
|
||||||
|
} else {
|
||||||
|
urlValues.Add("diskId", strconv.Itoa(d.Get("disk_id").(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityDiskCheckPresence: load disk")
|
||||||
|
diskRaw, err := c.DecortAPICall(ctx, "POST", disksGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(diskRaw), disk)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return disk, nil
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package disks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityDiskListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (DisksList, error) {
|
||||||
|
diskList := DisksList{}
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
if page, ok := d.GetOk("page"); ok {
|
||||||
|
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||||
|
}
|
||||||
|
if size, ok := d.GetOk("size"); ok {
|
||||||
|
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||||
|
}
|
||||||
|
if diskType, ok := d.GetOk("type"); ok {
|
||||||
|
urlValues.Add("type", strings.ToUpper(diskType.(string)))
|
||||||
|
}
|
||||||
|
if accountId, ok := d.GetOk("accountId"); ok {
|
||||||
|
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityDiskListCheckPresence: load disk list")
|
||||||
|
diskListRaw, err := c.DecortAPICall(ctx, "POST", disksListAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(diskListRaw), &diskList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return diskList, nil
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
const K8sCreateAPI = "/restmachine/cloudbroker/k8s/create"
|
||||||
|
const K8sGetAPI = "/restmachine/cloudbroker/k8s/get"
|
||||||
|
const K8sUpdateAPI = "/restmachine/cloudbroker/k8s/update"
|
||||||
|
const K8sDeleteAPI = "/restmachine/cloudbroker/k8s/delete"
|
||||||
|
|
||||||
|
const K8sWgCreateAPI = "/restmachine/cloudbroker/k8s/workersGroupAdd"
|
||||||
|
const K8sWgDeleteAPI = "/restmachine/cloudbroker/k8s/workersGroupDelete"
|
||||||
|
|
||||||
|
const K8sWorkerAddAPI = "/restmachine/cloudbroker/k8s/workerAdd"
|
||||||
|
const K8sWorkerDeleteAPI = "/restmachine/cloudbroker/k8s/deleteWorkerFromGroup"
|
||||||
|
|
||||||
|
const K8sGetConfigAPI = "/restmachine/cloudbroker/k8s/getConfig"
|
||||||
|
|
||||||
|
const LbGetAPI = "/restmachine/cloudbroker/lb/get"
|
||||||
|
|
||||||
|
const AsyncTaskGetAPI = "/restmachine/cloudbroker/tasks/get"
|
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type K8sNodeRecord struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Disk int `json:"disk"`
|
||||||
|
Cpu int `json:"cpu"`
|
||||||
|
Num int `json:"num"`
|
||||||
|
Ram int `json:"ram"`
|
||||||
|
DetailedInfo []struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"detailedInfo"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//K8sRecord represents k8s instance
|
||||||
|
type K8sRecord struct {
|
||||||
|
AccountID int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
CI int `json:"ciId"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Groups struct {
|
||||||
|
Masters K8sNodeRecord `json:"masters"`
|
||||||
|
Workers []K8sNodeRecord `json:"workers"`
|
||||||
|
} `json:"k8sGroups"`
|
||||||
|
LbID int `json:"lbId"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
RgID int `json:"rgId"`
|
||||||
|
RgName string `json:"rgName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//LbRecord represents load balancer instance
|
||||||
|
type LbRecord struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
RgID int `json:"rgId"`
|
||||||
|
VinsID int `json:"vinsId"`
|
||||||
|
ExtNetID int `json:"extnetId"`
|
||||||
|
PrimaryNode struct {
|
||||||
|
BackendIP string `json:"backendIp"`
|
||||||
|
ComputeID int `json:"computeId"`
|
||||||
|
FrontendIP string `json:"frontendIp"`
|
||||||
|
NetworkID int `json:"networkId"`
|
||||||
|
} `json:"primaryNode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//Blasphemous workaround for parsing Result value
|
||||||
|
type TaskResult int
|
||||||
|
|
||||||
|
func (r *TaskResult) UnmarshalJSON(b []byte) error {
|
||||||
|
if b[0] == '"' {
|
||||||
|
b := b[1 : len(b)-1]
|
||||||
|
if len(b) == 0 {
|
||||||
|
*r = 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
n, err := strconv.Atoi(string(b))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*r = TaskResult(n)
|
||||||
|
} else if b[0] == '[' {
|
||||||
|
res := []interface{}{}
|
||||||
|
if err := json.Unmarshal(b, &res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if n, ok := res[0].(float64); ok {
|
||||||
|
*r = TaskResult(n)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("could not unmarshal %v into int", res[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//AsyncTask represents a long task completion status
|
||||||
|
type AsyncTask struct {
|
||||||
|
AuditID string `json:"auditId"`
|
||||||
|
Completed bool `json:"completed"`
|
||||||
|
Error string `json:"error"`
|
||||||
|
Log []string `json:"log"`
|
||||||
|
Result TaskResult `json:"result"`
|
||||||
|
Stage string `json:"stage"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
UpdateTime uint64 `json:"updateTime"`
|
||||||
|
UpdatedTime uint64 `json:"updatedTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SshKeyConfig struct {
|
||||||
|
User string
|
||||||
|
SshKey string
|
||||||
|
UserShell string
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
func nodeMasterDefault() K8sNodeRecord {
|
||||||
|
return K8sNodeRecord{
|
||||||
|
Num: 1,
|
||||||
|
Cpu: 2,
|
||||||
|
Ram: 2048,
|
||||||
|
Disk: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodeWorkerDefault() K8sNodeRecord {
|
||||||
|
return K8sNodeRecord{
|
||||||
|
Num: 1,
|
||||||
|
Cpu: 1,
|
||||||
|
Ram: 1024,
|
||||||
|
Disk: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseNode(nodeList []interface{}) K8sNodeRecord {
|
||||||
|
node := nodeList[0].(map[string]interface{})
|
||||||
|
|
||||||
|
return K8sNodeRecord{
|
||||||
|
Num: node["num"].(int),
|
||||||
|
Cpu: node["cpu"].(int),
|
||||||
|
Ram: node["ram"].(int),
|
||||||
|
Disk: node["disk"].(int),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodeToResource(node K8sNodeRecord) []interface{} {
|
||||||
|
mp := make(map[string]interface{})
|
||||||
|
|
||||||
|
mp["num"] = node.Num
|
||||||
|
mp["cpu"] = node.Cpu
|
||||||
|
mp["ram"] = node.Ram
|
||||||
|
mp["disk"] = node.Disk
|
||||||
|
|
||||||
|
return []interface{}{mp}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodeK8sSubresourceSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"num": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "Number of nodes to create.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "Node CPU count.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "Node RAM in MB.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"disk": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "Node boot disk size in GB.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,403 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceK8sCreate: called with name %s, rg %d", d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("name", d.Get("name").(string))
|
||||||
|
urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int)))
|
||||||
|
urlValues.Add("k8ciId", strconv.Itoa(d.Get("k8sci_id").(int)))
|
||||||
|
urlValues.Add("workerGroupName", d.Get("wg_name").(string))
|
||||||
|
|
||||||
|
var masterNode K8sNodeRecord
|
||||||
|
if masters, ok := d.GetOk("masters"); ok {
|
||||||
|
masterNode = parseNode(masters.([]interface{}))
|
||||||
|
} else {
|
||||||
|
masterNode = nodeMasterDefault()
|
||||||
|
}
|
||||||
|
urlValues.Add("masterNum", strconv.Itoa(masterNode.Num))
|
||||||
|
urlValues.Add("masterCpu", strconv.Itoa(masterNode.Cpu))
|
||||||
|
urlValues.Add("masterRam", strconv.Itoa(masterNode.Ram))
|
||||||
|
urlValues.Add("masterDisk", strconv.Itoa(masterNode.Disk))
|
||||||
|
|
||||||
|
var workerNode K8sNodeRecord
|
||||||
|
if workers, ok := d.GetOk("workers"); ok {
|
||||||
|
workerNode = parseNode(workers.([]interface{}))
|
||||||
|
} else {
|
||||||
|
workerNode = nodeWorkerDefault()
|
||||||
|
}
|
||||||
|
urlValues.Add("workerNum", strconv.Itoa(workerNode.Num))
|
||||||
|
urlValues.Add("workerCpu", strconv.Itoa(workerNode.Cpu))
|
||||||
|
urlValues.Add("workerRam", strconv.Itoa(workerNode.Ram))
|
||||||
|
urlValues.Add("workerDisk", strconv.Itoa(workerNode.Disk))
|
||||||
|
|
||||||
|
//if withLB, ok := d.GetOk("with_lb"); ok {
|
||||||
|
//urlValues.Add("withLB", strconv.FormatBool(withLB.(bool)))
|
||||||
|
//}
|
||||||
|
urlValues.Add("withLB", strconv.FormatBool(true))
|
||||||
|
|
||||||
|
if extNet, ok := d.GetOk("extnet_id"); ok {
|
||||||
|
urlValues.Add("extnetId", strconv.Itoa(extNet.(int)))
|
||||||
|
} else {
|
||||||
|
urlValues.Add("extnetId", "0")
|
||||||
|
}
|
||||||
|
|
||||||
|
//if desc, ok := d.GetOk("desc"); ok {
|
||||||
|
//urlValues.Add("desc", desc.(string))
|
||||||
|
//}
|
||||||
|
|
||||||
|
resp, err := c.DecortAPICall(ctx, "POST", K8sCreateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
urlValues.Add("auditId", strings.Trim(resp, `"`))
|
||||||
|
|
||||||
|
for {
|
||||||
|
resp, err := c.DecortAPICall(ctx, "POST", AsyncTaskGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
task := AsyncTask{}
|
||||||
|
if err := json.Unmarshal([]byte(resp), &task); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
log.Debugf("resourceK8sCreate: instance creating - %s", task.Stage)
|
||||||
|
|
||||||
|
if task.Completed {
|
||||||
|
if task.Error != "" {
|
||||||
|
return diag.FromErr(fmt.Errorf("cannot create k8s instance: %v", task.Error))
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(strconv.Itoa(int(task.Result)))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Second * 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("default_wg_id", k8s.Groups.Workers[0].ID)
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
urlValues.Add("lbId", strconv.Itoa(k8s.LbID))
|
||||||
|
|
||||||
|
resp, err = c.DecortAPICall(ctx, "POST", LbGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var lb LbRecord
|
||||||
|
if err := json.Unmarshal([]byte(resp), &lb); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
d.Set("extnet_id", lb.ExtNetID)
|
||||||
|
d.Set("lb_ip", lb.PrimaryNode.FrontendIP)
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
urlValues.Add("k8sId", d.Id())
|
||||||
|
kubeconfig, err := c.DecortAPICall(ctx, "POST", K8sGetConfigAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("could not get kubeconfig: %v", err)
|
||||||
|
}
|
||||||
|
d.Set("kubeconfig", kubeconfig)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceK8sRead: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||||
|
if k8s == nil {
|
||||||
|
d.SetId("")
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("name", k8s.Name)
|
||||||
|
d.Set("rg_id", k8s.RgID)
|
||||||
|
d.Set("k8sci_id", k8s.CI)
|
||||||
|
d.Set("wg_name", k8s.Groups.Workers[0].Name)
|
||||||
|
d.Set("masters", nodeToResource(k8s.Groups.Masters))
|
||||||
|
d.Set("workers", nodeToResource(k8s.Groups.Workers[0]))
|
||||||
|
d.Set("default_wg_id", k8s.Groups.Workers[0].ID)
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("lbId", strconv.Itoa(k8s.LbID))
|
||||||
|
|
||||||
|
resp, err := c.DecortAPICall(ctx, "POST", LbGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var lb LbRecord
|
||||||
|
if err := json.Unmarshal([]byte(resp), &lb); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
d.Set("extnet_id", lb.ExtNetID)
|
||||||
|
d.Set("lb_ip", lb.PrimaryNode.FrontendIP)
|
||||||
|
|
||||||
|
urlValues = &url.Values{}
|
||||||
|
urlValues.Add("k8sId", d.Id())
|
||||||
|
kubeconfig, err := c.DecortAPICall(ctx, "POST", K8sGetConfigAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("could not get kubeconfig: %v", err)
|
||||||
|
}
|
||||||
|
d.Set("kubeconfig", kubeconfig)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceK8sUpdate: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
|
||||||
|
if d.HasChange("name") {
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("k8sId", d.Id())
|
||||||
|
urlValues.Add("name", d.Get("name").(string))
|
||||||
|
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", K8sUpdateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("workers") {
|
||||||
|
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg := k8s.Groups.Workers[0]
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("k8sId", d.Id())
|
||||||
|
urlValues.Add("workersGroupId", strconv.Itoa(wg.ID))
|
||||||
|
|
||||||
|
newWorkers := parseNode(d.Get("workers").([]interface{}))
|
||||||
|
|
||||||
|
if newWorkers.Num > wg.Num {
|
||||||
|
urlValues.Add("num", strconv.Itoa(newWorkers.Num-wg.Num))
|
||||||
|
if _, err := c.DecortAPICall(ctx, "POST", K8sWorkerAddAPI, urlValues); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := wg.Num - 1; i >= newWorkers.Num; i-- {
|
||||||
|
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
|
||||||
|
if _, err := c.DecortAPICall(ctx, "POST", K8sWorkerDeleteAPI, urlValues); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||||
|
if k8s == nil {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("k8sId", d.Id())
|
||||||
|
urlValues.Add("permanently", "true")
|
||||||
|
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", K8sDeleteAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
log.Debugf("resourceK8sExists: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
k8s, err := utilityK8sCheckPresence(ctx, d, m)
|
||||||
|
if k8s == nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "Name of the cluster.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "Resource group ID that this instance belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"k8sci_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "ID of the k8s catalog item to base this instance on.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"wg_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "Name for first worker group created with cluster.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"masters": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: nodeK8sSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Master node(s) configuration.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"workers": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: nodeK8sSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Worker node(s) configuration.",
|
||||||
|
},
|
||||||
|
|
||||||
|
//"with_lb": {
|
||||||
|
//Type: schema.TypeBool,
|
||||||
|
//Optional: true,
|
||||||
|
//ForceNew: true,
|
||||||
|
//Default: true,
|
||||||
|
//Description: "Create k8s with load balancer if true.",
|
||||||
|
//},
|
||||||
|
|
||||||
|
"extnet_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
|
||||||
|
},
|
||||||
|
|
||||||
|
//"desc": {
|
||||||
|
//Type: schema.TypeString,
|
||||||
|
//Optional: true,
|
||||||
|
//Description: "Text description of this instance.",
|
||||||
|
//},
|
||||||
|
|
||||||
|
"lb_ip": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "IP address of default load balancer.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"default_wg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "ID of default workers group for this instace.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"kubeconfig": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Kubeconfig for cluster access.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceK8s() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceK8sCreate,
|
||||||
|
ReadContext: resourceK8sRead,
|
||||||
|
UpdateContext: resourceK8sUpdate,
|
||||||
|
DeleteContext: resourceK8sDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout20m,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout20m,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: resourceK8sSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,258 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceK8sWgCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceK8sWgCreate: called with k8s id %d", d.Get("k8s_id").(int))
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||||
|
urlValues.Add("name", d.Get("name").(string))
|
||||||
|
urlValues.Add("workerNum", strconv.Itoa(d.Get("num").(int)))
|
||||||
|
urlValues.Add("workerCpu", strconv.Itoa(d.Get("cpu").(int)))
|
||||||
|
urlValues.Add("workerRam", strconv.Itoa(d.Get("ram").(int)))
|
||||||
|
urlValues.Add("workerDisk", strconv.Itoa(d.Get("disk").(int)))
|
||||||
|
|
||||||
|
resp, err := c.DecortAPICall(ctx, "POST", K8sWgCreateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(resp)
|
||||||
|
|
||||||
|
// This code is the supposed flow, but at the time of writing it's not yet implemented by the platfom
|
||||||
|
|
||||||
|
//urlValues = &url.Values{}
|
||||||
|
//urlValues.Add("auditId", strings.Trim(resp, `"`))
|
||||||
|
|
||||||
|
//for {
|
||||||
|
//resp, err := controller.decortAPICall("POST", AsyncTaskGetAPI, urlValues)
|
||||||
|
//if err != nil {
|
||||||
|
//return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
//task := AsyncTask{}
|
||||||
|
//if err := json.Unmarshal([]byte(resp), &task); err != nil {
|
||||||
|
//return err
|
||||||
|
//}
|
||||||
|
//log.Debugf("resourceK8sCreate: workers group creating - %s", task.Stage)
|
||||||
|
|
||||||
|
//if task.Completed {
|
||||||
|
//if task.Error != "" {
|
||||||
|
//return fmt.Errorf("cannot create workers group: %v", task.Error)
|
||||||
|
//}
|
||||||
|
|
||||||
|
//d.SetId(strconv.Itoa(int(task.Result)))
|
||||||
|
//break
|
||||||
|
//}
|
||||||
|
|
||||||
|
//time.Sleep(time.Second * 5)
|
||||||
|
//}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int))
|
||||||
|
|
||||||
|
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
|
||||||
|
if wg == nil {
|
||||||
|
d.SetId("")
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("name", wg.Name)
|
||||||
|
d.Set("num", wg.Num)
|
||||||
|
d.Set("cpu", wg.Cpu)
|
||||||
|
d.Set("ram", wg.Ram)
|
||||||
|
d.Set("disk", wg.Disk)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sWgUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceK8sWgUpdate: called with k8s id %d", d.Get("k8s_id").(int))
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
|
||||||
|
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||||
|
urlValues.Add("workersGroupId", d.Id())
|
||||||
|
|
||||||
|
if newNum := d.Get("num").(int); newNum > wg.Num {
|
||||||
|
urlValues.Add("num", strconv.Itoa(newNum-wg.Num))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", K8sWorkerAddAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := wg.Num - 1; i >= newNum; i-- {
|
||||||
|
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", K8sWorkerDeleteAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sWgDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int))
|
||||||
|
|
||||||
|
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
|
||||||
|
if wg == nil {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||||
|
urlValues.Add("workersGroupId", strconv.Itoa(wg.ID))
|
||||||
|
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", K8sWgDeleteAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sWgExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
log.Debugf("resourceK8sWgExists: called with k8s id %d", d.Get("k8s_id").(int))
|
||||||
|
|
||||||
|
wg, err := utilityK8sWgCheckPresence(ctx, d, m)
|
||||||
|
if wg == nil {
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceK8sWgSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"k8s_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "ID of k8s instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "Name of the worker group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"num": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: 1,
|
||||||
|
Description: "Number of worker nodes to create.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Default: 1,
|
||||||
|
Description: "Worker node CPU count.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Default: 1024,
|
||||||
|
Description: "Worker node RAM in MB.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"disk": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Default: 0,
|
||||||
|
Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceK8sWg() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceK8sWgCreate,
|
||||||
|
ReadContext: resourceK8sWgRead,
|
||||||
|
UpdateContext: resourceK8sWgUpdate,
|
||||||
|
DeleteContext: resourceK8sWgDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout20m,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout20m,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: resourceK8sWgSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityK8sCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8sRecord, error) {
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("k8sId", d.Id())
|
||||||
|
|
||||||
|
resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var k8s K8sRecord
|
||||||
|
if err := json.Unmarshal([]byte(resp), &k8s); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &k8s, nil
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*K8sNodeRecord, error) {
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||||
|
|
||||||
|
resp, err := c.DecortAPICall(ctx, "POST", K8sGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var k8s K8sRecord
|
||||||
|
if err := json.Unmarshal([]byte(resp), &k8s); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, wg := range k8s.Groups.Workers {
|
||||||
|
if wg.ID == id {
|
||||||
|
return &wg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kvmvm
|
||||||
|
|
||||||
|
const KvmX86CreateAPI = "/restmachine/cloudbroker/kvmx86/create"
|
||||||
|
const KvmPPCCreateAPI = "/restmachine/cloudbroker/kvmppc/create"
|
||||||
|
const ComputeGetAPI = "/restmachine/cloudbroker/compute/get"
|
||||||
|
const RgListComputesAPI = "/restmachine/cloudbroker/rg/listComputes"
|
||||||
|
const ComputeNetAttachAPI = "/restmachine/cloudbroker/compute/netAttach"
|
||||||
|
const ComputeNetDetachAPI = "/restmachine/cloudbroker/compute/netDetach"
|
||||||
|
const ComputeDiskAttachAPI = "/restmachine/cloudbroker/compute/diskAttach"
|
||||||
|
const ComputeDiskDetachAPI = "/restmachine/cloudbroker/compute/diskDetach"
|
||||||
|
const ComputeStartAPI = "/restmachine/cloudbroker/compute/start"
|
||||||
|
const ComputeStopAPI = "/restmachine/cloudbroker/compute/stop"
|
||||||
|
const ComputeResizeAPI = "/restmachine/cloudbroker/compute/resize"
|
||||||
|
const DisksResizeAPI = "/restmachine/cloudbroker/disks/resize2"
|
||||||
|
const ComputeDeleteAPI = "/restmachine/cloudbroker/compute/delete"
|
@ -0,0 +1,385 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kvmvm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
// "net/url"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parse list of all disks from API compute/get into a list of "extra disks" attached to this compute
|
||||||
|
// Extra disks are all compute disks but a boot disk.
|
||||||
|
func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
||||||
|
// this return value will be used to d.Set("extra_disks",) item of dataSourceCompute schema,
|
||||||
|
// which is a simple list of integer disk IDs excluding boot disk ID
|
||||||
|
length := len(disks)
|
||||||
|
log.Debugf("parseComputeDisksToExtraDisks: called for %d disks", length)
|
||||||
|
|
||||||
|
if length == 0 || (length == 1 && disks[0].Type == "B") {
|
||||||
|
// the disk list is empty (which is kind of strange - diskless compute?), or
|
||||||
|
// there is only one disk in the list and it is a boot disk;
|
||||||
|
// as we skip boot disks, the result will be of 0 length anyway
|
||||||
|
return make([]interface{}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]interface{}, length-1)
|
||||||
|
idx := 0
|
||||||
|
for _, value := range disks {
|
||||||
|
if value.Type == "B" {
|
||||||
|
// skip boot disk when iterating over the list of disks
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result[idx] = value.ID
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseBootDiskSize(disks []DiskRecord) int {
|
||||||
|
// this return value will be used to d.Set("boot_disk_size",) item of dataSourceCompute schema
|
||||||
|
if len(disks) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range disks {
|
||||||
|
if value.Type == "B" {
|
||||||
|
return value.SizeMax
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseBootDiskId(disks []DiskRecord) uint {
|
||||||
|
// this return value will be used to d.Set("boot_disk_id",) item of dataSourceCompute schema
|
||||||
|
if len(disks) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range disks {
|
||||||
|
if value.Type == "B" {
|
||||||
|
return value.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func findBootDisk(disks []DiskRecord) (*DiskRecord, error) {
|
||||||
|
for _, d := range disks {
|
||||||
|
if d.Type == "B" {
|
||||||
|
return &d, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("boot disk not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the list of interfaces from compute/get response into a list of networks
|
||||||
|
// attached to this compute
|
||||||
|
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
||||||
|
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
||||||
|
length := len(ifaces)
|
||||||
|
log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length)
|
||||||
|
|
||||||
|
result := []interface{}{}
|
||||||
|
|
||||||
|
for _, value := range ifaces {
|
||||||
|
elem := make(map[string]interface{})
|
||||||
|
// Keys in this map should correspond to the Schema definition
|
||||||
|
// as returned by networkSubresourceSchemaMake()
|
||||||
|
elem["net_id"] = value.NetID
|
||||||
|
elem["net_type"] = value.NetType
|
||||||
|
elem["ip_address"] = value.IPAddress
|
||||||
|
elem["mac"] = value.MAC
|
||||||
|
|
||||||
|
// log.Debugf(" element %d: net_id=%d, net_type=%s", i, value.NetID, value.NetType)
|
||||||
|
|
||||||
|
result = append(result, elem)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||||
|
// This function expects that compFacts string contains response from API compute/get,
|
||||||
|
// i.e. detailed information about compute instance.
|
||||||
|
//
|
||||||
|
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||||
|
// from resourceComputeExists(...) method
|
||||||
|
model := ComputeGetResp{}
|
||||||
|
log.Debugf("flattenCompute: ready to unmarshal string %s", compFacts)
|
||||||
|
err := json.Unmarshal([]byte(compFacts), &model)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("flattenCompute: ID %d, RG ID %d", model.ID, model.RgID)
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%d", model.ID))
|
||||||
|
// d.Set("compute_id", model.ID) - we should NOT set compute_id in the schema here: if it was set - it is already set, if it wasn't - we shouldn't
|
||||||
|
d.Set("name", model.Name)
|
||||||
|
d.Set("rg_id", model.RgID)
|
||||||
|
d.Set("rg_name", model.RgName)
|
||||||
|
d.Set("account_id", model.AccountID)
|
||||||
|
d.Set("account_name", model.AccountName)
|
||||||
|
d.Set("driver", model.Driver)
|
||||||
|
d.Set("cpu", model.Cpu)
|
||||||
|
d.Set("ram", model.Ram)
|
||||||
|
// d.Set("boot_disk_size", model.BootDiskSize) - bootdiskSize key in API compute/get is always zero, so we set boot_disk_size in another way
|
||||||
|
d.Set("image_id", model.ImageID)
|
||||||
|
d.Set("description", model.Desc)
|
||||||
|
d.Set("cloud_init", "applied") // NOTE: for existing compute we hard-code this value as an indicator for DiffSuppress fucntion
|
||||||
|
// d.Set("status", model.Status)
|
||||||
|
// d.Set("tech_status", model.TechStatus)
|
||||||
|
|
||||||
|
if model.TechStatus == "STARTED" {
|
||||||
|
d.Set("started", true)
|
||||||
|
} else {
|
||||||
|
d.Set("started", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
bootDisk, err := findBootDisk(model.Disks)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("boot_disk_size", bootDisk.SizeMax)
|
||||||
|
d.Set("boot_disk_id", bootDisk.ID) // we may need boot disk ID in resize operations
|
||||||
|
d.Set("sep_id", bootDisk.SepID)
|
||||||
|
d.Set("pool", bootDisk.Pool)
|
||||||
|
|
||||||
|
if len(model.Disks) > 0 {
|
||||||
|
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(model.Disks))
|
||||||
|
if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(model.Interfaces) > 0 {
|
||||||
|
log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(model.Interfaces))
|
||||||
|
if err = d.Set("network", parseComputeInterfacesToNetworks(model.Interfaces)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(model.OsUsers) > 0 {
|
||||||
|
log.Debugf("flattenCompute: calling parseOsUsers for %d logins", len(model.OsUsers))
|
||||||
|
if err = d.Set("os_users", parseOsUsers(model.OsUsers)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
compFacts, err := utilityComputeCheckPresence(ctx, d, m)
|
||||||
|
if compFacts == "" {
|
||||||
|
// if empty string is returned from utilityComputeCheckPresence then there is no
|
||||||
|
// such Compute and err tells so - just return it to the calling party
|
||||||
|
d.SetId("") // ensure ID is empty
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = flattenCompute(d, compFacts); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceCompute() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceComputeRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Name of this compute instance. NOTE: this parameter is case sensitive.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: consider removing compute_id from the schema, as it not practical to call this data provider if
|
||||||
|
// corresponding compute ID is already known
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "ID of the compute instance. If ID is specified, name and resource group ID are ignored.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "ID of the resource group where this compute instance is located.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"rg_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the resource group where this compute instance is located.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "ID of the account this compute instance belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the account this compute instance belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"driver": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Hardware architecture of this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Number of CPUs allocated for this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Amount of RAM in MB allocated for this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"image_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "ID of the OS image this compute instance is based on.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"image_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the OS image this compute instance is based on.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"boot_disk_size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "This compute instance boot disk size in GB.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"boot_disk_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "This compute instance boot disk ID.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"extra_disks": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
Description: "IDs of the extra disk(s) attached to this compute.",
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
"disks": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
||||||
|
},
|
||||||
|
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
|
"network": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: constants.MaxNetworksPerCompute,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: networkSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Network connection(s) for this compute.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"os_users": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: osUsersSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Guest OS users provisioned on this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "User-defined text description of this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"cloud_init": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Placeholder for cloud_init parameters.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"started": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Description: "Is compute started.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kvmvm
|
||||||
|
|
||||||
|
type DiskRecord struct {
|
||||||
|
Acl map[string]interface{} `json:"acl"`
|
||||||
|
AccountID int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
BootPartition int `json:"bootPartition"`
|
||||||
|
CreatedTime uint64 `json:"creationTime"`
|
||||||
|
ComputeID int `json:"computeId"`
|
||||||
|
ComputeName string `json:"computeName"`
|
||||||
|
DeletedTime uint64 `json:"deletionTime"`
|
||||||
|
DeviceName string `json:"devicename"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
DestructionTime uint64 `json:"destructionTime"`
|
||||||
|
DiskPath string `json:"diskPath"`
|
||||||
|
GridID int `json:"gid"`
|
||||||
|
GUID int `json:"guid"`
|
||||||
|
ID uint `json:"id"`
|
||||||
|
ImageID int `json:"imageId"`
|
||||||
|
Images []int `json:"images"`
|
||||||
|
IOTune map[string]interface{} `json:"iotune"`
|
||||||
|
IQN string `json:"iqn"`
|
||||||
|
Login string `json:"login"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
MachineId int `json:"machineId"`
|
||||||
|
MachineName string `json:"machineName"`
|
||||||
|
Milestones uint64 `json:"milestones"`
|
||||||
|
Order int `json:"order"`
|
||||||
|
Params string `json:"params"`
|
||||||
|
Passwd string `json:"passwd"`
|
||||||
|
ParentId int `json:"parentId"`
|
||||||
|
PciSlot int `json:"pciSlot"`
|
||||||
|
Pool string `json:"pool"`
|
||||||
|
PurgeTime uint64 `json:"purgeTime"`
|
||||||
|
PurgeAttempts uint64 `json:"purgeAttempts"`
|
||||||
|
RealityDeviceNumber int `json:"realityDeviceNumber"`
|
||||||
|
ReferenceId string `json:"referenceId"`
|
||||||
|
ResID string `json:"resId"`
|
||||||
|
ResName string `json:"resName"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
SepType string `json:"sepType"`
|
||||||
|
SepID int `json:"sepId"` // NOTE: absent from compute/get output
|
||||||
|
SizeMax int `json:"sizeMax"`
|
||||||
|
SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space
|
||||||
|
Snapshots []SnapshotRecord `json:"snapshots"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
TechStatus string `json:"techStatus"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
UpdateBy uint64 `json:"updateBy"`
|
||||||
|
VMID int `json:"vmid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InterfaceRecord struct {
|
||||||
|
ConnID int `json:"connId"` // This is VLAN ID or VxLAN ID, depending on ConnType
|
||||||
|
ConnType string `json:"connType"` // Either "VLAN" or "VXLAN" tag
|
||||||
|
DefaultGW string `json:"defGw"`
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
IPAddress string `json:"ipAddress"` // without trailing network mask, i.e. "192.168.1.3"
|
||||||
|
MAC string `json:"mac"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
NetID int `json:"netId"` // This is either ExtNet ID or ViNS ID, depending on NetType
|
||||||
|
NetMask int `json:"netMask"`
|
||||||
|
NetType string `json:"netType"` // Either "EXTNET" or "VINS" tag
|
||||||
|
PciSlot int `json:"pciSlot"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
VNFs []int `json:"vnfs"`
|
||||||
|
QOS InterfaceQosRecord `json:"qos"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InterfaceQosRecord struct {
|
||||||
|
ERate int `json:"eRate"`
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
InBurst int `json:"inBurst"`
|
||||||
|
InRate int `json:"inRate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnapshotRecord struct {
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
ResId string `json:"resId"`
|
||||||
|
SnapSetGuid string `json:"snapSetGuid"`
|
||||||
|
SnapSetTime uint64 `json:"snapSetTime"`
|
||||||
|
TimeStamp uint64 `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnapshotRecordList []SnapshotRecord
|
||||||
|
|
||||||
|
type ComputeGetResp struct {
|
||||||
|
// ACLs `json:"ACL"` - it is a dictionary, special parsing required
|
||||||
|
AccountID int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
Arch string `json:"arch"`
|
||||||
|
BootDiskSize int `json:"bootdiskSize"`
|
||||||
|
CloneReference int `json:"cloneReference"`
|
||||||
|
Clones []int `json:"clones"`
|
||||||
|
Cpu int `json:"cpus"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
Disks []DiskRecord `json:"disks"`
|
||||||
|
Driver string `json:"driver"`
|
||||||
|
GridID int `json:"gid"`
|
||||||
|
ID uint `json:"id"`
|
||||||
|
ImageID int `json:"imageId"`
|
||||||
|
ImageName string `json:"imageName"`
|
||||||
|
Interfaces []InterfaceRecord `json:"interfaces"`
|
||||||
|
LockStatus string `json:"lockStatus"`
|
||||||
|
ManagerID int `json:"managerId"`
|
||||||
|
ManagerType string `json:"manageType"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
NatableVinsID int `json:"natableVinsId"`
|
||||||
|
NatableVinsIP string `json:"natableVinsIp"`
|
||||||
|
NatableVinsName string `json:"natableVinsName"`
|
||||||
|
NatableVinsNet string `json:"natableVinsNetwork"`
|
||||||
|
NatableVinsNetName string `json:"natableVinsNetworkName"`
|
||||||
|
OsUsers []OsUserRecord `json:"osUsers"`
|
||||||
|
Ram int `json:"ram"`
|
||||||
|
RgID int `json:"rgId"`
|
||||||
|
RgName string `json:"rgName"`
|
||||||
|
SnapSets []SnapSetRecord `json:"snapSets"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
// Tags []string `json:"tags"` // Tags were reworked since DECORT 3.7.1
|
||||||
|
TechStatus string `json:"techStatus"`
|
||||||
|
TotalDiskSize int `json:"totalDiskSize"`
|
||||||
|
UpdatedBy string `json:"updatedBy"`
|
||||||
|
UpdateTime uint64 `json:"updateTime"`
|
||||||
|
UserManaged bool `json:"userManaged"`
|
||||||
|
Vgpus []int `json:"vgpus"`
|
||||||
|
VinsConnected int `json:"vinsConnected"`
|
||||||
|
VirtualImageID int `json:"virtualImageId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OsUserRecord struct {
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Login string `json:"login"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
PubKey string `json:"pubkey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnapSetRecord struct {
|
||||||
|
Disks []int `json:"disks"`
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
TimeStamp uint64 `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComputeBriefRecord struct { // this is a brief compute specifiaction as returned by API rg/listComputes
|
||||||
|
// we do not even include here all fields as returned by this API, but only the most important that
|
||||||
|
// are really necessary to identify and distinguish computes
|
||||||
|
AccountID int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ID uint `json:"id"`
|
||||||
|
RgID int `json:"rgId"`
|
||||||
|
RgName string `json:"rgName"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
TechStatus string `json:"techStatus"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RgListComputesResp []ComputeBriefRecord
|
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kvmvm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"hash/fnv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/statefuncs"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is subresource of compute resource used when creating/managing compute network connections
|
||||||
|
|
||||||
|
func networkSubresIPAddreDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
|
||||||
|
if newVal != "" && newVal != oldVal {
|
||||||
|
log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
log.Debugf("networkSubresIPAddreDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal)
|
||||||
|
return true // suppress difference
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is based on the original Terraform SerializeResourceForHash found
|
||||||
|
// in helper/schema/serialize.go
|
||||||
|
// It skips network subresource attributes, which are irrelevant for identification
|
||||||
|
// of unique network blocks
|
||||||
|
func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource *schema.Resource) {
|
||||||
|
if val == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rs := resource.Schema
|
||||||
|
m := val.(map[string]interface{})
|
||||||
|
|
||||||
|
keys := make([]string, 0, len(rs))
|
||||||
|
allComputed := true
|
||||||
|
|
||||||
|
for k, val := range rs {
|
||||||
|
if val.Optional || val.Required {
|
||||||
|
allComputed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(keys)
|
||||||
|
for _, k := range keys {
|
||||||
|
// explicitly ignore "ip_address" when hashing
|
||||||
|
if k == "ip_address" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
subSchema := rs[k]
|
||||||
|
// Skip attributes that are not user-provided. Computed attributes
|
||||||
|
// do not contribute to the hash since their ultimate value cannot
|
||||||
|
// be known at plan/diff time.
|
||||||
|
if !allComputed && !(subSchema.Required || subSchema.Optional) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
output.WriteString(k)
|
||||||
|
output.WriteRune(':')
|
||||||
|
value := m[k]
|
||||||
|
schema.SerializeValueForHash(output, value, subSchema)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HashNetworkSubresource hashes network subresource of compute resource. It uses
|
||||||
|
// specially designed networkSubresourceSerialize (see above) to make sure hashing
|
||||||
|
// does not involve attributes that we deem irrelevant to the uniqueness of network
|
||||||
|
// subresource definitions.
|
||||||
|
// It is this function that should be specified as SchemaSetFunc when creating Set
|
||||||
|
// from network subresource (e.g. in flattenCompute)
|
||||||
|
//
|
||||||
|
// This function is based on the original Terraform function HashResource from
|
||||||
|
// helper/schema/set.go
|
||||||
|
func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc {
|
||||||
|
return func(v interface{}) int {
|
||||||
|
var serialized bytes.Buffer
|
||||||
|
networkSubresourceSerialize(&serialized, v, resource)
|
||||||
|
|
||||||
|
hs := fnv.New32a()
|
||||||
|
hs.Write(serialized.Bytes())
|
||||||
|
return int(hs.Sum32())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func networkSubresourceSchemaMake() map[string]*schema.Schema {
|
||||||
|
rets := map[string]*schema.Schema{
|
||||||
|
"net_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
StateFunc: statefuncs.StateFuncToUpper,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, false), // observe case while validating
|
||||||
|
Description: "Type of the network for this connection, either EXTNET or VINS.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"net_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "ID of the network for this connection.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ip_address": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
DiffSuppressFunc: networkSubresIPAddreDiffSupperss,
|
||||||
|
Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"mac": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "MAC address associated with this connection. MAC address is assigned automatically.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return rets
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kvmvm
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseOsUsers(logins []OsUserRecord) []interface{} {
|
||||||
|
var result = make([]interface{}, len(logins))
|
||||||
|
|
||||||
|
for index, value := range logins {
|
||||||
|
elem := make(map[string]interface{})
|
||||||
|
|
||||||
|
elem["guid"] = value.Guid
|
||||||
|
elem["login"] = value.Login
|
||||||
|
elem["password"] = value.Password
|
||||||
|
elem["public_key"] = value.PubKey
|
||||||
|
result[index] = elem
|
||||||
|
log.Debugf("parseOsUsers: parsed element %d - login %q", index, value.Login)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func osUsersSubresourceSchemaMake() map[string]*schema.Schema {
|
||||||
|
rets := map[string]*schema.Schema{
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "GUID of this guest OS user.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"login": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Login name of this guest OS user.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"password": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Sensitive: true,
|
||||||
|
Description: "Password of this guest OS user.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"public_key": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "SSH public key of this guest OS user.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
@ -0,0 +1,542 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kvmvm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/statefuncs"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
|
||||||
|
if oldVal == "" && newVal != "applied" {
|
||||||
|
// if old value for "cloud_init" resource is empty string, it means that we are creating new compute
|
||||||
|
// and there is a chance that the user will want custom cloud init parameters - so we check if
|
||||||
|
// cloud_init is explicitly set in TF file by making sure that its new value is different from "applied",
|
||||||
|
// which is a reserved key word.
|
||||||
|
log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal)
|
||||||
|
return false // there is a difference between stored and new value
|
||||||
|
}
|
||||||
|
log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal)
|
||||||
|
return true // suppress difference
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
// we assume all mandatory parameters it takes to create a comptue instance are properly
|
||||||
|
// specified - we rely on schema "Required" attributes to let Terraform validate them for us
|
||||||
|
|
||||||
|
log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
// create basic Compute (i.e. without extra disks and network connections - those will be attached
|
||||||
|
// by subsequent individual API calls).
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("rgId", fmt.Sprintf("%d", d.Get("rg_id").(int)))
|
||||||
|
urlValues.Add("name", d.Get("name").(string))
|
||||||
|
urlValues.Add("cpu", fmt.Sprintf("%d", d.Get("cpu").(int)))
|
||||||
|
urlValues.Add("ram", fmt.Sprintf("%d", d.Get("ram").(int)))
|
||||||
|
urlValues.Add("imageId", fmt.Sprintf("%d", d.Get("image_id").(int)))
|
||||||
|
urlValues.Add("bootDisk", fmt.Sprintf("%d", d.Get("boot_disk_size").(int)))
|
||||||
|
urlValues.Add("netType", "NONE") // at the 1st step create isolated compute
|
||||||
|
urlValues.Add("start", "0") // at the 1st step create compute in a stopped state
|
||||||
|
|
||||||
|
argVal, argSet := d.GetOk("description")
|
||||||
|
if argSet {
|
||||||
|
urlValues.Add("desc", argVal.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
if sepID, ok := d.GetOk("sep_id"); ok {
|
||||||
|
urlValues.Add("sepId", strconv.Itoa(sepID.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if pool, ok := d.GetOk("pool"); ok {
|
||||||
|
urlValues.Add("pool", pool.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sshKeysVal, sshKeysSet := d.GetOk("ssh_keys")
|
||||||
|
if sshKeysSet {
|
||||||
|
// process SSH Key settings and set API values accordingly
|
||||||
|
log.Debugf("resourceComputeCreate: calling makeSshKeysArgString to setup SSH keys for guest login(s)")
|
||||||
|
urlValues.Add("userdata", makeSshKeysArgString(sshKeysVal.([]interface{})))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
computeCreateAPI := KvmX86CreateAPI
|
||||||
|
driver := d.Get("driver").(string)
|
||||||
|
if driver == "KVM_PPC" {
|
||||||
|
computeCreateAPI = KvmPPCCreateAPI
|
||||||
|
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC")
|
||||||
|
} else { // note that we do not validate arch value for explicit "KVM_X86" here
|
||||||
|
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
|
||||||
|
}
|
||||||
|
|
||||||
|
argVal, argSet = d.GetOk("cloud_init")
|
||||||
|
if argSet {
|
||||||
|
// userdata must not be empty string and must not be a reserved keyword "applied"
|
||||||
|
userdata := argVal.(string)
|
||||||
|
if userdata != "" && userdata != "applied" {
|
||||||
|
urlValues.Add("userdata", userdata)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apiResp, err := c.DecortAPICall(ctx, "POST", computeCreateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
// Compute create API returns ID of the new Compute instance on success
|
||||||
|
|
||||||
|
d.SetId(apiResp) // update ID of the resource to tell Terraform that the resource exists, albeit partially
|
||||||
|
compId, _ := strconv.Atoi(apiResp)
|
||||||
|
|
||||||
|
log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", compId, d.Get("name").(string))
|
||||||
|
|
||||||
|
// Configure data disks if any
|
||||||
|
argVal, argSet = d.GetOk("extra_disks")
|
||||||
|
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||||
|
// urlValues.Add("desc", argVal.(string))
|
||||||
|
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
|
||||||
|
err = utilityComputeExtraDisksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", compId, err)
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Configure external networks if any
|
||||||
|
argVal, argSet = d.GetOk("network")
|
||||||
|
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||||
|
log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len())
|
||||||
|
err = utilityComputeNetworksConfigure(ctx, d, m, false) // do_delta=false, as we are working on a new compute
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", compId, err)
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
|
||||||
|
// now we need to start it before we report the sequence complete
|
||||||
|
if d.Get("started").(bool) {
|
||||||
|
reqValues := &url.Values{}
|
||||||
|
reqValues.Add("computeId", fmt.Sprintf("%d", compId))
|
||||||
|
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId)
|
||||||
|
if _, err := c.DecortAPICall(ctx, "POST", ComputeStartAPI, reqValues); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", compId, d.Get("name").(string))
|
||||||
|
|
||||||
|
// We may reuse dataSourceComputeRead here as we maintain similarity
|
||||||
|
// between Compute resource and Compute data source schemas
|
||||||
|
// Compute read function will also update resource ID on success, so that Terraform
|
||||||
|
// will know the resource exists
|
||||||
|
return dataSourceComputeRead(ctx, d, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceComputeRead: called for Compute name %s, RG ID %d",
|
||||||
|
d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
compFacts, err := utilityComputeCheckPresence(ctx, d, m)
|
||||||
|
if compFacts == "" {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
// Compute with such name and RG ID was not found
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = flattenCompute(d, compFacts); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("resourceComputeRead: after flattenCompute: Compute ID %s, name %q, RG ID %d",
|
||||||
|
d.Id(), d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceComputeUpdate: called for Compute ID %s / name %s, RGID %d",
|
||||||
|
d.Id(), d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Resize CPU/RAM
|
||||||
|
2. Resize (grow) boot disk
|
||||||
|
3. Update extra disks
|
||||||
|
4. Update networks
|
||||||
|
5. Start/stop
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 1. Resize CPU/RAM
|
||||||
|
params := &url.Values{}
|
||||||
|
doUpdate := false
|
||||||
|
params.Add("computeId", d.Id())
|
||||||
|
|
||||||
|
oldCpu, newCpu := d.GetChange("cpu")
|
||||||
|
if oldCpu.(int) != newCpu.(int) {
|
||||||
|
params.Add("cpu", fmt.Sprintf("%d", newCpu.(int)))
|
||||||
|
doUpdate = true
|
||||||
|
} else {
|
||||||
|
params.Add("cpu", "0") // no change to CPU allocation
|
||||||
|
}
|
||||||
|
|
||||||
|
oldRam, newRam := d.GetChange("ram")
|
||||||
|
if oldRam.(int) != newRam.(int) {
|
||||||
|
params.Add("ram", fmt.Sprintf("%d", newRam.(int)))
|
||||||
|
doUpdate = true
|
||||||
|
} else {
|
||||||
|
params.Add("ram", "0")
|
||||||
|
}
|
||||||
|
|
||||||
|
if doUpdate {
|
||||||
|
log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d",
|
||||||
|
oldCpu.(int), newCpu.(int),
|
||||||
|
oldRam.(int), newRam.(int))
|
||||||
|
params.Add("force", "true")
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", ComputeResizeAPI, params)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Resize (grow) Boot disk
|
||||||
|
oldSize, newSize := d.GetChange("boot_disk_size")
|
||||||
|
if oldSize.(int) < newSize.(int) {
|
||||||
|
bdsParams := &url.Values{}
|
||||||
|
bdsParams.Add("diskId", fmt.Sprintf("%d", d.Get("boot_disk_id").(int)))
|
||||||
|
bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
||||||
|
log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d",
|
||||||
|
d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", DisksResizeAPI, bdsParams)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
} else if oldSize.(int) > newSize.(int) {
|
||||||
|
log.Warnf("resourceComputeUpdate: compute ID %s - shrinking boot disk is not allowed", d.Id())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Calculate and apply changes to data disks
|
||||||
|
err := utilityComputeExtraDisksConfigure(ctx, d, m, true) // pass do_delta = true to apply changes, if any
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Calculate and apply changes to network connections
|
||||||
|
err = utilityComputeNetworksConfigure(ctx, d, m, true) // pass do_delta = true to apply changes, if any
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.HasChange("started") {
|
||||||
|
params := &url.Values{}
|
||||||
|
params.Add("computeId", d.Id())
|
||||||
|
if d.Get("started").(bool) {
|
||||||
|
if _, err := c.DecortAPICall(ctx, "POST", ComputeStartAPI, params); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := c.DecortAPICall(ctx, "POST", ComputeStopAPI, params); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we may reuse dataSourceComputeRead here as we maintain similarity
|
||||||
|
// between Compute resource and Compute data source schemas
|
||||||
|
return dataSourceComputeRead(ctx, d, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
// NOTE: this function destroys target Compute instance "permanently", so
|
||||||
|
// there is no way to restore it.
|
||||||
|
// If compute being destroyed has some extra disks attached, they are
|
||||||
|
// detached from the compute
|
||||||
|
log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d",
|
||||||
|
d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
compFacts, err := utilityComputeCheckPresence(ctx, d, m)
|
||||||
|
if compFacts == "" {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
// the target Compute does not exist - in this case according to Terraform best practice
|
||||||
|
// we exit from Destroy method without error
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
|
||||||
|
model := ComputeGetResp{}
|
||||||
|
log.Debugf("resourceComputeDelete: ready to unmarshal string %s", compFacts)
|
||||||
|
err = json.Unmarshal([]byte(compFacts), &model)
|
||||||
|
if err == nil && len(model.Disks) > 0 {
|
||||||
|
// prepare to detach data disks from compute - do it only if compFacts unmarshalled
|
||||||
|
// properly and the resulting model contains non-empty Disks list
|
||||||
|
for _, diskFacts := range model.Disks {
|
||||||
|
if diskFacts.Type == "B" {
|
||||||
|
// boot disk is never detached on compute delete
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("resourceComputeDelete: ready to detach data disk ID %d from compute ID %s", diskFacts.ID, d.Id())
|
||||||
|
|
||||||
|
detachParams := &url.Values{}
|
||||||
|
detachParams.Add("computeId", d.Id())
|
||||||
|
detachParams.Add("diskId", fmt.Sprintf("%d", diskFacts.ID))
|
||||||
|
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", ComputeDiskDetachAPI, detachParams)
|
||||||
|
if err != nil {
|
||||||
|
// We do not fail compute deletion on data disk detach errors
|
||||||
|
log.Errorf("resourceComputeDelete: error when detaching Disk ID %d: %s", diskFacts.ID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
params := &url.Values{}
|
||||||
|
params.Add("computeId", d.Id())
|
||||||
|
params.Add("permanently", "1")
|
||||||
|
// TODO: this is for the upcoming API update - params.Add("detachdisks", "1")
|
||||||
|
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", ComputeDeleteAPI, params)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
||||||
|
log.Debugf("resourceComputeExist: called for Compute name %s, RG ID %d",
|
||||||
|
d.Get("name").(string), d.Get("rg_id").(int))
|
||||||
|
|
||||||
|
compFacts, err := utilityComputeCheckPresence(ctx, d, m)
|
||||||
|
if compFacts == "" {
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceCompute() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceComputeCreate,
|
||||||
|
ReadContext: resourceComputeRead,
|
||||||
|
UpdateContext: resourceComputeUpdate,
|
||||||
|
DeleteContext: resourceComputeDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout180s,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout180s,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.IntAtLeast(1),
|
||||||
|
Description: "ID of the resource group where this compute should be deployed.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"driver": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
StateFunc: statefuncs.StateFuncToUpper,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"KVM_X86", "KVM_PPC"}, false), // observe case while validating
|
||||||
|
Description: "Hardware architecture of this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.IntBetween(1, constants.MaxCpusPerCompute),
|
||||||
|
Description: "Number of CPUs to allocate to this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.IntAtLeast(constants.MinRamPerCompute),
|
||||||
|
Description: "Amount of RAM in MB to allocate to this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"image_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ValidateFunc: validation.IntAtLeast(1),
|
||||||
|
Description: "ID of the OS image to base this compute instance on.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"boot_disk_size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"sep_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"pool": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"extra_disks": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: constants.MaxExtraDisksPerCompute,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"network": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: constants.MaxNetworksPerCompute,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: networkSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.",
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
"ssh_keys": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: MaxSshKeysPerCompute,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: sshSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "SSH keys to authorize on this compute instance.",
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Optional text description of this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"cloud_init": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Default: "applied",
|
||||||
|
DiffSuppressFunc: cloudInitDiffSupperss,
|
||||||
|
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// The rest are Compute properties, which are "computed" once it is created
|
||||||
|
"rg_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the resource group where this compute instance is located.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "ID of the account this compute instance belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the account this compute instance belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"boot_disk_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "This compute instance boot disk ID.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"os_users": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: osUsersSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Guest OS users provisioned on this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"started": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Description: "Is compute started.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kvmvm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityComputeExtraDisksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error {
|
||||||
|
// d is filled with data according to computeResource schema, so extra disks config is retrieved via "extra_disks" key
|
||||||
|
// If do_delta is true, this function will identify changes between new and existing specs for extra disks and try to
|
||||||
|
// update compute configuration accordingly
|
||||||
|
// Otherwise it will apply whatever is found in the new set of "extra_disks" right away.
|
||||||
|
// Primary use of do_delta=false is when calling this function from compute Create handler.
|
||||||
|
|
||||||
|
// Note that this function will not abort on API errors, but will continue to configure (attach / detach) other individual
|
||||||
|
// disks via atomic API calls. However, it will not retry failed manipulation on the same disk.
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
|
||||||
|
log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta)
|
||||||
|
|
||||||
|
// NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt
|
||||||
|
old_set, new_set := d.GetChange("extra_disks")
|
||||||
|
|
||||||
|
apiErrCount := 0
|
||||||
|
var lastSavedError error
|
||||||
|
|
||||||
|
if !do_delta {
|
||||||
|
if new_set.(*schema.Set).Len() < 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, disk := range new_set.(*schema.Set).List() {
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("computeId", d.Id())
|
||||||
|
urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", ComputeDiskAttachAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
// failed to attach extra disk - partial resource update
|
||||||
|
apiErrCount++
|
||||||
|
lastSavedError = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if apiErrCount > 0 {
|
||||||
|
log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s",
|
||||||
|
apiErrCount, d.Id(), lastSavedError)
|
||||||
|
return lastSavedError
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
|
||||||
|
log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
|
||||||
|
for _, diskId := range detach_set.List() {
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("computeId", d.Id())
|
||||||
|
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", ComputeDiskDetachAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
// failed to detach disk - there will be partial resource update
|
||||||
|
log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||||
|
apiErrCount++
|
||||||
|
lastSavedError = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
|
||||||
|
log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
|
||||||
|
for _, diskId := range attach_set.List() {
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("computeId", d.Id())
|
||||||
|
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", ComputeDiskAttachAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
// failed to attach disk - there will be partial resource update
|
||||||
|
log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||||
|
apiErrCount++
|
||||||
|
lastSavedError = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if apiErrCount > 0 {
|
||||||
|
log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s",
|
||||||
|
apiErrCount, d.Id(), lastSavedError)
|
||||||
|
return lastSavedError
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func utilityComputeNetworksConfigure(ctx context.Context, d *schema.ResourceData, m interface{}, do_delta bool) error {
|
||||||
|
// "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key
|
||||||
|
// If do_delta is true, this function will identify changes between new and existing specs for network and try to
|
||||||
|
// update compute configuration accordingly
|
||||||
|
// Otherwise it will apply whatever is found in the new set of "network" right away.
|
||||||
|
// Primary use of do_delta=false is when calling this function from compute Create handler.
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
|
||||||
|
old_set, new_set := d.GetChange("network")
|
||||||
|
|
||||||
|
apiErrCount := 0
|
||||||
|
var lastSavedError error
|
||||||
|
|
||||||
|
if !do_delta {
|
||||||
|
if new_set.(*schema.Set).Len() < 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, runner := range new_set.(*schema.Set).List() {
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
net_data := runner.(map[string]interface{})
|
||||||
|
urlValues.Add("computeId", d.Id())
|
||||||
|
urlValues.Add("netType", net_data["net_type"].(string))
|
||||||
|
urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
|
||||||
|
ipaddr, ipSet := net_data["ip_address"] // "ip_address" key is optional
|
||||||
|
if ipSet {
|
||||||
|
urlValues.Add("ipAddr", ipaddr.(string))
|
||||||
|
}
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", ComputeNetAttachAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
// failed to attach network - partial resource update
|
||||||
|
apiErrCount++
|
||||||
|
lastSavedError = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if apiErrCount > 0 {
|
||||||
|
log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s",
|
||||||
|
apiErrCount, d.Id(), lastSavedError)
|
||||||
|
return lastSavedError
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
|
||||||
|
log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
|
||||||
|
for _, runner := range detach_set.List() {
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
net_data := runner.(map[string]interface{})
|
||||||
|
urlValues.Add("computeId", d.Id())
|
||||||
|
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
||||||
|
urlValues.Add("mac", net_data["mac"].(string))
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", ComputeNetDetachAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
// failed to detach this network - there will be partial resource update
|
||||||
|
log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s",
|
||||||
|
net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err)
|
||||||
|
apiErrCount++
|
||||||
|
lastSavedError = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
|
||||||
|
log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
|
||||||
|
for _, runner := range attach_set.List() {
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
net_data := runner.(map[string]interface{})
|
||||||
|
urlValues.Add("computeId", d.Id())
|
||||||
|
urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
|
||||||
|
urlValues.Add("netType", net_data["net_type"].(string))
|
||||||
|
if net_data["ip_address"].(string) != "" {
|
||||||
|
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
||||||
|
}
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", ComputeNetAttachAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
// failed to attach this network - there will be partial resource update
|
||||||
|
log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s",
|
||||||
|
net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err)
|
||||||
|
apiErrCount++
|
||||||
|
lastSavedError = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if apiErrCount > 0 {
|
||||||
|
log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s",
|
||||||
|
apiErrCount, d.Id(), lastSavedError)
|
||||||
|
return lastSavedError
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func utilityComputeCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
|
||||||
|
// This function tries to locate Compute by one of the following approaches:
|
||||||
|
// - if compute_id is specified - locate by compute ID
|
||||||
|
// - if compute_name is specified - locate by a combination of compute name and resource
|
||||||
|
// group ID
|
||||||
|
//
|
||||||
|
// If succeeded, it returns non-empty string that contains JSON formatted facts about the
|
||||||
|
// Compute as returned by compute/get API call.
|
||||||
|
// Otherwise it returns empty string and meaningful error.
|
||||||
|
//
|
||||||
|
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||||
|
// method for resource's Exists method.
|
||||||
|
//
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
// make it possible to use "read" & "check presence" functions with compute ID set so
|
||||||
|
// that Import of Compute resource is possible
|
||||||
|
idSet := false
|
||||||
|
theId, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil || theId <= 0 {
|
||||||
|
computeId, argSet := d.GetOk("compute_id") // NB: compute_id is NOT present in computeResource schema!
|
||||||
|
if argSet {
|
||||||
|
theId = computeId.(int)
|
||||||
|
idSet = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
idSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if idSet {
|
||||||
|
// compute ID is specified, try to get compute instance straight by this ID
|
||||||
|
log.Debugf("utilityComputeCheckPresence: locating compute by its ID %d", theId)
|
||||||
|
urlValues.Add("computeId", fmt.Sprintf("%d", theId))
|
||||||
|
computeFacts, err := c.DecortAPICall(ctx, "POST", ComputeGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return computeFacts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID was not set in the schema upon entering this function - work through Compute name
|
||||||
|
// and RG ID
|
||||||
|
computeName, argSet := d.GetOk("name")
|
||||||
|
if !argSet {
|
||||||
|
return "", fmt.Errorf("Cannot locate compute instance if name is empty and no compute ID specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
rgId, argSet := d.GetOk("rg_id")
|
||||||
|
if !argSet {
|
||||||
|
return "", fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
urlValues.Add("rgId", fmt.Sprintf("%d", rgId))
|
||||||
|
apiResp, err := c.DecortAPICall(ctx, "POST", RgListComputesAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityComputeCheckPresence: ready to unmarshal string %s", apiResp)
|
||||||
|
|
||||||
|
computeList := RgListComputesResp{}
|
||||||
|
err = json.Unmarshal([]byte(apiResp), &computeList)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// log.Printf("%#v", computeList)
|
||||||
|
log.Debugf("utilityComputeCheckPresence: traversing decoded JSON of length %d", len(computeList))
|
||||||
|
for index, item := range computeList {
|
||||||
|
// need to match Compute by name, skip Computes with the same name in DESTROYED satus
|
||||||
|
if item.Name == computeName.(string) && item.Status != "DESTROYED" {
|
||||||
|
log.Debugf("utilityComputeCheckPresence: index %d, matched name %s", index, item.Name)
|
||||||
|
// we found the Compute we need - now get detailed information via compute/get API
|
||||||
|
cgetValues := &url.Values{}
|
||||||
|
cgetValues.Add("computeId", fmt.Sprintf("%d", item.ID))
|
||||||
|
apiResp, err = c.DecortAPICall(ctx, "POST", ComputeGetAPI, cgetValues)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return apiResp, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil // there should be no error if Compute does not exist
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pfw
|
||||||
|
|
||||||
|
const ComputePfwListAPI = "/restmachine/cloudbroker/compute/pfwList"
|
||||||
|
const ComputePfwAddAPI = "/restmachine/cloudbroker/compute/pfwAdd"
|
||||||
|
const ComputePfwDelAPI = "/restmachine/cloudbroker/compute/pfwDel"
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pfw
|
||||||
|
type PfwRecord struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
LocalIP string `json:"localIp"`
|
||||||
|
LocalPort int `json:"localPort"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
PublicPortEnd int `json:"publicPortEnd"`
|
||||||
|
PublicPortStart int `json:"publicPortStart"`
|
||||||
|
ComputeID int `json:"vmId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComputePfwListResp []PfwRecord
|
||||||
|
|
||||||
|
|
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pfw
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourcePfwCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int))
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||||
|
urlValues.Add("publicPortStart", strconv.Itoa(d.Get("public_port_start").(int)))
|
||||||
|
urlValues.Add("localBasePort", strconv.Itoa(d.Get("local_base_port").(int)))
|
||||||
|
urlValues.Add("proto", d.Get("proto").(string))
|
||||||
|
|
||||||
|
if portEnd, ok := d.GetOk("public_port_end"); ok {
|
||||||
|
urlValues.Add("publicPortEnd", strconv.Itoa(portEnd.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pfwId, err := c.DecortAPICall(ctx, "POST", ComputePfwAddAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%d-%s", d.Get("compute_id").(int), pfwId))
|
||||||
|
|
||||||
|
pfw, err := utilityPfwCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("local_ip", pfw.LocalIP)
|
||||||
|
if _, ok := d.GetOk("public_port_end"); !ok {
|
||||||
|
d.Set("public_port_end", pfw.PublicPortEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourcePfwRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourcePfwRead: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
||||||
|
|
||||||
|
pfw, err := utilityPfwCheckPresence(ctx, d, m)
|
||||||
|
if pfw == nil {
|
||||||
|
d.SetId("")
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("compute_id", pfw.ComputeID)
|
||||||
|
d.Set("public_port_start", pfw.PublicPortStart)
|
||||||
|
d.Set("public_port_end", pfw.PublicPortEnd)
|
||||||
|
d.Set("local_ip", pfw.LocalIP)
|
||||||
|
d.Set("local_base_port", pfw.LocalPort)
|
||||||
|
d.Set("proto", pfw.Protocol)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourcePfwDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourcePfwDelete: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
||||||
|
|
||||||
|
pfw, err := utilityPfwCheckPresence(ctx, d, m)
|
||||||
|
if pfw == nil {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||||
|
urlValues.Add("ruleId", strconv.Itoa(pfw.ID))
|
||||||
|
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", ComputePfwDelAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourcePfwExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
log.Debugf("resourcePfwExists: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
||||||
|
|
||||||
|
pfw, err := utilityPfwCheckPresence(ctx, d, m)
|
||||||
|
if pfw == nil {
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourcePfwSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "ID of compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"public_port_start": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ValidateFunc: validation.IntBetween(1, 65535),
|
||||||
|
Description: "External start port number for the rule.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"public_port_end": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ValidateFunc: validation.IntBetween(1, 65535),
|
||||||
|
Description: "End port number (inclusive) for the ranged rule.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"local_ip": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "IP address of compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"local_base_port": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ValidateFunc: validation.IntBetween(1, 65535),
|
||||||
|
Description: "Internal base port number.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"proto": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false),
|
||||||
|
Description: "Network protocol, either 'tcp' or 'udp'.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourcePfw() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourcePfwCreate,
|
||||||
|
ReadContext: resourcePfwRead,
|
||||||
|
DeleteContext: resourcePfwDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout60s,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout60s,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: resourcePfwSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pfw
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityPfwCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*PfwRecord, error) {
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||||
|
resp, err := c.DecortAPICall(ctx, "POST", ComputePfwListAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
idS := strings.Split(d.Id(), "-")[1]
|
||||||
|
id, err := strconv.Atoi(idS)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pfws []PfwRecord
|
||||||
|
if err := json.Unmarshal([]byte(resp), &pfws); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pfw := range pfws {
|
||||||
|
if pfw.ID == id {
|
||||||
|
return &pfw, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rg
|
||||||
|
|
||||||
|
const ResgroupCreateAPI = "/restmachine/cloudbroker/rg/create"
|
||||||
|
const ResgroupUpdateAPI = "/restmachine/cloudbroker/rg/update"
|
||||||
|
const ResgroupListAPI = "/restmachine/cloudbroker/rg/list"
|
||||||
|
const ResgroupGetAPI = "/restmachine/cloudbroker/rg/get"
|
||||||
|
const ResgroupDeleteAPI = "/restmachine/cloudbroker/rg/delete"
|
||||||
|
const RgListComputesAPI = "/restmachine/cloudbroker/rg/listComputes"
|
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
// "net/url"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenResgroup(d *schema.ResourceData, rg_facts string) error {
|
||||||
|
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||||
|
// from resourceRsgroupExists(...) method
|
||||||
|
// log.Debugf("%s", rg_facts)
|
||||||
|
log.Debugf("flattenResgroup: ready to decode response body from API")
|
||||||
|
details := ResgroupGetResp{}
|
||||||
|
err := json.Unmarshal([]byte(rg_facts), &details)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d",
|
||||||
|
details.Name, details.ID, details.AccountID)
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%d", details.ID))
|
||||||
|
d.Set("rg_id", details.ID)
|
||||||
|
d.Set("name", details.Name)
|
||||||
|
d.Set("account_name", details.AccountName)
|
||||||
|
d.Set("account_id", details.AccountID)
|
||||||
|
// d.Set("grid_id", details.GridID)
|
||||||
|
d.Set("description", details.Desc)
|
||||||
|
d.Set("status", details.Status)
|
||||||
|
d.Set("def_net_type", details.DefaultNetType)
|
||||||
|
d.Set("def_net_id", details.DefaultNetID)
|
||||||
|
/*
|
||||||
|
d.Set("vins", details.Vins)
|
||||||
|
d.Set("computes", details.Computes)
|
||||||
|
*/
|
||||||
|
|
||||||
|
log.Debugf("flattenResgroup: calling flattenQuota()")
|
||||||
|
if err = d.Set("quota", parseQuota(details.Quota)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||||
|
if rg_facts == "" {
|
||||||
|
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
||||||
|
// such resource group and err tells so - just return it to the calling party
|
||||||
|
d.SetId("") // ensure ID is empty in this case
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return diag.FromErr(flattenResgroup(d, rg_facts))
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceResgroup() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceResgroupRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Name of the resource group. Names are case sensitive and unique within the context of an account.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Unique ID of the resource group. If this ID is specified, then resource group name is ignored.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the account, which this resource group belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
Description: "Unique ID of the account, which this resource group belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "User-defined text description of this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
/* commented out, as in this version of provider we use default Grid ID
|
||||||
|
"grid_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Unique ID of the grid, where this resource group is deployed.",
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
|
"quota": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: quotaRgSubresourceSchemaMake(), // this is a dictionary
|
||||||
|
},
|
||||||
|
Description: "Quota settings for this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"def_net_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Type of the default network for this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"def_net_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "ID of the default network for this resource group (if any).",
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Current status of this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"vins": {
|
||||||
|
Type: schema.TypeList, // this is a list of ints
|
||||||
|
Computed: true,
|
||||||
|
MaxItems: LimitMaxVinsPerResgroup,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
Description: "List of VINs deployed in this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"computes": {
|
||||||
|
Type: schema.TypeList, //t his is a list of ints
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
Description: "List of computes deployed in this resource group.",
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,324 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenRgList(rgl ResgroupListResp) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, rg := range rgl {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"account_id": rg.AccountID,
|
||||||
|
"account_name": rg.AccountName,
|
||||||
|
"acl": flattenRgAcl(rg.ACLs),
|
||||||
|
"created_by": rg.CreatedBy,
|
||||||
|
"created_time": rg.CreatedTime,
|
||||||
|
"def_net_id": rg.DefaultNetID,
|
||||||
|
"def_net_type": rg.DefaultNetType,
|
||||||
|
"deleted_by": rg.DeletedBy,
|
||||||
|
"deleted_time": rg.DeletedTime,
|
||||||
|
"desc": rg.Decsription,
|
||||||
|
"gid": rg.GridID,
|
||||||
|
"guid": rg.GUID,
|
||||||
|
"rg_id": rg.ID,
|
||||||
|
"lock_status": rg.LockStatus,
|
||||||
|
"milestones": rg.Milestones,
|
||||||
|
"name": rg.Name,
|
||||||
|
"register_computes": rg.RegisterComputes,
|
||||||
|
"resource_limits": flattenRgResourceLimits(rg.ResourceLimits),
|
||||||
|
"secret": rg.Secret,
|
||||||
|
"status": rg.Status,
|
||||||
|
"updated_by": rg.UpdatedBy,
|
||||||
|
"updated_time": rg.UpdatedTime,
|
||||||
|
"vins": rg.Vins,
|
||||||
|
"vms": rg.Computes,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenRgAcl(rgAcls []AccountAclRecord) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, rgAcl := range rgAcls {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"explicit": rgAcl.IsExplicit,
|
||||||
|
"guid": rgAcl.Guid,
|
||||||
|
"right": rgAcl.Rights,
|
||||||
|
"status": rgAcl.Status,
|
||||||
|
"type": rgAcl.Type,
|
||||||
|
"user_group_id": rgAcl.UgroupID,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"cu_c": rl.CUC,
|
||||||
|
"cu_d": rl.CUD,
|
||||||
|
"cu_i": rl.CUI,
|
||||||
|
"cu_m": rl.CUM,
|
||||||
|
"cu_np": rl.CUNP,
|
||||||
|
"gpu_units": rl.GpuUnits,
|
||||||
|
}
|
||||||
|
res = append(res, temp)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceRgListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
rgList, err := utilityRgListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenRgList(rgList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceRgListSchemaMake() map[string]*schema.Schema {
|
||||||
|
res := map[string]*schema.Schema{
|
||||||
|
"includedeleted": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "included deleted resource groups",
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Page number",
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Page size",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"acl": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"explicit": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"user_group_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"def_net_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"def_net_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"desc": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"lock_status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"milestones": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"register_computes": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"resource_limits": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cu_c": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_d": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_i": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_m": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cu_np": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gpu_units": {
|
||||||
|
Type: schema.TypeFloat,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"secret": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vins": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"vms": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceRgList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceRgListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceRgListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rg
|
||||||
|
|
||||||
|
type ResourceLimits struct {
|
||||||
|
CUC float64 `json:"CU_C"`
|
||||||
|
CUD float64 `json:"CU_D"`
|
||||||
|
CUI float64 `json:"CU_I"`
|
||||||
|
CUM float64 `json:"CU_M"`
|
||||||
|
CUNP float64 `json:"CU_NP"`
|
||||||
|
GpuUnits float64 `json:"gpu_units"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResgroupRecord struct {
|
||||||
|
ACLs []AccountAclRecord `json:"acl"`
|
||||||
|
AccountID int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
CreatedBy string `json:"createdBy"`
|
||||||
|
CreatedTime uint64 `json:"createdTime"`
|
||||||
|
DefaultNetID int `json:"def_net_id"`
|
||||||
|
DefaultNetType string `json:"def_net_type"`
|
||||||
|
DeletedBy string `json:"deletedBy"`
|
||||||
|
DeletedTime int `json:"deletedTime"`
|
||||||
|
Decsription string `json:"desc"`
|
||||||
|
GridID int `json:"gid"`
|
||||||
|
GUID int `json:"guid"`
|
||||||
|
ID uint `json:"id"`
|
||||||
|
LockStatus string `json:"lockStatus"`
|
||||||
|
Milestones int `json:"milestones"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
RegisterComputes bool `json:"registerComputes"`
|
||||||
|
ResourceLimits ResourceLimits `json:"resourceLimits"`
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
UpdatedBy string `json:"updatedBy"`
|
||||||
|
UpdatedTime uint64 `json:"updatedTime"`
|
||||||
|
Vins []int `json:"vins"`
|
||||||
|
Computes []int `json:"vms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResgroupListResp []ResgroupRecord
|
||||||
|
|
||||||
|
type ResgroupUpdateParam struct {
|
||||||
|
RgId int `json:"rgId"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Desc string `json:"decs"`
|
||||||
|
Ram int `json:"maxMemoryCapacity"`
|
||||||
|
Disk int `json:"maxVDiskCapacity"`
|
||||||
|
Cpu int `json:"maxCPUCapacity"`
|
||||||
|
NetTraffic int `json:"maxNetworkPeerTransfer"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountAclRecord struct {
|
||||||
|
IsExplicit bool `json:"explicit"`
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Rights string `json:"right"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
UgroupID string `json:"userGroupId"`
|
||||||
|
CanBeDeleted bool `json:"canBeDeleted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResgroupGetResp struct {
|
||||||
|
ACLs []UserAclRecord `json:"ACLs"`
|
||||||
|
Usage UsageRecord `json:"Resources"`
|
||||||
|
AccountID int `json:"accountId"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
GridID int `json:"gid"`
|
||||||
|
CreatedBy string `json:"createdBy"`
|
||||||
|
CreatedTime uint64 `json:"createdTime"`
|
||||||
|
DefaultNetID int `json:"def_net_id"`
|
||||||
|
DefaultNetType string `json:"def_net_type"`
|
||||||
|
DeletedBy string `json:"deletedBy"`
|
||||||
|
DeletedTime uint64 `json:"deletedTime"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
ID uint `json:"id"`
|
||||||
|
LockStatus string `json:"lockStatus"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Quota QuotaRecord `json:"resourceLimits"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
UpdatedBy string `json:"updatedBy"`
|
||||||
|
UpdatedTime uint64 `json:"updatedTime"`
|
||||||
|
Vins []int `json:"vins"`
|
||||||
|
Computes []int `json:"vms"`
|
||||||
|
|
||||||
|
Ignored map[string]interface{} `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserAclRecord struct {
|
||||||
|
IsExplicit bool `json:"explicit"`
|
||||||
|
Rights string `json:"right"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
UgroupID string `json:"userGroupId"`
|
||||||
|
// CanBeDeleted bool `json:"canBeDeleted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get
|
||||||
|
Cpu int `json:"CU_C"` // CPU count in pcs
|
||||||
|
Ram float64 `json:"CU_M"` // RAM volume in MB, it is STILL reported as FLOAT
|
||||||
|
Disk int `json:"CU_D"` // Disk capacity in GB
|
||||||
|
ExtIPs int `json:"CU_I"` // Ext IPs count
|
||||||
|
ExtTraffic int `json:"CU_NP"` // Ext network traffic
|
||||||
|
GpuUnits int `json:"gpu_units"` // GPU count
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResourceRecord struct { // this is how actual usage is reported by /api/.../rg/get
|
||||||
|
Cpu int `json:"cpu"`
|
||||||
|
Disk int `json:"disksize"`
|
||||||
|
ExtIPs int `json:"extips"`
|
||||||
|
ExtTraffic int `json:"exttraffic"`
|
||||||
|
Gpu int `json:"gpu"`
|
||||||
|
Ram int `json:"ram"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UsageRecord struct {
|
||||||
|
Current ResourceRecord `json:"Current"`
|
||||||
|
Reserved ResourceRecord `json:"Reserved"`
|
||||||
|
}
|
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeQuotaRecord(arg_list []interface{}) QuotaRecord {
|
||||||
|
quota := QuotaRecord{
|
||||||
|
Cpu: -1,
|
||||||
|
Ram: -1., // this is float64, but may change in the future
|
||||||
|
Disk: -1,
|
||||||
|
ExtTraffic: -1,
|
||||||
|
ExtIPs: -1,
|
||||||
|
GpuUnits: -1,
|
||||||
|
}
|
||||||
|
subres_data := arg_list[0].(map[string]interface{})
|
||||||
|
|
||||||
|
if subres_data["cpu"].(int) > 0 {
|
||||||
|
quota.Cpu = subres_data["cpu"].(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
if subres_data["disk"].(int) > 0 {
|
||||||
|
quota.Disk = subres_data["disk"].(int) // Disk capacity ib GB
|
||||||
|
}
|
||||||
|
|
||||||
|
if subres_data["ram"].(float64) > 0 {
|
||||||
|
quota.Ram = subres_data["ram"].(float64) // RAM volume in MB, as float64!
|
||||||
|
}
|
||||||
|
|
||||||
|
if subres_data["ext_traffic"].(int) > 0 {
|
||||||
|
quota.ExtTraffic = subres_data["ext_traffic"].(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
if subres_data["ext_ips"].(int) > 0 {
|
||||||
|
quota.ExtIPs = subres_data["ext_ips"].(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
if subres_data["gpu_units"].(int) > 0 {
|
||||||
|
quota.GpuUnits = subres_data["gpu_units"].(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
return quota
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseQuota(quota QuotaRecord) []interface{} {
|
||||||
|
quota_map := make(map[string]interface{})
|
||||||
|
|
||||||
|
quota_map["cpu"] = quota.Cpu
|
||||||
|
quota_map["ram"] = quota.Ram // NB: this is float64, unlike the rest of values
|
||||||
|
quota_map["disk"] = quota.Disk
|
||||||
|
quota_map["ext_traffic"] = quota.ExtTraffic
|
||||||
|
quota_map["ext_ips"] = quota.ExtIPs
|
||||||
|
quota_map["gpu_units"] = quota.GpuUnits
|
||||||
|
|
||||||
|
result := make([]interface{}, 1)
|
||||||
|
result[0] = quota_map
|
||||||
|
|
||||||
|
return result // this result will be used to d.Set("quota,") of dataSourceResgroup schema
|
||||||
|
}
|
||||||
|
|
||||||
|
func quotaRgSubresourceSchemaMake() map[string]*schema.Schema {
|
||||||
|
rets := map[string]*schema.Schema{
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: -1,
|
||||||
|
Description: "Limit on the total number of CPUs in this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeFloat, // NB: API expects and returns this as float in units of MB! This may be changed in the future.
|
||||||
|
Optional: true,
|
||||||
|
Default: -1.,
|
||||||
|
Description: "Limit on the total amount of RAM in this resource group, specified in MB.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"disk": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: -1,
|
||||||
|
Description: "Limit on the total volume of storage resources in this resource group, specified in GB.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ext_traffic": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: -1,
|
||||||
|
Description: "Limit on the total ingress network traffic for this resource group, specified in GB.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ext_ips": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: -1,
|
||||||
|
Description: "Limit on the total number of external IP addresses this resource group can use.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"gpu_units": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: -1,
|
||||||
|
Description: "Limit on the total number of virtual GPUs this resource group can use.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return rets
|
||||||
|
}
|
@ -0,0 +1,442 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/location"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
// First validate that we have all parameters required to create the new Resource Group
|
||||||
|
|
||||||
|
// Valid account ID is required to create new resource group
|
||||||
|
// obtain Account ID by account name - it should not be zero on success
|
||||||
|
|
||||||
|
rg_name, arg_set := d.GetOk("name")
|
||||||
|
if !arg_set {
|
||||||
|
return diag.FromErr(fmt.Errorf("Cannot create new RG: missing name."))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Current version of provider works with default grid id (same is true for disk resources)
|
||||||
|
grid_id, arg_set := d.GetOk("grid_id")
|
||||||
|
if !arg_set {
|
||||||
|
return fmt.Errorf("Cannot create new RG %q in account ID %d: missing Grid ID.",
|
||||||
|
rg_name.(string), validated_account_id)
|
||||||
|
}
|
||||||
|
if grid_id.(int) < 1 {
|
||||||
|
grid_id = DefaultGridID
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// all required parameters are set in the schema - we can continue with RG creation
|
||||||
|
log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d",
|
||||||
|
rg_name.(string), d.Get("account_id").(int))
|
||||||
|
|
||||||
|
// quota settings are optional
|
||||||
|
set_quota := false
|
||||||
|
var quota_record QuotaRecord
|
||||||
|
arg_value, arg_set := d.GetOk("quota")
|
||||||
|
if arg_set {
|
||||||
|
log.Debugf("resourceResgroupCreate: setting Quota on RG requested")
|
||||||
|
quota_record = makeQuotaRecord(arg_value.([]interface{}))
|
||||||
|
set_quota = true
|
||||||
|
}
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
log.Debugf("resourceResgroupCreate: called by user %q for RG name %s, account ID %d",
|
||||||
|
c.GetDecortUsername(),
|
||||||
|
rg_name.(string), d.Get("account_id").(int))
|
||||||
|
|
||||||
|
url_values := &url.Values{}
|
||||||
|
url_values.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
||||||
|
url_values.Add("name", rg_name.(string))
|
||||||
|
url_values.Add("gid", fmt.Sprintf("%d", location.DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention
|
||||||
|
url_values.Add("owner", c.GetDecortUsername())
|
||||||
|
|
||||||
|
// pass quota values as set
|
||||||
|
if set_quota {
|
||||||
|
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quota_record.Cpu))
|
||||||
|
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quota_record.Disk))
|
||||||
|
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quota_record.Ram)) // RAM quota is float; this may change in the future
|
||||||
|
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quota_record.ExtTraffic))
|
||||||
|
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quota_record.ExtIPs))
|
||||||
|
// url_values.Add("???", fmt.Sprintf("%d", quota_record.GpuUnits))
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse and handle network settings
|
||||||
|
def_net_type, arg_set := d.GetOk("def_net_type")
|
||||||
|
if arg_set {
|
||||||
|
url_values.Add("def_net", def_net_type.(string)) // NOTE: in API default network type is set by "def_net" parameter
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcidr, arg_set := d.GetOk("ipcidr")
|
||||||
|
if arg_set {
|
||||||
|
url_values.Add("ipcidr", ipcidr.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
ext_net_id, arg_set := d.GetOk("ext_net_id")
|
||||||
|
if arg_set {
|
||||||
|
url_values.Add("extNetId", fmt.Sprintf("%d", ext_net_id.(int)))
|
||||||
|
}
|
||||||
|
|
||||||
|
ext_ip, arg_set := d.GetOk("ext_ip")
|
||||||
|
if arg_set {
|
||||||
|
url_values.Add("extIp", ext_ip.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
api_resp, err := c.DecortAPICall(ctx, "POST", ResgroupCreateAPI, url_values)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(api_resp) // rg/create API returns ID of the newly creted resource group on success
|
||||||
|
// rg.ID, _ = strconv.Atoi(api_resp)
|
||||||
|
if !set_quota {
|
||||||
|
resp, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rg := ResgroupGetResp{}
|
||||||
|
if err := json.Unmarshal([]byte(resp), &rg); err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("quota", parseQuota(rg.Quota))
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-read newly created RG to make sure schema contains complete and up to date set of specifications
|
||||||
|
return resourceResgroupRead(ctx, d, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d",
|
||||||
|
d.Get("name").(string), d.Get("account_id").(int))
|
||||||
|
|
||||||
|
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||||
|
if rg_facts == "" {
|
||||||
|
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
||||||
|
// such resource group and err tells so - just return it to the calling party
|
||||||
|
d.SetId("") // ensure ID is empty
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return diag.FromErr(flattenResgroup(d, rg_facts))
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceResgroupUpdate: called for RG name %s, account ID %d",
|
||||||
|
d.Get("name").(string), d.Get("account_id").(int))
|
||||||
|
|
||||||
|
/* NOTE: we do not allow changing the following attributes of an existing RG via terraform:
|
||||||
|
- def_net_type
|
||||||
|
- ipcidr
|
||||||
|
- ext_net_id
|
||||||
|
- ext_ip
|
||||||
|
|
||||||
|
The following code fragment checks if any of these have been changed and generates error.
|
||||||
|
*/
|
||||||
|
for _, attr := range []string{"def_net_type", "ipcidr", "ext_ip"} {
|
||||||
|
attr_new, attr_old := d.GetChange("def_net_type")
|
||||||
|
if attr_new.(string) != attr_old.(string) {
|
||||||
|
return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing %s for existing RG is not allowed", d.Id(), attr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_new, attr_old := d.GetChange("ext_net_id")
|
||||||
|
if attr_new.(int) != attr_old.(int) {
|
||||||
|
return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing ext_net_id for existing RG is not allowed", d.Id()))
|
||||||
|
}
|
||||||
|
|
||||||
|
do_general_update := false // will be true if general RG update is necessary (API rg/update)
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
url_values := &url.Values{}
|
||||||
|
url_values.Add("rgId", d.Id())
|
||||||
|
|
||||||
|
name_new, name_set := d.GetOk("name")
|
||||||
|
if name_set {
|
||||||
|
log.Debugf("resourceResgroupUpdate: name specified - looking for deltas from the old settings.")
|
||||||
|
name_old, _ := d.GetChange("name")
|
||||||
|
if name_old.(string) != name_new.(string) {
|
||||||
|
do_general_update = true
|
||||||
|
url_values.Add("name", name_new.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quota_value, quota_set := d.GetOk("quota")
|
||||||
|
if quota_set {
|
||||||
|
log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.")
|
||||||
|
quotarecord_new := makeQuotaRecord(quota_value.([]interface{}))
|
||||||
|
quota_value_old, _ := d.GetChange("quota") // returns old as 1st, new as 2nd return value
|
||||||
|
quotarecord_old := makeQuotaRecord(quota_value_old.([]interface{}))
|
||||||
|
|
||||||
|
if quotarecord_new.Cpu != quotarecord_old.Cpu {
|
||||||
|
do_general_update = true
|
||||||
|
log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu)
|
||||||
|
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu))
|
||||||
|
}
|
||||||
|
|
||||||
|
if quotarecord_new.Disk != quotarecord_old.Disk {
|
||||||
|
do_general_update = true
|
||||||
|
log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.Disk)
|
||||||
|
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk))
|
||||||
|
}
|
||||||
|
|
||||||
|
if quotarecord_new.Ram != quotarecord_old.Ram { // NB: quota on RAM is stored as float32, in units of MB
|
||||||
|
do_general_update = true
|
||||||
|
log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram)
|
||||||
|
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram))
|
||||||
|
}
|
||||||
|
|
||||||
|
if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic {
|
||||||
|
do_general_update = true
|
||||||
|
log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic)
|
||||||
|
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.ExtTraffic))
|
||||||
|
}
|
||||||
|
|
||||||
|
if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs {
|
||||||
|
do_general_update = true
|
||||||
|
log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs)
|
||||||
|
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
desc_new, desc_set := d.GetOk("description")
|
||||||
|
if desc_set {
|
||||||
|
log.Debugf("resourceResgroupUpdate: description specified - looking for deltas from the old settings.")
|
||||||
|
desc_old, _ := d.GetChange("description")
|
||||||
|
if desc_old.(string) != desc_new.(string) {
|
||||||
|
do_general_update = true
|
||||||
|
url_values.Add("desc", desc_new.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if do_general_update {
|
||||||
|
log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG")
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", ResgroupUpdateAPI, url_values)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugf("resourceResgroupUpdate: no difference between old and new state - no update on the RG will be done")
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceResgroupRead(ctx, d, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceResgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
// NOTE: this method forcibly destroys target resource group with flag "permanently", so there is no way to
|
||||||
|
// restore the destroyed resource group as well all Computes & VINSes that existed in it
|
||||||
|
log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d",
|
||||||
|
d.Get("name").(string), d.Get("account_id").(int))
|
||||||
|
|
||||||
|
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||||
|
if rg_facts == "" {
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
// the target RG does not exist - in this case according to Terraform best practice
|
||||||
|
// we exit from Destroy method without error
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
url_values := &url.Values{}
|
||||||
|
url_values.Add("rgId", d.Id())
|
||||||
|
url_values.Add("force", "1")
|
||||||
|
url_values.Add("permanently", "1")
|
||||||
|
url_values.Add("reason", "Destroyed by DECORT Terraform provider")
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
_, err = c.DecortAPICall(ctx, "POST", ResgroupDeleteAPI, url_values)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceResgroupExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
// Reminder: according to Terraform rules, this function should NOT modify ResourceData argument
|
||||||
|
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||||
|
if rg_facts == "" {
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceResgroup() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceResgroupCreate,
|
||||||
|
ReadContext: resourceResgroupRead,
|
||||||
|
UpdateContext: resourceResgroupUpdate,
|
||||||
|
DeleteContext: resourceResgroupDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout180s,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout180s,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "Name of this resource group. Names are case sensitive and unique within the context of a account.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.IntAtLeast(1),
|
||||||
|
Description: "Unique ID of the account, which this resource group belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"def_net_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Default: "PRIVATE",
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false),
|
||||||
|
Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"def_net_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "ID of the default network for this resource group (if any).",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ipcidr": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ext_net_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: 0,
|
||||||
|
Description: "ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE",
|
||||||
|
},
|
||||||
|
|
||||||
|
"ext_ip": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0",
|
||||||
|
},
|
||||||
|
|
||||||
|
/* commented out, as in this version of provider we use default Grid ID
|
||||||
|
"grid_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: 0, // if 0 is passed, default Grid ID will be used
|
||||||
|
// DefaultFunc: utilityResgroupGetDefaultGridID,
|
||||||
|
ForceNew: true, // change of Grid ID will require new RG
|
||||||
|
Description: "Unique ID of the grid, where this resource group is deployed.",
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
|
"quota": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: quotaRgSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Quota settings for this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "User-defined text description of this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the account, which this resource group belongs to.",
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Current status of this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"vins": {
|
||||||
|
Type: schema.TypeList, // this is a list of ints
|
||||||
|
Computed: true,
|
||||||
|
MaxItems: LimitMaxVinsPerResgroup,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
Description: "List of VINs deployed in this resource group.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"computes": {
|
||||||
|
Type: schema.TypeList, // this is a list of ints
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
Description: "List of computes deployed in this resource group.",
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
||||||
|
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// On success this function returns a string, as returned by API rg/get, which could be unmarshalled
|
||||||
|
// into ResgroupGetResp structure
|
||||||
|
func utilityResgroupCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (string, error) {
|
||||||
|
// This function tries to locate resource group by one of the following algorithms depending
|
||||||
|
// on the parameters passed:
|
||||||
|
// - if resource group ID is specified -> by RG ID
|
||||||
|
// - if resource group name is specifeid -> by RG name and either account ID or account name
|
||||||
|
//
|
||||||
|
// If succeeded, it returns non empty string that contains JSON formatted facts about the
|
||||||
|
// resource group as returned by rg/get API call.
|
||||||
|
// Otherwise it returns empty string and a meaningful error.
|
||||||
|
//
|
||||||
|
// NOTE: As our provider always deletes RGs permanently, there is no "restore" method and
|
||||||
|
// consequently we are not interested in matching RGs in DELETED state. Hence, we call
|
||||||
|
// .../rg/list API with includedeleted=false
|
||||||
|
//
|
||||||
|
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||||
|
// method for the Terraform resource Exists method.
|
||||||
|
//
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
// make it possible to use "read" & "check presence" functions with RG ID set so
|
||||||
|
// that Import of RG resource is possible
|
||||||
|
idSet := false
|
||||||
|
theId, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil || theId <= 0 {
|
||||||
|
rgId, argSet := d.GetOk("rg_id")
|
||||||
|
if argSet {
|
||||||
|
theId = rgId.(int)
|
||||||
|
idSet = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
idSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if idSet {
|
||||||
|
// go straight for the RG by its ID
|
||||||
|
log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId)
|
||||||
|
urlValues.Add("rgId", fmt.Sprintf("%d", theId))
|
||||||
|
rgFacts, err := c.DecortAPICall(ctx, "POST", ResgroupGetAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return rgFacts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rgName, argSet := d.GetOk("name")
|
||||||
|
if !argSet {
|
||||||
|
// no RG ID and no RG name - we cannot locate resource group in this case
|
||||||
|
return "", fmt.Errorf("Cannot check resource group presence if name is empty and no resource group ID specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid account ID is required to locate a resource group
|
||||||
|
// obtain Account ID by account name - it should not be zero on success
|
||||||
|
|
||||||
|
urlValues.Add("includedeleted", "false")
|
||||||
|
apiResp, err := c.DecortAPICall(ctx, "POST", ResgroupListAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// log.Debugf("%s", apiResp)
|
||||||
|
log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", ResgroupListAPI)
|
||||||
|
model := ResgroupListResp{}
|
||||||
|
err = json.Unmarshal([]byte(apiResp), &model)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model))
|
||||||
|
for index, item := range model {
|
||||||
|
// match by RG name & account ID
|
||||||
|
if item.Name == rgName.(string) && item.AccountID == d.Get("account_id").(int) {
|
||||||
|
log.Debugf("utilityResgroupCheckPresence: match RG name %s / ID %d, account ID %d at index %d",
|
||||||
|
item.Name, item.ID, item.AccountID, index)
|
||||||
|
|
||||||
|
// not all required information is returned by rg/list API, so we need to initiate one more
|
||||||
|
// call to rg/get to obtain extra data to complete Resource population.
|
||||||
|
// Namely, we need resource quota settings
|
||||||
|
reqValues := &url.Values{}
|
||||||
|
reqValues.Add("rgId", fmt.Sprintf("%d", item.ID))
|
||||||
|
apiResp, err := c.DecortAPICall(ctx, "POST", ResgroupGetAPI, reqValues)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiResp, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, d.Get("account_id").(int))
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func utilityRgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (ResgroupListResp, error) {
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
rgList := ResgroupListResp{}
|
||||||
|
|
||||||
|
if size, ok := d.GetOk("size"); ok {
|
||||||
|
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||||
|
}
|
||||||
|
if page, ok := d.GetOk("page"); ok {
|
||||||
|
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||||
|
}
|
||||||
|
if includedeleted, ok := d.GetOk("includedeleted"); ok {
|
||||||
|
urlValues.Add("includedeleted", strconv.FormatBool(includedeleted.(bool)))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("utilityRgListCheckPresence: load rg list")
|
||||||
|
rgListRaw, err := c.DecortAPICall(ctx, "POST", ResgroupListAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(rgListRaw), &rgList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return rgList, nil
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package snapshot
|
||||||
|
|
||||||
|
const snapshotCreateAPI = "/restmachine/cloudbroker/compute/snapshotCreate"
|
||||||
|
const snapshotDeleteAPI = "/restmachine/cloudbroker/compute/snapshotDelete"
|
||||||
|
const snapshotRollbackAPI = "/restmachine/cloudbroker/compute/snapshotRollback"
|
||||||
|
const snapshotListAPI = "/restmachine/cloudbroker/compute/snapshotList"
|
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package snapshot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func flattenSnapshotList(gl SnapshotList) []map[string]interface{} {
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for _, item := range gl {
|
||||||
|
temp := map[string]interface{}{
|
||||||
|
"label": item.Label,
|
||||||
|
"guid": item.Guid,
|
||||||
|
"disks": item.Disks,
|
||||||
|
"timestamp": item.Timestamp,
|
||||||
|
}
|
||||||
|
|
||||||
|
res = append(res, temp)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceSnapshotListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
snapshotList, err := utilitySnapshotListCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
id := uuid.New()
|
||||||
|
d.SetId(id.String())
|
||||||
|
d.Set("items", flattenSnapshotList(snapshotList))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceSnapshotListSchemaMake() map[string]*schema.Schema {
|
||||||
|
rets := map[string]*schema.Schema{
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "ID of the compute instance to create snapshot for.",
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Description: "snapshot list",
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceSnapshotSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceSnapshotSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"label": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "text label for snapshot. Must be unique among this compute snapshots.",
|
||||||
|
},
|
||||||
|
"disks": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "guid of the snapshot",
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "timestamp",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DataSourceSnapshotList() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
ReadContext: dataSourceSnapshotListRead,
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: dataSourceSnapshotListSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package snapshot
|
||||||
|
|
||||||
|
type Snapshot struct {
|
||||||
|
Disks []int `json:"disks"`
|
||||||
|
Guid string `json:"guid"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
Timestamp uint64 `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnapshotList []Snapshot
|
@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
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://github.com/rudecs/terraform-provider-decort
|
||||||
|
|
||||||
|
Please see README.md to learn where to place source code so that it
|
||||||
|
builds seamlessly.
|
||||||
|
|
||||||
|
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||||
|
*/
|
||||||
|
|
||||||
|
package snapshot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/constants"
|
||||||
|
"github.com/rudecs/terraform-provider-decort/internal/controller"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceSnapshotCreate: called for snapshot %s", d.Get("label").(string))
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("label", d.Get("label").(string))
|
||||||
|
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||||
|
|
||||||
|
snapshotId, err := c.DecortAPICall(ctx, "POST", snapshotCreateAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshotId = strings.ReplaceAll(snapshotId, "\"", "")
|
||||||
|
|
||||||
|
d.SetId(snapshotId)
|
||||||
|
d.Set("guid", snapshotId)
|
||||||
|
|
||||||
|
diagnostics := resourceSnapshotRead(ctx, d, m)
|
||||||
|
if diagnostics != nil {
|
||||||
|
return diagnostics
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSnapshotRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
snapshot, err := utilitySnapshotCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("timestamp", snapshot.Timestamp)
|
||||||
|
d.Set("guid", snapshot.Guid)
|
||||||
|
d.Set("disks", snapshot.Disks)
|
||||||
|
d.Set("label", snapshot.Label)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSnapshotDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
log.Debugf("resourceSnapshotDelete: called for %s, id: %s", d.Get("label").(string), d.Id())
|
||||||
|
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||||
|
urlValues.Add("label", d.Get("label").(string))
|
||||||
|
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", snapshotDeleteAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSnapshotExists(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
|
||||||
|
snapshot, err := utilitySnapshotCheckPresence(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if snapshot == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSnapshotEdit(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
if d.HasChange("rollback") {
|
||||||
|
if d.Get("rollback").(bool) {
|
||||||
|
err := resourceSnapshotRollback(ctx, d, m)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSnapshotRollback(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||||
|
c := m.(*controller.ControllerCfg)
|
||||||
|
urlValues := &url.Values{}
|
||||||
|
|
||||||
|
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||||
|
urlValues.Add("label", d.Get("label").(string))
|
||||||
|
|
||||||
|
_, err := c.DecortAPICall(ctx, "POST", snapshotRollbackAPI, urlValues)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceSnapshotSchemaMake() map[string]*schema.Schema {
|
||||||
|
return map[string]*schema.Schema{
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "ID of the compute instance to create snapshot for.",
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "text label for snapshot. Must be unique among this compute snapshots.",
|
||||||
|
},
|
||||||
|
"rollback": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "is rollback the snapshot",
|
||||||
|
},
|
||||||
|
"disks": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "guid of the snapshot",
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "timestamp",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResourceSnapshot() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
SchemaVersion: 1,
|
||||||
|
|
||||||
|
CreateContext: resourceSnapshotCreate,
|
||||||
|
ReadContext: resourceSnapshotRead,
|
||||||
|
UpdateContext: resourceSnapshotEdit,
|
||||||
|
DeleteContext: resourceSnapshotDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: &constants.Timeout60s,
|
||||||
|
Read: &constants.Timeout30s,
|
||||||
|
Update: &constants.Timeout60s,
|
||||||
|
Delete: &constants.Timeout60s,
|
||||||
|
Default: &constants.Timeout60s,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: resourceSnapshotSchemaMake(),
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue